Javascript | What is ES6? — Regular Expression
Regular expressions are an important part of working with strings in JavaScript, and like many parts of the language, they haven’t changed much in recent versions. ECMAScript 6, however, makes several improvements to regular expressions to go along with the updates to strings.
The Regular Expression y Flag (sticky)
ECMAScript 6 standardized the y
flag after it was implemented in Firefox as a proprietary extension to regular expressions. The y
flag affects a regular expression search’s sticky
property, and it tells the search to start matching characters in a string at the position specified by the regular expression’s lastIndex
property. If there is no match at that location, then the regular expression stops matching.
To see how this works, consider the following code:
let text = "hello1 hello2 hello3",
pattern = /hello\d\s?/,
result = pattern.exec(text),
globalPattern = /hello\d\s?/g,
globalResult = globalPattern.exec(text),
stickyPattern = /hello\d\s?/y,
stickyResult = stickyPattern.exec(text); console.log(result[0]); // "hello1 " console.log(globalResult[0]); // "hello1 " console.log(stickyResult[0]); // "hello1 " pattern.lastIndex = 1;
globalPattern.lastIndex = 1;
stickyPattern.lastIndex = 1;
result = pattern.exec(text);
globalResult = globalPattern.exec(text);
stickyResult = stickyPattern.exec(text); console.log(result[0]); // "hello1 " console.log(globalResult[0]); // "hello2 " console.log(stickyResult[0]); // Error! stickyResult is null
Here is the JSBin for the above: https://jsbin.com/vigive/1/edit?html,console
This example has three regular expressions. The expression in pattern
has no flags, the one in globalPattern
uses the g
flag, and the one in stickyPattern
uses the y
flag. In the first trio of console.log()
calls, all three regular expressions should return "hello1 "
with a space at the end.
After that, the lastIndex
property is changed to 1 on all three patterns, meaning that the regular expression should start matching from the second character on all of them. The regular expression with no flags completely ignores the change to lastIndex
and still matches "hello1 "
without incident. The regular expression with the g
flag goes on to match "hello2 "
because it is searching forward from the second character of the string ("e"
). The sticky regular expression doesn’t match anything beginning at the second character so stickyResult
is null
.
The sticky flag saves the index of the next character after the last match in
lastIndex
whenever an operation is performed. If an operation results in no match, thenlastIndex
is set back to 0.
The global flag behaves the same way, as demonstrated here:
let text = "hello1 hello2 hello3",
pattern = /hello\d\s?/,
result = pattern.exec(text),
globalPattern = /hello\d\s?/g,
globalResult = globalPattern.exec(text),
stickyPattern = /hello\d\s?/y,
stickyResult = stickyPattern.exec(text); console.log(result[0]); // "hello1 " console.log(globalResult[0]); // "hello1 " console.log(stickyResult[0]); // "hello1 " console.log(pattern.lastIndex); // 0 console.log(globalPattern.lastIndex); // 7 console.log(stickyPattern.lastIndex); // 7 result = pattern.exec(text);
globalResult = globalPattern.exec(text);
stickyResult = stickyPattern.exec(text); console.log(result[0]); // "hello1 " console.log(globalResult[0]); // "hello2 " console.log(stickyResult[0]); // "hello2 " console.log(pattern.lastIndex); // 0 console.log(globalPattern.lastIndex); // 14 console.log(stickyPattern.lastIndex); // 14
Here is the JSBin for the same: https://jsbin.com/vigive/2/edit?html,console
The value of lastIndex
changes to 7 after the first call to exec()
and to 14 after the second call, for both the stickyPattern
and globalPattern
variables.
There are two more subtle details about the sticky flag to keep in mind:
- The
lastIndex
property is only honored when calling methods that exist on the regular expression object, like theexec()
andtest()
methods. Passing the regular expression to a string method, such asmatch()
, will not result in the sticky behavior. - When using the
^
character to match the start of a string, sticky regular expressions only match from the start of the string (or the start of the line in multiline mode). WhilelastIndex
is 0, the^
makes a sticky regular expression no different from a non-sticky one. IflastIndex
doesn’t correspond to the beginning of the string in single-line mode or the beginning of a line in multiline mode, the sticky regular expression will never match.
As with other regular expression flags, you can detect the presence of y
by using a property. In this case, you’d check the sticky
property, as follows:
var pattern = /hello\d/y;
console.log(pattern.sticky); // true
The sticky
property is set to true if the sticky flag is present, and the property is false if not. The sticky
property is read-only based on the presence of the flag and cannot be changed in code.
If you enjoyed reading, make that heart go green! Recommend it to friends and of course, let me know if you have any feedback.
You can also join my slack community.
Do checkout http://www.programmingbuddy.club
Exercises for Practice: (optional)
Exercise 1:
If you have a string ‘xaxaxa’
and a regular expression as /a/y.
See below code and determine what will be the result on console.log() with comment (A)
const REGEX = /a/y;
REGEX.lastIndex = 2;
console.log(REGEX.test('xaxaxa')); //(A)
Exercise 2:
In the above example, if instead of REGEX.lastIndex = 2, we did a REGEX.lastIndex = 3 — What will be the output for (B)
and (D)
below:
const REGEX = /a/y;
REGEX.lastIndex = 3;
console.log(REGEX.test('xaxaxa')); //(B)
console.log(REGEX.lastIndex); // (D)