Consider the following Javascript script:

1
2
3
4
5
6
7
8
const regex = /<(\w+)>/g
const testString = "<location>"
// Check whether testString contains pattern "<slot>"
// If yes, extract the slot name

if (regex.test(testString)) {
console.log(regex.exec(testString)[1])
}

It seems to be a perfect logic extracting the tag name of the tag string: one uses test to prevent the situation that testString does not match. However, it would throw an error:

1
TypeError: regex.exec(...) is null

It just violates our intuition: the string do match the regex, but it could not be matched. So why does this happen?


As MDN has stated, invoking test on a regex with flag “global” set would set “lastIndex” on the original regex. That lastIndex allows user to continue test the original string since there may be more than one matched patterns. This is affecting the exec that comes along. So the proper usage of a regex with “g” flag set is to continue executing the regex until it returns null, which means no other pattern could be found in the string.

This behavior is sometimes undesirable, since in the above scenario, I just want to know whether the string matches the predefined pattern. And the reason I don’t want to create the regex on the fly is to save the overhead of creating an object.

One obvious solution is to remove “g” flag. But sometimes, we do want to keep the “g” flag to find if a string matches the given pattern, and we don’t wish to modify the internal state of regex. In that case, one can switch to string.search(regex) , which would always returns the index of first match, or -1 if not matched.


留言

2019-07-10