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 日

这是相同的代码,但从 RegExp 的末尾删除了“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/>");

输出变为:August 12,1988,August,,

根据我在网上找到的定义,'g' 应该匹配所有出现的模式。但是我仍然对“g”对代码的影响感到困惑。

我将不胜感激任何澄清。

提前致谢。

4

3 回答 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”的东西。在您的情况下,您将该方法应用于数组,这就是您得到奇怪结果的原因。

最后,学习使用开发者工具,包括调试器和console.log。在表现力和生产力方面,它比滥用 document.write 和 alert 要好得多。

console.write(match3)
于 2013-02-23T00:42:06.350 回答
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]);
});
于 2013-02-23T00:41:53.737 回答
0

引用文档String.match:_

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

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

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

于 2013-02-23T00:42:59.800 回答