Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a RegExp with global flag give wrong results?

What is the problem with this regular expression when I use the global flag and the case insensitive flag? Query is a user generated input. The result should be [true, true].

var query = 'Foo B'; var re = new RegExp(query, 'gi'); var result = []; result.push(re.test('Foo Bar')); result.push(re.test('Foo Bar')); // result will be [true, false] 

var reg = /^a$/g;  for(i = 0; i++ < 10;)     console.log(reg.test("a"));
like image 648
about Avatar asked Oct 05 '09 15:10

about


People also ask

What does the global flag do in regex?

The " g " flag indicates that the regular expression should be tested against all possible matches in a string. A regular expression defined as both global (" g ") and sticky (" y ") will ignore the global flag and perform sticky matches.

What function perform case insensitive and global searches in regexp?

For a global, case-insensitive search, use the "i" modifier together with the g modifier.

What is pattern flags in regex?

A regular expression consists of a pattern and optional flags: g , i , m , u , s , y . Without flags and special symbols (that we'll study later), the search by a regexp is the same as a substring search. The method str. match(regexp) looks for matches: all of them if there's g flag, otherwise, only the first one.

Which of the following regexp methods will return a true if a pattern match is present in a string?

exec(str) The regexp. exec(str) method returns a match for regexp in the string str .


1 Answers

A RegExp object with the g flag keeps track of the lastIndex where a match occurred, so on subsequent matches it will start from the last used index, instead of 0. Take a look:

var query = 'Foo B'; var re = new RegExp(query, 'gi'); var result = []; result.push(re.test('Foo Bar'));  alert(re.lastIndex);  result.push(re.test('Foo Bar'));

If you don't want to manually reset lastIndex to 0 after every test, just remove the g flag.

Here's the algorithm that the specs dictate (section 15.10.6.2):

RegExp.prototype.exec(string)

Performs a regular expression match of string against the regular expression and returns an Array object containing the results of the match, or null if the string did not match The string ToString(string) is searched for an occurrence of the regular expression pattern as follows:

  1. Let R be this RexExp object.
  2. Let S be the value of ToString(string).
  3. Let length be the length of S.
  4. Let lastIndex be the value of the lastIndex property on R.
  5. Let i be the value of ToInteger(lastIndex).
  6. If the global property is false, let i = 0.
  7. If i < 0 or i > length then set the lastIndex property of R to 0 and return null.
  8. Call [[Match]], giving it the arguments S and i. If [[Match]] returned failure, go to step 9; otherwise let r be its State result and go to step 10.
  9. Let i = i+1.
  10. Go to step 7.
  11. Let e be r's endIndex value.
  12. If the global property is true, set the lastIndex property of R to e.
  13. Let n be the length of r's captures array. (This is the same value as 15.10.2.1's NCapturingParens.)
  14. Return a new array with the following properties:
  • The index property is set to the position of the matched substring within the complete string S.
  • The input property is set to S.
  • The length property is set to n + 1.
  • The 0 property is set to the matched substring (i.e. the portion of S between offset i inclusive and offset e exclusive).
  • For each integer i such that i > 0 and i ≤ n, set the property named ToString(i) to the ith element of r's captures array.
like image 154
Ionuț G. Stan Avatar answered Oct 12 '22 23:10

Ionuț G. Stan