/Regular Expressions/
.test("Patterns in JavaScript")
Vijayabharathi Balasubramanian
Why?
- Find and replace
- Search Engine
- grep
- Checking for valid inputs
Syntax
let password="totally hidden";
/pattern/.test(password);
/pattern/.test("another");
//NO VARIABLES INSIDE PATTERN
/password/.test("xyz");
Match Strings
/a/.test('a');
/a/.test('b');
/a/.test('a'); //true
/a/.test('b'); //false
Match Anywhere
/a/.test('ab');
/a/.test('bc');
/a/.test('ca');
/a/.test('ab'); //true
/a/.test('bc'); //false
/a/.test('ca'); //true
More than one
/ab/.test('abc');
/bc/.test('abc');
/ac/.test('abc');
/ab/.test('abc'); //true
/bc/.test('abc'); //true
/ac/.test('abc'); //false
Numbers
/42/.test("42");
/42/.test("Answer: 42");
/42/.test("42"); //true
/42/.test("Answer: 42"); //true
OR Conditions
/4|2/.test("34");
/4|2/.test("23");
/4|2/.test("42");
/4|2/.test("35");
/4|2/.test("34"); //true
/4|2/.test("23"); //true
/4|2/.test("42"); //true
/4|2/.test("35"); //false
Character Sets
[set of possibilities for a single character]
Character Sets
/[42]/.test("2");
/[42]/.test("4");
/[42]/.test("42");
/[42]/.test("35");
/[42]/.test("2"); //true
/[42]/.test("4"); //true
/[42]/.test("42"); //true
/[42]/.test("35"); //false
Range of Characters
/[0-9]/.test("18");
/[0-9]/.test("90");
/[1-8]/.test("90");
/[0-9]/.test("18"); //true
/[0-9]/.test("90"); //true
/[1-8]/.test("90"); //false
Equivalent Expressions
/0|1|2|3|4|5|6|7|8|9/
===
/[0123456789]/
===
[0-9]
Multiple Ranges
/[0-9a-fA-F]/.test("AF3333");
/[0-9a-fA-F]/.test("Storm");
/[0-9a-fA-F]/.test("Z3");
/[0-9a-fA-F]/.test("AF3333"); //true
/[0-9a-fA-F]/.test("Storm"); //false
/[0-9a-fA-F]/.test("Z3"); //true!!
Shocker Ranges!!
/[+-=]/.test("a");
/[+-=]/.test("9");
/[+-=]/.test(";");
/[+-=]/.test("_");
/[+-=]/.test("a"); //false
/[+-=]/.test("9"); //true!!
/[+-=]/.test(";"); //true
/[+-=]/.test("_"); //false
Shocker Ranges!!
/[ -~]/.test("");
/[ -~]/.test("a");
/[ -~]/.test("0");
/[ -~]/.test("A");
/[ -~]/.test(";");
/[ -~]/.test("_");
/[ -~]/.test(""); //false
/[ -~]/.test("a"); //true
/[ -~]/.test("0"); //true
/[ -~]/.test("A"); //true
/[ -~]/.test(";"); //true
/[ -~]/.test("_"); //true
By ASCII-Table.svg: ZZT32derivative work: LanoxxthShaddow (ASCII-Table.svg) [Public domain], via Wikimedia Commons
[+-=]
[ -~]
Negative Char Set with...
/[^a-z]/.test("cba");
/[^0-9]/.test("42");
/[^0-9a-zA-Z]/.test("Route42");
/[^0-9a-zA-Z]/.test("$#");
/[^a-z]/.test("cba"); //false
/[^0-9]/.test("42"); //false
/[^0-9a-zA-Z]/.test("Route42"); //false
/[^0-9a-zA-Z]/.test("$#"); //true
^
Starts with...
/^a/.test("abc");
/^a/.test("cba");
/^[a-z]/.test("cba");
/^[0-9]/.test("42");
/^a/.test("abc"); //true
/^a/.test("cba"); //false
/^[a-z]/.test("cba"); //true
/^[0-9]/.test("42"); //true
^
- Overloaded
/^[^a-z]/.test("cba");
/^[^a-z]/.test("42");
/^[^0-9]/.test("cba");
/^[^0-9]/.test("42");
/^[^a-z]/.test("cba"); //false
/^[^a-z]/.test("42"); //true
/^[^0-9]/.test("cba"); //true
/^[^0-9]/.test("42"); //false
^
Ends with... $
/a$/.test("abc");
/a$/.test("cba");
/[a-z]$/.test("cba");
/[0-9]$/.test("42");
/a$/.test("abc"); //false
/a$/.test("cba"); //true
/[a-z]$/.test("cba"); //true
/[0-9]$/.test("42"); //true
Start|End to End
/^[a-z]$/.test("");
/^[a-z]$/.test("a");
/^[a-z]$/.test("z");
/^[a-z]$/.test("az");
/^[a-z]$/.test(""); //false
/^[a-z]$/.test("a"); //true
/^[a-z]$/.test("z"); //true
/^[a-z]$/.test("az"); //false
0 or 1 ?
/^[a-z]?$/.test("");
/^[a-z]?$/.test("z");
/^[a-z]?$/.test("az");
/^[a-z]?$/.test(""); //true
/^[a-z]?$/.test("z"); //true
/^[a-z]?$/.test("az"); //false
1 or more = +
/^[a-z]+$/.test("");
/^[a-z]+$/.test("z");
/^[a-z]+$/.test("az");
/^a+$/.test("ab");
/^[01]+$/.test("10010");
/^[a-z]+$/.test(""); //false
/^[a-z]+$/.test("z"); //true
/^[a-z]+$/.test("az"); //true
/^a+$/.test("ab"); //false
/^[01]+$/.test("10010"); //true
0 or more = *
/^[a-z]*$/.test("");
/^[a-z]*$/.test("z");
/^[a-z]*$/.test("az");
/^[a-z]*$/.test(""); //true
/^[a-z]*$/.test("z"); //true
/^[a-z]*$/.test("az"); //true
Escape with ... \
/\$/.test("abc");
/\$/.test("a$b");
/\^/.test("$^");
/\//.test("/");
/\$/.test("abc"); //false
/\$/.test("a$b"); //true
/\^/.test("$^"); //true
/\//.test("/"); //true
\ can do more than escape
\d
\D
\w
\W
\s
\S
.
a single numeric digit === [0-9]
any character other than numerals === [^0-9]
a single alpha-numeric char [A-Za-z0-9_]
any character other than alpha-numeric
a single white space, new line or tab
!\w - anything other than white space
match any single character
Number of Occurrences
{n}
{n,}
{min,max}
Match exactly n consecutive occurrences
Minimum n, maximum ∞
>=min && <=max
{n} - Exact Match
/a{3}/.test("");
/a{3}/.test("a");
/a{3}/.test("aaa");
/a{3}/.test("baaac");
/^a{3}$/.test("baaac");
/a{3}/.test(""); //false
/a{3}/.test("a"); //false
/a{3}/.test("aaa"); //true
/a{3}/.test("baaac"); //true
/^a{3}$/.test("baaac"); //false
{n,} - Minimum Match
/a{3,}/.test("aa");
/a{3,}/.test("aaaa");
/a{3,}/.test("baaac");
/^a{3,}$/.test("baaac");
/^a{3,}$/.test("aaaaa");
/a{3,}/.test("aa"); //false
/a{3,}/.test("aaaa"); //true
/a{3,}/.test("baaac"); //true
/^a{3,}$/.test("baaac"); //false
/^a{3,}$/.test("aaaaa"); //true
{n,m} - MinMaxMatch
/a{1,3}/.test("");
/a{1,3}/.test("ba");
/a{1,3}/.test("aaab");
/^a{1,3}$/.test("aaab");
/^a{1,3}$/.test("aaa");
/a{1,3}/.test(""); //false
/a{1,3}/.test("ba"); //true
/a{1,3}/.test("aaab"); //true
/^a{1,3}$/.test("aaab"); //false
/^a{1,3}$/.test("aaa"); //true
Food for thought
/^abc{3}$/.test("abccc");
/^abc{3}$/.test("abcabcabc");
/^abc{3}$/.test("abccc"); //true
/^abc{3}$/.test("abcabcabc"); //false?
Strong password
let pwd="password123";
let atLeast8Chars=/.{8,}/.test(pwd);
let oneLowerCase=/[a-z]/.test(pwd);
let oneUpperCase=/[A-Z]/.test(pwd);
let oneNumber=/\d/.test(pwd);
let oneSymbol=/[^ a-zA-Z0-9]/.test(pwd);
let isValidPassword= atLeast8Chars
&& oneLowerCase
&& oneUpperCase
&& oneNumber
&& oneSymbol;
console.log(isValidPassword);
Just unreadable code!
new RegExp(pattern)
let pattern="[a-z]";
/pattern/.test("zurich");
/pattern/.test("some pattern here");
let reg=new RegExp(pattern);
reg.test("zurich");
reg.test("some pattern here");
let pattern="[a-z]";
/pattern/.test("zurich"); //false
/pattern/.test("some pattern here"); //true
let reg=new RegExp(pattern);
reg.test("zurich"); //true
reg.test("some pattern here"); //true
Password
const isPasswordValid = pwd => {
let rules=[
".{8,}", // minimum 8 characters
"[a-z]", // at least one lowercase
"[A-Z]", // at least one uppercase
"\\d", // at least one digit
"[^ a-zA-Z0-9]" //at least one symbol
];
let validate = rule => new RegExp(rule).test(pwd);
return rules.every(validate);
}
let pwd="Pa$$w0rd";
isPassswordValid(pwd); //true
pwd="Pasword";
isPasswordValid(pwd); //false
Remembered Matches
(x)
(?:x)
x(?=y)
x(?!y)
Remember the match and recall by \1 , \2 ...
Do not remember the match. Just for grouping
Positive lookahead - match x followed by y
Negative lookahead - match x not followed by y
(x) - Remember and recall
/(a)\1/.test("ba");
/(a)\1/.test("baa");
/(\w)\1/.test("bob");
/(\w)\1/.test("matt");
/^(\w)\1$/.test("yy");
/(a)\1/.test("ba"); false
/(a)\1/.test("baa"); true
/(\w)\1/.test("bob"); false
/(\w)\1/.test("matt"); true
/^(\w)\1$/.test("yy"); true
Duplicates
(x) - Remember and recall
/(\d)(\d)\2\1/.test("1212");
/(\d)(\d)\2\1/.test("1221");
/(\d)(\d)\2\1/.test("1111");
/(\d)(\d)\2\1/.test("1212"); //false
/(\d)(\d)\2\1/.test("1221"); //true
/(\d)(\d)\2\1/.test("1111"); //true
Reversed
(?:x) - Just forget it
/^abc{3}$/.test("abccc");
/(?:ab){2}/.test("abab");
/(?:ab){2}\1/.test("ababab");
/^abc{3}$/.test("abccc"); //true
/(?:ab){2}/.test("abab"); //true
/(?:ab){2}\1/.test("ababab"); //false
General grouping
(?=) look who's next!
/x(?=y)/.test("wxyz");
/(?=.{3})/.test("ab");
/(?=.{2})/.test("ab");
/^(?=.{2})$/.test("ab");
/^(?=.{2}).*$/.test("abc");
/^.{2}$/.test("abc");
/x(?=y)/.test("wxyz"); true
/(?=.{3})/.test("ab"); false
/(?=.{2})/.test("ab"); true
/^(?=.{2})$/.test("ab"); false
/^(?=.{2}).*$/.test("abc"); true
/^.{2}$/.test("abc"); false
Positive look ahead
(?=) look who's next!
/^(?=.{8,})(?=.*[A-Z]+)(?=.*\d+).*$/.test("passw0rd");
/^(?=.{8,})(?=.*[A-Z]+)(?=.*\d+).*$/.test("Passw0rd");
/^(?=.{8,})(?=.*[A-Z]+)(?=.*\d+).*$/.test("Passw0r");
/^(?=.{8,})(?=.*[A-Z]+)(?=.*\d+).*$/.test("passw0rd"); false
/^(?=.{8,})(?=.*[A-Z]+)(?=.*\d+).*$/.test("Passw0rd"); true
/^(?=.{8,})(?=.*[A-Z]+)(?=.*\d+).*$/.test("Passw0r"); false
Positive look ahead
(?!) can't stand next!
/x(?!y)/.test("wxyz");
/x(?!y)/.test("zyxw");
/x(?!y)/.test("wxyz"); false
/x(?!y)/.test("zyxw"); true
Negative look ahead
Email Validation!
- Send a confirmation email!
RegExp Methods
- test - true / false
- exec - result in an array & can be called multiple times
String Methods
- match
- search
- replace
- split
String.Match
let str="FF3H3G3";
str.match(/[G-Z]/i);
str.match(/[G-Z]/ig);
let str="FF3H3G3";
str.match(/[G-Z]/i);
//["H", index: 3, input: "FF3H3G3"]
str.match(/[G-Z]/ig); //["G", "H"]
Returns Array
String.Search
let str="csv,file";
str.search(/,/);
str.search(/;/);
let str="csv,file";
str.search(/,/); //3
str.search(/;/); //-1
Returns index of match
String.Replace
str="csv,file,with,comma"
str.replace(",",";");
str.replace(/,/g,";");
str="csv,file,with,comma";//"csv,file,with,comma"
str.replace(",",";"); //"csv;file,with,comma"
str.replace(/,/g,";"); //"csv;file;with;comma"
Replace matches with new substring
String.Replace
var re = /(\w+)\s(\w+)/;
var str = 'John Smith';
var newstr = str.replace(re, '$2, $1');
console.log(newstr); // Smith, John
Replace with Matches
String.Split
Returns array
Final Test
//.test("code");
//.test("");
References
Thank you
You are all awesome!
Regular Expressins in JavaScript - Pattern matching fundamentals
By Vijayabharathi Balasubramanian
Regular Expressins in JavaScript - Pattern matching fundamentals
Basics of pattern matching in JavaScript using Regular Expression and its syntax.
- 1,898