Methods of RegExp and String

On this page, you will see how various methods work in-depth with regular expressions in JavaScript.

Particularly, we will cover methods such as str.match(regexp), str.matchAll(regexp), str.split(regexp|substr, limit), str.search(regexp), str.replace(str|regexp, str|func), regexp.exec(str), and regexp.test(str).

str.match(regexp)

The str.match(regexp) method detects matches for regexp in the string str.

This method includes the following three modes:

  1. In case there is no g flag in the regexp, it returns the initial match as an array with the properties index, input, as well as capturing groups, like here:
    let str = "I learn JavaScript";
    let result = str.match(/Java(Script)/);
    
    console.log(result[0]); // JavaScript (full match)
    console.log(result[1]); // Script
    console.log(result.length); // 2
    // Additional information:
    console.log(result.index); // 8 (match position)
    console.log(result.input); // I learn JavaScript
  2. If there is g flag in the regexp, then it returns an array of all the matches as strings, excluding capturing groups or other details, like this:
    let str = "I like JavaScript";
    let result = str.match(/Java(Script)/g);
    console.log(result[0]); // JavaScript
    console.log(result.length); // 1
  3. In case no matches are found, no matter there is g flag or not, null will be returned. It’s an important nuance. In case there is no match, you won’t receive an empty array but null. Forgetting that will lead to mistakes.
    let str = "I love JavaScript";
    let result = str.match(/HTML/);
    console.log(result); // null
    console.log(result.length); // Error: Cannot read property 'length' of null

In case you want to get the result as an array, you should write it as follows:

let result = str.match(regexp) || [];

str.matchAll(regexp)

The str.matchAll(regexp) method is an enhanced version of the str.match method. Primarily, it is used to look for all matches with all groups. But, it has three differences from str.match, that are as follows:

  1. It doesn’t return an array, but an iterable object with matches. A regular array can be made from it with Array.from.
  2. Each match is returned as an array with capturing groups.
  3. In case of having no matches, it returns an empty iterable object, not null.

An example of using the str.matchAll(regexp) looks like this:

let str = '<p>Welcome to W3Docs</p>';
let regexp = /<(.*?)>/g;
let matchAll = str.matchAll(regexp);
console.log(matchAll); // [object RegExp String Iterator], not array, but an iterable
matchAll = Array.from(matchAll); // array now
let firstMatch = matchAll[0];
alert(firstMatch[0]); // <p>
console.log(firstMatch[1]); // p
console.log(firstMatch.index); // 0
alert(firstMatch.input); // <p>Welcome to W3Docs</p>

Using for..of for looping over the matches of matchAll, Array.from is not needed.

str.split(regexp|substr, limit)

This method helps to split the string with regexp as a delimiter.

The split method can be used with strings, in this way:

console.log('21-34-75'.split('-')) // array of [21, 34, 75]

In the same way, you can split by a regular expression:

console.log('21, 34, 75'.split(/,\s*/)) // array of [21, 34, 75]

str.search(regexp)

The str.search(regexp) method is used for returning the position of the first match. In case of finding no match, -1 is returned, like this:

let str = "Welcome to W3Docs";
console.log(str.search(/docs/i)); // 13 (first match position)

There is an essential limitation, you should note: only the first match is found by the search.

For example, if you want to find more matches, you can use another method such as str.matchAll(regexp).

str.replace(str|regexp, str|func)

This is a generic method and is used to search and replace one of the most efficient ones.

It can be used without regexps for searching and replacing a substring, like this:

console.log('21-34-75'.replace("-", ":")) // 21:34-75

The second argument is considered a replacement string, hence a special character can be used in it.

Here is an example:

let str = "John Smith";
// swap first and last name
console.log(str.replace(/(John) (smith)/i, '$2, $1')) // Smith, John

For situations, requiring smart replacement, the second argument can act as a function.

That function can be called with arguments func(match, p1, p2, ..., pn, offset, input, groups):

  1. match –it’s the match,
  2. p1, p2, ..., pn – the capturing group contents (if there exist any),
  3. offset – the match position,
  4. input – the string of the source,,
  5. groups – named groups object.

In case no parentheses exist in the regexp, only three arguments should be used func(str, offset, input).

Here is an example of uppercasing all the matches:

let str = "javascript and php";
let result = str.replace(/javascript|php/gi, str => str.toUpperCase());
console.log(result); // JAVASCRIPT and PHP

Replacing each match by its position in the string will look as follows:

console.log("Go-go-Go".replace(/Go/gi, (match, offset) => offset)); // 0-3-6

Once using named groups, the groups object is always the last, so it can be obtained like this:

let str = "John Smith";
let result = str.replace(/(?<name>\w+) (?<surname>\w+)/, (...match) => {
	let groups = match.pop();
	return `${groups.surname}, ${groups.name}`;
});
console.log(result); // Smith, John

When you use a function, it gives you ultimate replacement power: it receives all the information about the match, having access to outer variables.

regexp.exec(str)

The regexp.exec(str) method is used for returning a match for the regexp in the string str. The main difference of this method is that it is called on a regexp, not a string.

Its behavior is different depending on whether the regexp includes the g flag or not.

In case of having no g flag, it returns the first match, like the str.match(regexp) method. It won’t bring anything new.

In case of having the str.match(regexp) flag, the following happens:

  • Calling regexp.exec(str) will return the first match, saving the position right after it in the regexp.lastIndex property.
  • The following such call begins the search from the regexp.lastIndex position, returning the next match and saving the position after that in regexp.lastIndex.
  • In case of finding no matches, regexp.exec will return null and reset regexp.lastIndex to 0.

The regexp.exec method can be used to look from a specific position by manually setting lastIndex.

Here is an example:

let str = 'Welcome to W3Docs';
let regexp = /\w+/g; // without flag "g", lastIndex property will be ignored
regexp.lastIndex = 10; // look for from the tenth position (from the comma)
console.log(regexp.exec(str)); // W3Docs

In case of replacing the g flag with y, no matches will be found, because at position 5 there is no word:

let str = 'Welcome to W3Docs';
let regexp = /\w+/y;
regexp.lastIndex = 10; // look for right at position 5
console.log(regexp.exec(str)); // null

This method is handy in circumstances when it is necessary to read something from the string with regexp, at a certain position, not further.

regexp.test(str)

The regexp.test(str) method searches for a match, returning true/false depending on whether it exists or not.

Here is an example with a positive result:

let str = "I learn JavaScript";
// these two tests do the same
console.log(/learn/i.test(str)); // true
console.log(str.search(/learn/i) != -1); // true

How, let’s check out one with a negative result:

let str = "Go-go-go";
console.log(/like/i.test(str)); // false
console.log(str.search(/like/i) != -1); // false

If the regexp has g flag, then this method searches from the regexp.lastIndex property and updates like the regexp.exec method. Hence, it can be used for searching from a specific position, like this:

let regexp = /like/gi;
let str = "I like JavaScript";
// start the search from position 11:
regexp.lastIndex = 11;
console.log(regexp.test(str)); // false (no match)

It is also essential to know that using the same global regexp to different inputs, it can bring wrong results because regexp.test call advances the regexp.lastIndex property. Therefore, the search in another string can start from the non-zero position.

Let’s check out an example:

let regexp = /javascript/g; // (regexp.lastIndex=0)
console.log(regexp.test("javascript")); // true (regexp.lastIndex=10 now)
console.log(regexp.test("javascript")); // false

It happens as in the second test regexp.lastIndex is non-zero. For working around that, it is possible to set regexp.lastIndex = 0 before every search.Rather than calling methods on regexp, you can use string methods str.match/search/… that don’t use lastIndex.




Do you find this helpful?

Related articles