Home Software Development Guide JavaScript: Regular Expressions

JavaScript: Regular Expressions

by wforbes

(THIS ARTICLE IS A WORK IN PROGRESS)

Regular Expressions (Regex) are a very powerful way to work with text. They let you efficiently and quickly search through it, filter it, and match patterns in it.

A simple example of this would be searching through a paragraph for every instance of the word “of”. Without Regex you would have to write numerous lines of code to parse through the text and test each character in it. First test for ‘o’ if it immediately followed a space character ‘ ‘, then each time you found one check the next character to see if it was an ‘f’, and then check if that ‘f’ was followed by another space character ‘ ‘. Finally, you’d keep a tally count of each occurrence of these.

Now imagine how much more code it would take to search for a longer word or a set of different words. Imagine how much processing time it would take to search through a gigantic set of text. If you were to search for the word ‘antidisestablishmentarianism’ within a set of text that’s a million lines long, not only would it take a little while to write the code, but then that code would take a while to run.

That’s a really basic example. You’ll probably encounter much more complicated search or matching algorithms that need conditional logic. Consider a situation where you conditionally need to look for a phrase within text where it begins with a certain letter or number combination, contains specific letters or numbers after that, and ends in a specific way. Like recognizing a valid email format. A valid email will usually begin with letters or numbers for the Local-Part, but may not contain some types of symbols and be only a certain length. Then it contains an ‘@’ symbol, followed by the Domain which has its own limitations. Then it ends with a ‘.’ period character followed by at least two characters afterward. While it’s very possible to write some code in whatever programming language you know to accomplish that, regular expressions provide a faster, more efficient way to get the job done.

While going through the Regular Expressions tutorials on FreeCodeCamp I started keeping the notes you will find on this page. As I get better and learn more about Regular Expressions I will keep improving the information found here and add more resources as I go. I strongly suggest you check out the FreeCodeCamp Regex tutorials in the meantime.

RegExr.com is another great resource for learning Regular Expressions, and has an awesome tool built into their site to run and experiment with Regex patterns.

The Mozilla Web Docs has a whole chapter on Regular Expressions that you can check out as well.

Regex Basics

Regular Expressions (Regex) are patterns of text that you write with special symbols and syntax to specify what you’d like to search for or match in the text. Running the Regex patterns you create can be done in just about any programming language. This article is about JavaScript, so that’s what we’ll concentrate on. Although it’s important to remember that each language has somewhat different ways to process your Regex patterns.


Creating Regex And Testing With It

One of the most simple Regex patterns you can use looks a lot like plain text. If you wanted to find the word “awesome” in the string “JavaScript is awesome, don’t listen to the haters”, you would use the pattern: /awesome/. It’s the set of characters you want to search for surrounded by forward slashes, instead of surrounded by quotes like you would with a normal string.

JavaScript has a few different ways to run Regex patterns. Here we’ll use the .test() method, which you can call on Regex patterns. We’ll define the string we want to search through “JavaScript is awesome, don’t listen to the haters” in a variable, then define our Regex pattern /awesome/ in a variable, and finally we’ll call the .test() method on our pattern variable, passing our string variable into it as a parameter.

let phraseString = "JavaScript is awesome, don't listen to the haters"; //string to test on
let regexPattern = /awesome/; //regex pattern to test for
regexPattern.test(phraseString); //testing the string for the regex pattern

Boom! Wait… Nothing happened. What gives?

Well the .test() method returns a boolean, true or false to communicate whether the string you passed as in the parameter contains the Regex pattern or not. In our case it returns true. So, for example, you could use it as a conditional in an if statement:

let phraseString = "JavaScript is awesome, don't listen to the haters"; //string to test on
let regexPattern = /awesome/; //regex pattern to test for
if (regexPattern.test(phraseString)) { //testing the string for the regex pattern, returning true
  //True: phraseString does contain the pattern 'awesome'!
}

The .test() method is great if you simply want to just see if a string contains something with a true (yes it’s there) or false (no it’s not in there).

More Dynamic Patterns Using The RegExp Object

You may be wondering: “That’s great and all, but what if the Regex pattern I’m going to use might be changing or coming from user input? How can I make a dynamic pattern?”

Well, you’re in luck! There’s a way to define your Regex pattern so it compiles at runtime instead of literally defining it in code. You can use the RegExp object! Let’s look at the same example but use the RegExp object’s constructor to define our RegExp pattern from a string…

let phraseString = "JavaScript is awesome, don't listen to the haters"; //string to test on
let regexString = "awesome"; //string to use as a pattern
let regexPattern = new RegExp(regexString); //creating the regex pattern using the RegExp object
if (regexPattern.test(phraseString)) { //testing the string for the regex pattern, returning true
  //True: phraseString does contain the pattern 'awesome'!
}

Defining your Regular Expression pattern this way lets you pass virtually any string in to the RegExp object constructor and… *presto-chango!*… out comes a Regex pattern you can use.

Test For Multiple Matches With The Global Flag

Running the .test() method the way the previous examples demonstrate will let you see if the string contains your pattern with a simple true or false, just once. There is a way to continue to .test() a string, but it will require learning a new concept. Flags! You add a flag to your Regex pattern by either appending a certain letter to the end of your literal Regex pattern definition or through passing that certain letter to the RegExp object constructor as the second parameter. There are a few different flags you can use, but for this functionality, we’ll use the letter ‘g‘ for global. We’ll also look at a new property of the Regex pattern ‘.lastIndex‘:

let phraseString = "JavaScript is awesome, don't listen to the haters"; //string to test on

let regexString = "awesome"; //string to use as a pattern
let regexPattern = new RegExp(regexString, "g"); //using "g" (global flag) as second parameter
console.log(regexPattern.test(phraseString)); //output: true
console.log(regexPattern.test(phraseString)); //output: false

//Global flag used with literal regex declaration
let literalRegex = /awesome/g; //regex pattern using "g" (global flag)
console.log(literalRegex.test(phraseString)); //output: true
console.log(literalRegex.test(phraseString)); //output: false

//With global flag set, calling .test() once returns true for the first occurance
//  but calling .test() a second time returns false because there aren't more occurances
//Global flag keeps track of where you left matching
//  with the lastIndex property, as the index your last match ended with

let secondPhrase = "JavaScript is awesome, so awesome that it's super awesome!"; //string to test on
let secondRegex = new RegExp(regexString, "g"); //creating a new RegExp object
console.log(secondRegex.lastIndex);          //output: 0 [the beginning of the string]
console.log(secondRegex.test(secondPhrase)); //output: true
console.log(secondRegex.lastIndex);          //output: 21 [the index right after the first match]
console.log(secondRegex.test(secondPhrase)); //output: true
console.log(secondRegex.lastIndex);          //output: 33 [the index right after the second match]
console.log(secondRegex.test(secondPhrase)); //output: true
console.log(secondRegex.lastIndex);          //output: 57 [the index right after the third match]
console.log(secondRegex.test(secondPhrase)); //output: false

references:
FreeCodeCamp.com’s “Using The Test Method” tutorial
MDN: Regular Expressions
MDN: RegExp.prototype.test() documentation