Master regular expressions in JavaScript

Liz Fedak
JavaScript in Plain English
7 min readNov 21, 2020

--

This guide is for leveling up your JavaScript regex game. Get started with Mozilla’s guide if you’re new to regular expressions.

Read the guide top to bottom as some of my examples build on each other assuming you’ve mastered the methods and regular expression syntax previously mentioned.

Cleaning up extra spaces using the string method replace

We can clean up white space in a string with a simple regular expression. The example below utilizes \s, which is regex for white spaces and +, which is regex for a match of 1 or more of the previous group. We use the JavaScript string method replace to find all white space matches that are 1 or more white spaces, and replace them with 1 white space.

The replace method is pretty versatile, but in the most basic form you pass it a match parameter and a string to replace matches with.

Note, this example also uses trim() to clean up leading and trailing white space. By using the global tag in your regular expression, it will replace all matches. You can also use replaceAll, but it’s not universally supported yet and won’t work in Node.js (as of 11/20/20).

Implement your own trim method

We could also implement our own Customtrim method that cleans up white space in the middle of text and not just at the start/end.

OR we can take this one step further and write our own leading/trailing regex to clean up the start/end of the line that cleans up the internal multi-space segments. (Note: there is a useful string method trimEnd and trimStart, so this is really just to show more regex 😉).

Using RegExp + String.prototype.match

The match() method retrieves the result of matching a string against a regular expression. — MDN

Per MDN, the RegExp object is used for matching text with a pattern. There are 2 ways to create a RegExp object, either with literal notation or a constructor. Let’s take a look at using the constructor:

This is a pretty contrived example, but say that you needed to count the number of letters in this string and wanted to use regex. You can write a for loop that will generate all of the applicable RegExp objects using the RegExp constructor. The gi part are the flags g and i that you add to the expression for global and case insensitive matches. The match method then finds all of the matches, and we can use the length method to check how many matches there are. Utilize“or empty array”, || [], in case there are no matches so you aren’t calling the length method on something that is undefined.

This is what one of the results of string.match looks like for the letter a, so we’re just calling the length method on an array of matches.

> [ 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'A', 'a', 'a' ]

And this is what your regular expressions all look like:

Using RegExp with escaped characters + Negative Lookbehind

You can make your regular expression expressions more complicated to look for something more specific. In this example, we’ll see examples of when you need to escape characters in your regex sequences in JavaScript.

In the code below, the RegExp’s goal is to find all of the capital letters that are not at the start of a sentence. (For simplicity, please ignore the very first letter, which is not covered by our regex expression.)

Testing on https://regexr.com/

The regular expression is using a “negative lookbehind”. A Negative Lookbehind/ahead looks at the text just before and after a string (depending on which one you’re using). For the Negative Lookbehind, it looks at the text that matches the passed expression just before our match. If it matches, then this ultimately is not a regex match because we don’t want that match.

Table from Rexegg.com https://www.rexegg.com/regex-lookarounds.html

In the code below, the regular expression probably looks pretty weird. If you cross-check it against the expression we wrote on https://regexr.com/ image above, you’ll see there are some extra backslashes in the string. This is because we have to escape the characters when typing them in JavaScript strings, and we had to escape the character in the regular expression in general because it is a special character, so we have \\.

Since this test is for capitalized letters, the i flag is removed from the expression, because that tests for case insensitivity. Here’s what our expressions will look like (left image).

Replace with a function argument

You can specify a function as the second parameter. In this case, the function will be invoked after the match has been performed. Note that the function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global. — MDN

Syntax:

const newStr = str.replace(regexp|substr, newSubstr|function)

We used a basic use of replace earlier in this article, where we just pass a regex and replace the matches with a given string.

With the function option, we can instead call the function after the match has been performed to transform the string. Below, we have an array of filenames that we want to transform. We want to keep IMG capitalized but lowercase the BIRTHDAY-PARTY and HALLOWEEN part of the filenames.

We use regex to extract the matches from the strings then use a function argument in replace to lowercase the letters. The function we pass to the replace method is a simple function that lowercases the string passed to it.

Since we want to leave IMG capitalized, we can use regex to extract the part of the filename that begins after IMG-, ending the match before the -001.jpeg portion. The regex match uses a positive look behind and a positive look ahead to contain our match to the applicable part of the string.

Using RegExp.prototype.test()

The test() method executes a search for a match between a regular expression and a specified string and returns true or false.

Say you need to validate a pin number and it could be either 4 or 6 digits. We can use a simple regular expression that uses \d, which matches digits, and {#}, a quantifier that matches the precise number.

The test method is called on the regular expression itself, not on a string, and the string is passed as an argument to the test method.

In the example below, we test an array of valid and invalid strings and log if they are valid or not.

Using String.prototype.search()

“The search() method executes a search for a match between a regular expression and aString object. When you want to know whether a pattern is found, and also know its index within a string, use search(). (If you only want to know if it exists, use the similar test() method on the RegExp prototype, which returns a boolean.) “— MDN

In the code below, say you want to validate if a user submits a comment and it has to include ‘yes’ or ‘no’. We can use the search method in an if block to verify that the user submitted a valid response. (You could just use test(), but I couldn’t think of a realistic example on the spot. 😅)

String.prototype.split()

In this example, we have an array of phone numbers in various formats, and we want to return an array with the phone numbers all cleaned up. This example is pretty straight forward. The regular expression uses a character set to match any of a -, ), (, ., or a space one or more times. It uses the split method to splits each number into an array of numbers, which it then joins back with just a hyphen.

Match

The match() method retrieves the result of matching a string against a regular expression. — MDN

We covered this one earlier, but here’s another example from a Code Wars challenge. The task is simply to count the total number of lowercase letters in a string. The global tag tells match to find all of the matches and the character set [a-z] is a match to any lower case letter. As mentioned earlier, we add in || [] because the result will otherwise be undefined if there are no matches and using the length method will throw an error on undefined.

const lowercaseCount = str => (str.match(/[a-z]/g) || []).length;

https://www.codewars.com/kata/56a946cd7bd95ccab2000055/javascript

Matchall

The matchAll() method returns an iterator of all results matching a string against a regular expression, including capturing groups.-MDN

Bear with me for this last example. Say you are typing out an order for a grocery pickup (Covid times) and need to input the order into a payment software as an object. The regular expression below finds all of the entries in the string that match the format of “# foodItem” and returns an iterator with the items. We can then use for…of on the iterator to build our object.

I hope these are useful as you encounter more realistic situations to use these regex and string methods. Drop a comment below if anything still doesn’t make sense or if you’d like to learn more about a different topic in JavaScript!

--

--