TOC
Regular Expressions:

Search/match with Regular expressions

At this point in the tutorial, we have talked about what regular expressions are, how they can act differently based on the options (flags) you specify, and we have even seen a couple of basic examples of how regular expressions can be used to look for a match in a string.

But we still haven't seen the full potential of regular expressions in JavaScript. As I mentioned earlier, they are very well integrated into the JavaScript language, as we'll see in this article. We will look into the methods found on the RegExp object, but we'll also talk about the methods found on the String object relating directly to regular expressions.

RegExp.test()

We already saw this method in action in the introduction article, but just to be thorough, allow me to mention it again. The test() method will simply check whether a match can be made on a string using the regular expression in question, for instance like this:

let testString = "Hello, I'm 42 years old";
let regex = new RegExp("[0-9]+");
if(regex.test(testString))
	alert("String contains a number!");
else
	alert("String does NOT contain a number!");

If you prefer the literal notation, the above example could look like this instead:

let testString = "Hello, I'm 42 years old";
if(/[0-9]+/.test(testString))
	alert("String contains a number!");
else
	alert("String does NOT contain a number!");

The test() method is quite simple, but very useful in a lot of situations.

RegExp.exec()

This is where it starts to get more interesting. You can use the exec() method to find one or several matches within a string. But let's first see what will happen if a match can't be made:

let testString = "Hello, I'm forty-two years old";
let regex = new RegExp("[0-9]+");
let result = regex.exec(testString);
alert("Result: " + result);

We simply get a NULL back. Let's try an example where we can indeed get a match:

let testString = "Hello, I'm 42 years old";
let regex = new RegExp("[0-9]+");
let result = regex.exec(testString);
alert("Result: " + result);
Result: 42

Now we get the expected match, as we can see from the result. However, if we look more closely, we'll notice that the result of the method is in fact an object with the matched string(s), as well as some additional properties about where the matches were made. Here's an example:

let testString = "Hello, I'm 42 years old";
let regex = new RegExp("[0-9]+");
let result = regex.exec(testString);
if(result != null)
	alert("Age: " + result + " (found at position " + result.index + ")");
Age: 42 (found at position 11)

So far, we have only located a single match, but obviously there could be more than one. The exec() method will only return the first match, but after doing that, it will update the lastIndex property of the RegExp object, and use this as the starting position if executed again. We can use this to our advantage and put it in a loop, to extract all matches in a string, like this:

let testString = "I'm 42, you're 24 and my dog is 7 years old";
let regex = new RegExp("[0-9]+", "g");
let result;
while(result = regex.exec(testString))
{
	alert("Match: " + result + " (position: " + result.index + ")");
}
Match: 42 (position: 4)
Match: 24 (position: 15)
Match: 7 (position: 32)

A very important detail here is the g (global) flag I set on the RegExp object - you need this to get multiple matches with the exec() method.

str.search()

When moving on to the regex related functions found on the String object, we find the search() function as one of the most basic ones. It will simply return the position of the first match, if any, or -1 if no matches can be made:

let testString = "I'm 42, you're 24 and my dog is 7 years old";
alert("First position: " + testString.search(/[0-9]/));
alert("First position: " + testString.search(/xxx/));

Notice how I now call the function search() on the testString variable, with a regular expression as the parameter.

Since the search() function only finds the first match, and only returns a position and no other relevant information, it's not so commonly used. Instead, you would often use the match/matchAll() functions or the exec() function.

str.match()

The match() function works much like the exec() function, but it's found on the String object instead of the RegExp object. Therefore, it works the other way around - you call it on a string and supply the regex to use as the parameter. Here's an example:

let testString = "I'm 42, you're 24 and my dog is 7 years old";
let regex = new RegExp("[0-9]+", "g");
let result = testString.match(regex);
alert(result);

As you can see, all the ages found in the string are returned as an Array and you are now free to iterate through this array or use it in any other way you might like. Just make sure that you check the result before using it like an array, because if no matches are found, NULL will be returned instead.

Also, I would like for you to pay special attention to the g (global) flag I set on the RegExp object - without it, only the first match would be returned. On the other hand, when the g flag is used for the match() function, no capturing groups are returned (more on those later on). If you need to use capturing groups AND do a global match, you need to use the exec() function or the recently added matchAll() function.

str.matchAll()

Important: The matchAll() function is a fairly recent addition to the JavaScript language - in fact, most modern browsers didn't include it prior to 2019. So, if you want to support older browsers, you need to use an alternative function (exec() or match()) or a polyfill.

The matchAll() function allows you to get a complete list of matches, including capturing groups, much like the exec() function, but without having to manually loop and call the function multiple times to obtain all the matches. It returns a so-called iterable object, which you can loop through or turn into an array. Inside of it, you will find items with information about each match, much like the exec() function. Let's see it in action:

let testString = "I'm 42, you're 24 and my dog is 7 years old";
let regex = new RegExp("[0-9]+", "g");
let result = testString.matchAll(regex);
for(let match of result)
{
	alert("Age: " + match + " (found at position " + match.index + ")");
}

Again you will notice the g (global) flag on the RegExp object, but this time, it's not optional - you simply can't use the matchAll() function without it and if you try, an error will be thrown. Also notice that if no matches are found, the matchAll() function will return an empty iterable object and NOT a NULL, as we were used to with the other functions.

str.split()

The last function we'll look into, is the split() function. It allows you to split a string into parts, based on a regular expression. Actually, the split() function is not entirely regex related - you can use a simple string to define the delimiter/separator, like this:

let testString = "01-02-2042";
alert(testString.split("-"));

This will split the string into parts based on the dash (-) character, resulting in an array of the 3 numbers found in the string. However, what if the string wasn't necessarily so neatly formatted? It could be that the user was able to use various characters to separate the numbers - for more complex situations like that, you can supply a regular expression to the function instead:

let testString = "01/02-2042";
let regex = new RegExp("[-/]");
alert(testString.split(regex));

With that simple regex, you can now accept both dashes and forward slashes as separators, and you can easily extend the regex to accommodate more use cases, if needed.

Summary

In this article, we have discussed all the methods for using regular expressions in combination with JavaScript to search for strings. As you can see, there are several methods which can help you, depending on what you need to accomplish. In the next couple of articles, we'll dig even deeper into all the cool stuff you can do with this powerful tool.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!