Back to Home

Methods of RegExp and String

In this article we’ll cover various methods that work with regexps in-depth.

str.match(regexp)

The method str.match(regexp) finds matches for regexp in the string str. It has 3 modes: 1. If the regexp doesn’t have flag pattern:g, then it returns the first match as an array with capturing groups and properties index (position of the match), input (input string, equals str):

let str = "I love JavaScript";
let result = str.match(/Java(Script)/);
alert( result[0] );     // JavaScript (full match)
alert( result[1] );     // Script (first capturing group)
alert( result.length ); // 2
// Additional information:
alert( result.index );  // 7 (match position)
alert( result.input );  // I love JavaScript (source string)
  1. If the regexp has flag pattern:g, then it returns an array of all matches as strings, without capturing groups and other details.
let str = "I love JavaScript";
let result = str.match(/Java(Script)/g);
alert( result[0] ); // JavaScript
alert( result.length ); // 1
  1. If there are no matches, no matter if there’s flag pattern:g or not, null is returned. That’s an important nuance. If there are no matches, we don’t get an empty array, but null. It’s easy to make a mistake forgetting about it, e.g.:
let str = "I love JavaScript";
let result = str.match(/HTML/);
alert(result); // null
alert(result.length); // Error: Cannot read property 'length' of null

If we want the result to be an array, we can write like this:

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

str.matchAll(regexp)

[recent browser=“new”] The method str.matchAll(regexp) is a “newer, improved” variant of str.match. It’s used mainly to search for all matches with all groups. There are 3 differences from match: 1. It returns an iterable object with matches instead of an array. We can make a regular array from it using Array.from. 2. Every match is returned as an array with capturing groups (the same format as str.match without flag pattern:g). 3. If there are no results, it returns an empty iterable object instead of null. Usage example: If we use for..of to loop over matchAll matches, then we don’t need Array.from any more.

str.split(regexp|substr, limit)

Splits the string using the regexp (or a substring) as a delimiter. We can use split with strings, like this: But we can split by a regular expression, the same way:

str.search(regexp)

The method str.search(regexp) returns the position of the first match or -1 if none found: The important limitation: search only finds the first match. If we need positions of further matches, we should use other means, such as finding them all with str.matchAll(regexp).

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

This is a generic method for searching and replacing, one of most useful ones. The swiss army knife for searching and replacing. We can use it without regexps, to search and replace a substring: There’s a pitfall though. When the first argument of replace is a string, it only replaces the first match. You can see that in the example above: only the first “-” is replaced by “:”. To find all hyphens, we need to use not the string “-”, but a regexp pattern:/-/g, with the obligatory pattern:g flag: The second argument is a replacement string. We can use special characters in it: For instance: For situations that require “smart” replacements, the second argument can be a function. It will be called for each match, and the returned value will be inserted as a replacement. The function is called with arguments func(match, p1, p2, …, pn, offset, input, groups): 1. match – the match, 2. p1, p2, …, pn – contents of capturing groups (if there are any), 3. offset – position of the match, 4. input – the source string, 5. groups – an object with named groups. If there are no parentheses in the regexp, then there are only 3 arguments: func(str, offset, input). For example, let’s uppercase all matches: Replace each match by its position in the string: In the example below there are two parentheses, so the replacement function is called with 5 arguments: the first is the full match, then 2 parentheses, and after it (not used in the example) the match position and the source string: If there are many groups, it’s convenient to use rest parameters to access them: Or, if we’re using named groups, then groups object with them is always the last, so we can obtain it like this: Using a function gives us the ultimate replacement power, because it gets all the information about the match, has access to outer variables and can do everything.

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

This method is essentially the same as str.replace, with two major differences: 1. If the first argument is a string, it replaces all occurrences of the string, while replace replaces only the first occurrence. 2. If the first argument is a regular expression without the g flag, there’ll be an error. With g flag, it works the same as replace. The main use case for replaceAll is replacing all occurrences of a string. Like this:

regexp.exec(str)

The regexp.exec(str) method returns a match for regexp in the string str. Unlike previous methods, it’s called on a regexp, not on a string. It behaves differently depending on whether the regexp has flag pattern:g. If there’s no pattern:g, then regexp.exec(str) returns the first match exactly as str.match(regexp). This behavior doesn’t bring anything new. But if there’s flag pattern:g, then: - A call to regexp.exec(str) returns the first match and saves the position immediately after it in the property regexp.lastIndex. - The next such call starts the search from position regexp.lastIndex, returns the next match and saves the position after it in regexp.lastIndex. - …And so on. - If there are no matches, regexp.exec returns null and resets regexp.lastIndex to 0. So, repeated calls return all matches one after another, using property regexp.lastIndex to keep track of the current search position. In the past, before the method str.matchAll was added to JavaScript, calls of regexp.exec were used in the loop to get all matches with groups: This works now as well, although for newer browsers str.matchAll is usually more convenient. We can use regexp.exec to search from a given position by manually setting lastIndex. For instance: If the regexp has flag pattern:y, then the search will be performed exactly at the position regexp.lastIndex, not any further. Let’s replace flag pattern:g with pattern:y in the example above. There will be no matches, as there’s no word at position 5: That’s convenient for situations when we need to “read” something from the string by a regexp at the exact position, not somewhere further.

regexp.test(str)

The method regexp.test(str) looks for a match and returns true/false whether it exists. For instance: An example with the negative answer: If the regexp has flag pattern:g, then regexp.test looks from regexp.lastIndex property and updates this property, just like regexp.exec. So we can use it to search from a given position: let regexp = /javascript/g; // (regexp just created: regexp.lastIndex=0) alert( regexp.test(“javascript”) ); // true (regexp.lastIndex=10 now) alert( regexp.test(“javascript”) ); // false

let str = '<h1>Hello, world!</h1>';
let regexp = /<(.*?)>/g;

let matchAll = str.matchAll(regexp);

alert(matchAll); // [object RegExp String Iterator], not array, but an iterable

matchAll = Array.from(matchAll); // array now

let firstMatch = matchAll[0];
alert( firstMatch[0] );  // <h1>
alert( firstMatch[1] );  // h1
alert( firstMatch.index );  // 0
alert( firstMatch.input );  // <h1>Hello, world!</h1>
Example:

Follow the lesson from Microsoft Web-Dev-For-Beginners course

Tags: string