为什么'g'标志更改JavaScript正则表达式的结果

Why does the 'g' flag change the result of a JavaScript regular expression?

本文关键字:正则表达式 结果 JavaScript 标志 为什么      更新时间:2023-09-26

考虑:

var reg = new RegExp("^19[-''d]*","g");
reg.test('1973-02-01') // true
reg.test('1973-01-01') // false

为什么第三行返回false?如果我移除"g"标志,那么它将返回true

在JavaScript中,正则表达式对象具有状态。当g标志("全局"(应用于它们时,这一点很重要,有时会以奇怪的方式应用。此状态是最后一次发生匹配的索引,这是正则表达式的.lastIndex属性。当您再次对同一regex对象调用exectest时,它会从停止的地方恢复。

在您的示例中发生的情况是,对于第二个调用,它从上次停止的位置开始,因此它看起来从字符串中的第10个字符开始—并且在那里找不到匹配,因为那里根本没有文本(即使有,^断言也不会匹配(。

如果我们查看lastIndex属性,我们可以看到发生了什么:

var reg = new RegExp("^19[-''d]*","g");
snippet.log("Before first test: " + reg.lastIndex);
snippet.log(reg.test('1973-02-01')); //return true
snippet.log("Before second test: " + reg.lastIndex);
snippet.log(reg.test('1973-01-01')); //return false
snippet.log("After second test: " + reg.lastIndex);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

如果没有g标志,regex对象不会保持任何状态,每次都从字符串的开头开始:

var reg = new RegExp("^19[-''d]*");
snippet.log("Before first test: " + reg.lastIndex);
snippet.log(reg.test('1973-02-01')); //return true
snippet.log("Before second test: " + reg.lastIndex);
snippet.log(reg.test('1973-01-01')); //return false
snippet.log("After second test: " + reg.lastIndex);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


附带说明:通常,最好使用regex文本在JvaScript中编写正则表达式,而不是使用RegExp构造函数和字符串。在你的情况下,那将是

var reg = /^19[-'d]*/g;
// or without the g flag:
var reg = /^19[-'d]*/;

旁注2:用^$g标志定义正则表达式没有多大意义,除非您还使用m(多行(标志来更改这些锚的含义。如果没有m,它们的意思是"输入的开始(^(或结束($(。">如果有m标志,它们的含义是">的开始(^(或终止($(。">