Skip to content

Instantly share code, notes, and snippets.

@emreavcilar
Last active August 14, 2022 21:35
Show Gist options
  • Save emreavcilar/c161d13d4d0b9b292c3d921df12958f6 to your computer and use it in GitHub Desktop.
Save emreavcilar/c161d13d4d0b9b292c3d921df12958f6 to your computer and use it in GitHub Desktop.
/*
Everything about regex
*/
/*
taken from https://github.com/GoktugOzturk/js-credit-card-validation/blob/master/creditcard.js
*/
var ccErrorNo = 0;
var ccErrors = new Array();
ccErrors[1] = "Unknown card type";
ccErrors[2] = "Credit card number has an inappropriate number of digits";
ccErrors[3] = "Credit card number is in invalid format";
ccErrors[4] = "Credit card number is invalid";
/**
* Validate Credit Card
*
* @param cardNumber
* numeric
* @param cardName
* string
* @return boolean
*/
function checkCreditCard(cardNumber, cardName){
// Cards we support. You may add addtional card types as follows.
// http://en.wikipedia.org/wiki/Bank_card_number#Issuer_Identification_Number_.28IIN.29
// digits: List of possible valid lengths of the card number for the card
// prefix: List of possible prefix for the card (Regex)
// luhn: Validate using luhn algorithm
var cards = {
amex: {
digits: [15],
prefix: "3[47]",
luhn: true
},
unionpay: {
digits: [16, 17, 18, 19],
prefix: "62",
validate: false
},
carteblanche: {
digits: [14],
prefix: "30[0-5]",
luhn: true
},
dinersclub: {
digits: [14],
prefix: "36",
luhn: true
},
discover: {
digits: [16],
prefix: "(6011|622|64[4-9]|65)",
luhn: true
},
instapayment: {
digits: [16],
prefix: "63[7-9]",
luhn: true
},
jcb: {
digits: [16],
prefix: "35(2[89]|[3-8])",
luhn: true
},
laser: {
digits: [16, 17, 18, 19],
prefix: "(6304|670[69]|6771)",
luhn: true
},
maestro: {
digits: [12, 13, 14, 15, 16, 17, 18, 19],
prefix: "(5018|5020|5038|6304|6759|676[1-3])",
luhn: true
},
mastercard: {
digits: [16],
prefix: "5[1-5]",
luhn: true
},
visa: {
digits: [16],
prefix: "4",
luhn: true
},
electron: {
digits: [16],
prefix: "(4026|417500|4508|4844|491[37])",
luhn: true
}
};
// Get card data
var card = cards[cardName.toLowerCase()] || false;
if(typeof card == "boolean"){
// Unknown Card Type
ccErrorNo = 1;
return false;
}
// Sanitize credit card
cardNumber = cardNumber.replace(/[^0-9]/g, "");
// Check if the length was valid. We only check the length if all else was
var cardLength = cardNumber.length;
var lengthValid = false;
for( var i in card.digits){
if(i == cardLength){
lengthValid = true;
break;
}
}
if(!lengthValid){
// Card Length Not Valid
ccErrorNo = 2;
return false;
}
;
// Check for Card Prefix
var exp = new RegExp("^" + card.prefix);
if(!exp.test(cardNumber)){
// Card Prefix Not Valid
ccErrorNo = 3;
return false;
}
// If CardType supports luhn algorith; check for it
if(card.luhn){
if(!checkLuhnAlgorithm(cardNumber)){
// Luhn Check Failed
ccErrorNo = 4;
return false;
}
}
// The credit card is OK.
return true;
}
/**
* Checks supplied number using Luhn Algorithm
* http://en.wikipedia.org/wiki/Luhn_algorithm
*
* @param luhnNumber
* numberic
* @return boolean
*/
function checkLuhnAlgorithm(luhnNumber){
var checksum = 0;
var calc;
var length = luhnNumber.length;
var j = 1;
for( var i = (length - 1); i >= 0; i--){
if(j++ % 2 == 1){
calc = Number(luhnNumber.charAt(i));
}else{
calc = Number(luhnNumber.charAt(i)) * 2;
if(calc > 9){
checksum++;
calc -= 10;
}
}
checksum += calc;
}
return(checksum % 10 == 0);
}
// using match
const text = "People often write hello world while hello world programming";
const regex = /hello world/g
const result = text.match(regex);
console.log(result);
// (2) ['hello world', 'hello world']
//------------------------------------------------------------------------
// using matchAll
const text = "People often write hello world while hello world programming";
const regex = /hello world/g
const results = [...text.matchAll(regex)];
results.forEach(res=>console.log(res));
// (1) ['hello world', index: 19, input: 'People often write hello world while hello world programming', groups: undefined]
// (1) ['hello world', index: 19, input: 'People often write hello world while hello world programming', groups: undefined]
//------------------------------------------------------------------------
// case insensitive
const text = "People often write hello world while HELLO WORLD programming";
const regex = /hello world/gi
const results = [...text.matchAll(regex)];
results.forEach(res=>console.log(res));
// (1) ['hello world', index: 19, input: 'People often write hello world while HELLO WORLD programming', groups: undefined]
// (1) ['HELLO WORLD', index: 37, input: 'People often write hello world while HELLO WORLD programming', groups: undefined]
//------------------------------------------------------------------------
//find capital letters
const text = "People often write hello world while HELLO WORLD programming";
const regex = /[A-Z]/g
const result = text.match(regex);
console.log(result);
// (11) ['P', 'H', 'E', 'L', 'L', 'O', 'W', 'O', 'R', 'L', 'D']
// ----------------------------------------------------------------------
//ignore "P" letter
const text = "People often write hello world while HELLO WORLD programming";
const regex = /[A-OQ-Z]/g
// or
const text = "People often write hello world while HELLO WORLD programming";
const regex = /(?![P])[A-Z]/g
const result = text.match(regex);
console.log(result);
// (10) ['H', 'E', 'L', 'L', 'O', 'W', 'O', 'R', 'L', 'D']
// ----------------------------------------------------------------------
// find digits
const text = "Some 2000 text hello world x190 xyz";
const regex = /\d/g
const result = text.match(regex);
console.log(result);
//(7) ['2', '0', '0', '0', '1', '9', '0']
// ----------------------------------------------------------------------
// add + to the pattern to get full numbers
const text = "Some 2000 text hello world x190 xyz";
const regex = /\d+/g
const result = text.match(regex);
console.log(result);
//(2) ['2000', '190']
// ----------------------------------------------------------------------
//replace
const text = "My favourite number is 7";
const regex = /\d+/g
const blank = text.replace(regex,"?");
console.log(blank);
// My favourite number is ?
// ----------------------------------------------------------------------
// search and exec
// The search method will give us the position of the first match
const text = "Hello world world 1000 xyz";
const regex = /world/g
const result = text.search(regex);
console.log(result)
// 6
// exec is similar to match but with the purpose to be used in a loop. It returns an array of captures or null
const text = "Hello world world 1000 xyz";
const regex = /world/g
while ((arr = regex.exec(text)) !== null){
console.log(`Found ${arr[0]}. Next starts at ${regex.lastIndex}.`);
}
// Found world. Next starts at 11.
// Found world. Next starts at 17.
/*
#javascript function that hides credit card numbers in a string.
*/
const hideCard =(str) =>
str.replace(
/\b(?:\d{4}[ -]?){3}(?=\d{4}\b)/gm,
'#### #### #### '
);
hideCard('visa 1234 3846 3947 0971');
// visa #### #### #### 0971
/*
This snippet can be used to check whether a particular string is an anagram with another string.
*/
const isAnagram = (str1, str2) => {
const normalize = str =>
str
.toLowerCase()
.replace(/[^a-z0-9]/gi, '')
.split('')
.sort()
.join('');
return normalize(str1) === normalize(str2);
};
isAnagram('iceman', 'cinema'); // true
/*
email validation
*/
const isEmailValid = (email) => {
var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
return emailPattern.test(email);
}
//--------------------------------------------------------
const email = "test-email@pyplane.com";
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/g
const result = email.match(regex);
console.log(result)
// (1) ['test-email@pyplane.com']
//--------------------------------------------------------
// multiple @
const email = "test-email@pyplane@.com";
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/g
const result = email.match(regex);
console.log(result)
// null
/*
matchAll is a new method added to the String prototype in javascript as
part of es2020 which related to Regular Expressions.
The method returns an iterator
that returns all matched groups one after another.
*/
const iter = 'abc'.matchAll(/[a-c]/g);
console.log(Array.from(iter));
// [
// ["a", index:0, input: "abc", groups: undefined],
// ["b", index:1, input: "abc", groups: undefined],
// ["c", index:2, input: "abc", groups: undefined]
// ]
/*
javascript for a parseRgx function that converts the named groups in a regex matches into an object.
*/
const parseRgx = rgx => s => {
const keys = ['_global', ...rgx.match(/\$(\w+)/g).map(k => k.replace(/\$|:/g,''))];
const matches = s.match(new RegExp(rgx.replace(/\$\w+:/g,''))) || [];
return matches.reduce((res,val,i) => Object.assign({}, res, {[keys[i]]: val}), {});
}
const parseEmail = parseRgx('($user:\\w+)@($domain:\\w+)\\.(?:\\w+)');
parseEmail('foo@bar.com'); // { _global: "foo@bar.com", domain: "bar", user: "foo"}
/*
Use the plus + operator to match "one or more" occurrences in a regular expression. We can
remove all extra whitespace by replacing with a single space.
*/
const str = 'Hello my name is Emre';
console.log(str.replace(/\s+g, ' '));
// "Hello my name is Emre"
/*
javascript that reads the query parameters from a URL string.
*/
const params = (url, q = {}) => {
url.replace(/([^?&=]+)=([^&]*)/g,(_,k,v)=>q[k]=v)
return q;
}
console.log(params('?foo=bar&baz=bing'));
// outputs {foo:bar, baz:bing}
/*
This snippet can be used to remove HTML/XML tags from a string.
*/
const stripHTMLTags = str => str.replace(/<[^>]*>/g, '');
stripHTMLTags('<p><em>lorem</em> <strong>ipsum</strong></p>'); // 'lorem ipsum'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment