var regexAbc = /a(b)c/gi console.log(regexAbc.exec("abc")) // ["abc", "b"] console.log(regexAbc.exec("abc")) // null console.log(regexAbc.exec("abc")) // ["abc", "b"] console.log(regexAbc.exec("abc")) // null
为什么会出现这样结果不一样的情况
欧阳克2016-11-11 11:47:54
如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1
个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2
个子表达式相匹配的文本(如果有的话),以此类推。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index
属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看得出,在调用非全局的 RegExp
对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。
但是,当 RegExpObject
是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex
属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的
lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec()
方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
提示和注释
重要事项:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。
提示:请注意,无论
RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是 exec() 与
String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用 exec()
方法是唯一一种获得全局模式的完整模式匹配信息的方法。
三叔2016-11-11 11:47:40
A JavaScript RegExp object is stateful.
When the regex is global, if you call a method the same regex object, it will start from the index past the end of the last match.
When no more matches are found, the index is reset to 0 automatically.
javascript 的正则表达式是有状态的。尤其是exec方法,是有副作用的。当其匹配成功的时候reg.lastIndex会被改变。因此导致了间隔的返回null的情况
To reset it manually, set the lastIndex property.
每次匹配完可以通过这样手动重置,以保证下一次匹配的结果是正常的
reg.lastIndex = 0;
尤其是在循环中使用同一只正则表达式的时候,尤其需要注意这一点