当前位置:网站首页>The second regular match is inconsistent with the first one, and the match in the regular loop is invalid

The second regular match is inconsistent with the first one, and the match in the regular loop is invalid

2022-06-12 11:43:00 Jioho_

The problem of regular matching inaccuracy

Reappear the scene ( It is recommended that you open the console to try ):

let reg = /J/gi

for (let i = 0; i <= 10; i++) {
    
  console.log(reg.test('Jioho'))
}

// true  and  false  Alternate output 

Do you think it is a circulating pot ? Let's have an acyclic scenario

let reg = /i/gi
console.log(reg.test('Jioho')) // true
console.log(reg.test('Jioho')) // false
console.log(reg.test('Jioho')) // true
console.log(reg.test('Jioho')) // false
console.log(reg.test('Jioho')) // true

Why regular second match is invalid

It's because of... In regular expressions g , Loop matching problem

Regular lastIndex Literally, it's the last index , In fact, it means the beginning of regular expression Index location for next lookup , The first time is always for 0 Of , When the first search is finished, the lastIndex The value of is set to the index position of the last character of the matched string plus 1, The second search will be from lastIndex This is where we start , And so on . If not found , It will put lastIndex Reset to 0. It should be noted that ,lastIndex Attributes only work in regular expressions with global flags

So in the example above reg Only once , But it has been used many times, so that's why it happened

If the code changes to this , The output is as expected :

// 1.  Remove  g
let reg = /j/i
console.log(reg.test('Jioho'))
console.log(reg.test('Jioho'))
console.log(reg.test('Jioho'))

// 2.  Recreate the regular in the loop 
for (let i = 0; i <= 10; i++) {
    
  const reg = /j/gi
  console.log(reg.test('Jioho'))
}

Learn more about regular Regex

stay MDN The document has a detailed introduction :RegExp( Regular expressions )

See today's protagonist :RegExp.lastIndex

lastIndex Is a readable and writable integer property of a regular expression , Used to specify the starting index for the next match .

Note that it is readable and writable . And see the detailed introduction rules :

Only regular expressions use expressions that represent global retrieval “g” When marking , This property will work . At this point, the following rules apply :

  • If lastIndex Greater than the length of the string , be regexp.test and regexp.exec The match will fail , then lastIndex Set to 0.
  • If lastIndex Equal to the length of the string , And the regular expression matches the empty string , Then the regular expression matches from lastIndex Starting string .(then the regular expression matches input starting at lastIndex.)
  • If lastIndex Equal to the length of the string , And the regular expression does not match the empty string , The regular expression does not match the string ,lastIndex Set to 0..
  • otherwise ,lastIndex Is set to the next position following the last successful match .

The document also introduces a RegExp.prototype.compile() While the script is running ( again ) Compile regular expressions .

So we can do it in a loop or under a specific business logic , Recompile regular expressions

Last

The possible reasons for the invalidity of regular multiple matches have been found , Because of the use of g Loop matching tags , And the regular code is not recompiled after being used once , But there have been relevant matches before ,lastInedx Not for 0

There are many ways to solve this problem

  • Redeclare the regular expression every time
for (let i = 0; i <= 10; i++) {
    
  const reg = /j/gi
  console.log(reg.test('Jioho'))
}
  • Reset lastIndex
const reg = /j/gi
for (let i = 0; i <= 10; i++) {
    
  reg.lastIndex = 0
  console.log(reg.test('Jioho'))
}
  • Recompile regular
const reg = /j/gi
for (let i = 0; i <= 10; i++) {
    
  reg.compile()
  console.log(reg.test('Jioho'))
}
原网站

版权声明
本文为[Jioho_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010522465775.html