2015-09-06 113 views

回答

14

在JavaScript中,正则表达式对象具有状态。当g标志(“全局”)应用于它们时有重要意义,有时以奇怪的方式应用。此状态是匹配上次发生的索引,这是正则表达式的.lastIndex属性。当您再次在同一个正则表达式对象上调用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标志,正则表达式对象不保留任何状态,从年初开始该字符串每次:

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>


边注:一般情况下,这是最好写使用正则表达式字面量JvaScript正则表达式,而不是使用RegExp构造和字符串。在你的情况,这将是

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

边注2:这是没有多大意义,除非你还定义了^$g国旗的正则表达式使用m(多行)标志来更改这些锚的含义。没有m,它们的意思是“输入的开始(^)或结束($)”。 m标志,它们表示的开始(^)或结束($)。

+4

一个很好且全面的答案(通常:-)。我会添加一个注释(3),说明如果2个日期字符串是相同的(例如,两个调用中的'1973-02-01'') – Amit

+0

感谢您的解释,将会生成完全相同的输出,它有助于很多。关于你的附注,我认为它是'var reg = [^ 19 [ - \ d] */g;' –

+0

@ChopperLee:是的,我忘了删除反斜杠。 :-)我记得我什么时候开始输入附注,但是...(现在修复) –

相关问题