regex

March 15, 2023 - Reading time: 11 minutes

These past few weeks I learned about regular expressions. Here's a recap! Almost all examples come from FreeCodeCamp.

Methods

Test method

let stringToTest = "a string";
let regEx = /pattern/;
regEx.test(stringToTest); // returns false

returns true or false depending if the pattern is found or not

Match method

let ourStr = "Regular expressions";
let ourRegex = /expressions/;
ourStr.match(ourRegex); // returns ["expressions"]

returns an extraction of the string that matches the provided pattern.

Replace method

let wrongText = "The sky is silver.";
let silverRegex = /silver/;
wrongText.replace(silverRegex, "blue"); // returns "The sky is blue"

searches for the described pattern and replacing it by a value of your choice.

You can also access capture groups in the replacement string with dollar signs ($) (see group capture in Patterns/Group elements/Reuse group).

"Code Camp".replace(/(\w+)\s(\w+)/, '$2 $1'); // returns "Camp Code"

Positive and negative lookahead

This is actually not a method but a special pattern to look ahead in the string for patterns further along. It won't match the element.

Use (?=...) to verify the element ("...") is there

Use (?!=...) to verify the element ("...") is not there

let quit = "qu";
let noquit = "qt";
let quRegex= /q(?=u)/;
let qRegex = /q(?!u)/;
quit.match(quRegex); // returns ["q"] ("u" is there)
noquit.match(qRegex); // returns ["q"] ("u" is not there)

Greedy vs lazy matching

This is not a method either but note that regular expressions are by default greedy meaning they will find the longest possible part of a string that fits the regex pattern and returns it as a match.

let string = "titanic";
let regEx = /t[a-z]*i/;
string.match(regEx); // returns "titani"

You can use ? to change it to lazy matching meaning the regular expression will find the shortest possible part of the string.

let string = "titanic";
let regEx = /t[a-z]*?i/;
string.match(regEx); // returns "ti"

Flags

Append flag right after the end of a pattern (//) if you need to extend the search to the whole string and/or ignore letter case.

Global search

Use g flag to search or extract a pattern more than once.

let testStr = "Repeat, Repeat, Repeat";
let repeatRegex = /Repeat/g;
testStr.match(ourRegex); // returns ["Repeat", "Repeat", "Repeat"]

Ignore case

Use i flag to ignore letter case (ie the difference between uppercase and lowercase letters).

let repeatRegex = /ignorecase/i;

This regex can match the strings ignorecase, igNoreCase, and IgnoreCase.

Multiple flags

Just concatenate them, for instance

let regEx = /search/gi

Patterns

Define a character set (aka character class)

Define a character set between square brackets []

Inside, define a list of character or a range of characters, using a hyphen character - to seperate from and to elements. Letters and numbers can be combined.

let regEx1 = /aeiu/
let regEx2 = /[a-e]/
let regEx3 = /[3-9]/
let regEx4 = /[a-e3-9]/

let catStr = "cat";
let batStr = "bat";
let matStr = "mat";
let bgRegex = /[a-e]at/;
catStr.match(bgRegex); // returns ["cat"]
batStr.match(bgRegex); // returns ["bat"]
matStr.match(bgRegex); // returns null

Negate a character set

Add ^ at the beginning of the character set you want to negate

let regEx = /[^aeiou]/gi // matches everything that is not a vowel

Group elements

Use () to group elements

let testStr = "Pumpkin";
let testRegex = /P(engu|umpk)in/;
testRegex.test(testStr); // Returns true

Reuse group

A group is saved as a temporary "variable" that can be accessed within the same regex using a backlash and the number of the captured group (e.g. \1). The number corresponds to the position of their opening parentheses, starting at 1.

let repeatStr = "row row row your boat";
let repeatRegex = /(\w+) \1 \1/;
repeatRegex.test(repeatStr); // Returns true
repeatStr.match(repeatRegex); // Returns ["row row row", "row"]

Possible existence of an element

Use ? right after the element

let american = "color";
let british = "colour";
let rainbowRegex= /colou?r/;
rainbowRegex.test(american); // Returns true
rainbowRegex.test(british); // Returns true

Alternative element

Use | (OR operator) between each element

let regEx = /yes|no/

Any element

Use wildcard character . to match any one character

let humStr = "I'll hum a song";
let hugStr = "Bear hug";
let huRegex = /hu./;
huRegex.test(humStr); // returns true
huRegex.test(hugStr); // returns true

Litteral string

Type the string you're looking for between / and /

let testStr = "Hello, my name is Kevin.";
let testRegex = /Kevin/;
testRegex.test(testStr); // returns true

All letters, numbers and underscore

Use \w

let longHand = /[A-Za-z0-9_]+/;
let shortHand = /\w+/;

For everything but letters, numbers and underscore, use \W (short hand for [^A-Za-z0-9_])

All numbers

Use \d

let longHand = /[0-9]/;
let shortHand = /\d/;

For all non-numbers, use \D (short hand for [^0-9])

Whitespace characters

Use \s to look for whitespace, carriage return (\r), tab (\t), form feed (\f), new line (\n) and vertical tab (\v)

let longHand = /[\r\t\f\n\v]/;
let shortHand = /\s/;

For non-whitespace, use \S (shorthand for [^ \r\t\f\n\v])

Define beginning and/or end of a pattern

Beginning

Use ^ outside of a character set and at the beginning of the regex

let firstString = "Ricky is first and can be found.";
let notFirst = "You can't find Ricky now.";
let firstRegex = /^Ricky/;
firstRegex.test(firstString); // returns true
firstRegex.test(notFirst); // returns false

Ending

Use $ at the end of the regex

let theEnding = "This is a never ending story";
let storyRegex = /story$/;
storyRegex.test(theEnding); // returns true
let noEnding = "Sometimes a story will have to end";
storyRegex.test(noEnding); // returns false

Occurencies

One or more times

Use + right after the character than can be found one or more times

let string1 = "abc"
let string2 = "aabc"
let string3 = "abab"
let regEx = /a+/g
string1.match(regEx); // returns [ 'a' ]
string2.match(regEx); // returns [ 'aa' ]
string3.match(regEx); // returns [ 'a', 'a' ]

Zero or more times

Use * right after the character that can be found zero or more times

let soccerWord = "gooooooooal!";
let gPhrase = "gut feeling";
let oPhrase = "over the moon";
let goRegex = /go*/;
soccerWord.match(goRegex); // returns ["goooooooo"]
gPhrase.match(goRegex); // returns ["g"]
oPhrase.match(goRegex); // returns null

Number of matches

Exact number

Specify a certain number of patterns using curly bracket {}

let A4 = "haaaah";
let A3 = "haaah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleHA = /ha{3}h/;
multipleHA.test(A4); // returns false
multipleHA.test(A3); // returns true
multipleHA.test(A100); // returns false

Lower number

To only specify the lower number of patterns, keep the first number followed by a comma.

let A4 = "haaaah";
let A2 = "haah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleA = /ha{3,}h/;
multipleA.test(A4); // returns true
multipleA.test(A2); // returns false
multipleA.test(A100); // returns true

Lower and upper number

Put two numbers between the curly brackets, separated by a comma - for the lower and upper number of patterns.

let A4 = "aaaah";
let A2 = "aah";
let multipleA = /a{3,5}h/;
multipleA.test(A4); // returns true
multipleA.test(A2); // returns false