需要帮助使用JavaScript正则表达式进行全局匹配

4

我是JavaScript的新手,有一个关于正则表达式的问题。我有以下代码:

var patt3=new RegExp(/(July|August)\s+\d{1,2}(\s|,)\d{4}/g);
var str3 = "August                               12,1988";
var match3 = str3.match(patt3);
document.write(match3.toString() + "<br/>");

输出结果为:1988年8月12日

下面是同样的代码,但是将正则表达式末尾的 'g' 去除了:

var patt3=new RegExp(/(July|August)\s+\d{1,2}(\s|,)\d{4}/);
var str3 = "August                               12,1988";
var match3 = str3.match(patt3);
document.write(match3.toString() + "<br/>");

输出结果为: 1988年8月12日,八月,,。
从我在网上找到的定义来看,'g'应该匹配所有模式出现的位置。但我仍然有些困惑,不知道'g'对代码有什么影响。
如果有任何解释,将不胜感激。
提前致谢。
3个回答

4
关键的区别在于,如果正则表达式模式是全局的,string.match 方法的行为将有所不同。定义如果模式是全局的,将返回包含所有匹配项的数组。在您的情况下只有一个匹配项,但您可以通过以下示例看到区别。

let matches = "aaaa".match(/a(a)/g); 
console.log(matches) // returns ["aa", "aa"]

然而,如果该模式不是全局匹配,该方法将返回与第一个匹配项对应的数组。该数组在第一个位置包含完整匹配字符串,在其他位置包含捕获内容。捕获内容是由括号分隔的正则表达式中的位。再次举个例子,你可以看到以下差异:

"aaaa".match(/a(a)/g); // returns ["aa", "a"]

最后,我想指出您代码中的一些小问题。

首先,您不需要在此处使用new Regexp构造函数。可以直接使用正则表达式字面量。

var patt3 = /(July|August)\s+\d{1,2}(\s|,)\d{4}/g

其次,不要盲目地使用“toString”方法。在你的情况下,你将该方法应用于数组,这就是为什么你得到奇怪的结果的原因。
最后,学会使用开发者工具,包括调试器和控制台日志输出。与滥用document.write和alert相比,它更具表现力和生产力。
console.write(match3)

1

g只匹配整个模式的所有出现。它不能像PHP的preg_match_all一样匹配组。没有g,它只匹配模式的第一个出现(matches[0]),并且所有匹配的组都是其他数组元素。

如果您想要获取嵌套匹配,可以使用John Resig所描述的概念来实现:

str3.replace(patt3, function () {
    //This is the first captured group in all matches iterated over
    console.log(arguments[1]);
});

0

引用文档中对于String.match的说明:

如果正则表达式不包含g标志,则返回与regexp.exec(string)相同的结果。

如果正则表达式包含g标志,则该方法返回一个包含所有匹配项的Array,如果没有匹配项,则该方法返回null。

在第二个例子中,数组的第一个元素是匹配项,而其他元素是捕获组。使用g时,每个元素都将是一个不同的匹配项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接