通常,当您执行类似操作'test'.match(/(e)/)
时会收到一个数组['e', 'e']
,其中第一个元素是匹配本身,第二个来自选择器(大括号),但是当使用全局修饰符时,'test'.match(/(e)/g)
它将省略匹配,而它不在情况下我根本不使用选择器。
我想知道是否以及在何处指定了以下行为(使用 Chromium 进行此测试)。
通常,当您执行类似操作'test'.match(/(e)/)
时会收到一个数组['e', 'e']
,其中第一个元素是匹配本身,第二个来自选择器(大括号),但是当使用全局修饰符时,'test'.match(/(e)/g)
它将省略匹配,而它不在情况下我根本不使用选择器。
我想知道是否以及在何处指定了以下行为(使用 Chromium 进行此测试)。
如果未设置全局标志 (g),则数组的元素 0 包含整个匹配项,而元素 1 到 n 包含任何子匹配项。此行为与未设置全局标志时的 exec 方法(正则表达式)(JavaScript)的行为相同。如果设置了全局标志,则元素 0 到 n 包含发生的所有匹配项。
http://msdn.microsoft.com/en-us/library/ie/7df7sf4x(v=vs.94).aspx
换句话说,当g
提供时,match
只收集最上面的匹配,忽略任何捕获组。
例子:
> s = "Foo Bar"
"Foo Bar"
> s.match(/([A-Z])([a-z]+)/)
["Foo", "F", "oo"]
> s.match(/([A-Z])([a-z]+)/g)
["Foo", "Bar"]
没有内置函数可以像 pythonfindall
那样从所有匹配项中收集所有组,但是使用以下代码很容易编写exec
:
function matchAll(re, str) {
var p, r = [];
while(p = re.exec(str))
r.push(p);
return r;
}
matchAll(/([A-Z])([a-z]+)/g, "Foo Bar")
结果:
[
Array[3]
0: "Foo"
1: "F"
2: "oo"
index: 0
input: "Foo Bar"
length: 3
__proto__: Array[0]
,
Array[3]
0: "Bar"
1: "B"
2: "ar"
index: 4
input: "Foo Bar"
length: 3
__proto__: Array[0]
]
该行为在ECMA 脚本语言规范中指定。本节详细描述了带和不带全局修饰符的正则表达式引擎所遵循的过程。
具体在第 11 点:If global is true,
Call the [[Put]] internal method of R with arguments "lastIndex", e, and true.