为什么Javascript正则表达式每秒都匹配一次?
我定义一个regex对象,然后在循环中匹配它。准确地说,它只在某些时候匹配——每秒钟一次。所以我创建了这个问题的最小工作样本 我在Opera和Firefox中尝试了这段代码。两者的行为相同:为什么Javascript正则表达式每秒都匹配一次?,javascript,regex,Javascript,Regex,我定义一个regex对象,然后在循环中匹配它。准确地说,它只在某些时候匹配——每秒钟一次。所以我创建了这个问题的最小工作样本 我在Opera和Firefox中尝试了这段代码。两者的行为相同: >>> domainRegex = /(?:\.|^)([a-z0-9\-]+\.[a-z0-9\-]+)$/g; /(?:\.|^)([a-z0-9\-]+\.[a-z0-9\-]+)$/g >>> domainRegex.exec('mail-we0-f174.go
>>> domainRegex = /(?:\.|^)([a-z0-9\-]+\.[a-z0-9\-]+)$/g;
/(?:\.|^)([a-z0-9\-]+\.[a-z0-9\-]+)$/g
>>> domainRegex.exec('mail-we0-f174.google.com');
Array [".google.com", "google.com"]
>>> domainRegex.exec('mail-we0-f174.google.com');
null
>>> domainRegex.exec('mail-we0-f174.google.com');
Array [".google.com", "google.com"]
>>> domainRegex.exec('mail-we0-f174.google.com');
null
>>> domainRegex.exec('mail-we0-f174.google.com');
Array [".google.com", "google.com"]
>>> domainRegex.exec('mail-we0-f174.google.com');
null
为什么会这样?这种行为有记录吗?除了在循环体内部定义正则表达式之外,还有其他方法吗?按照您描述的方式工作;当存在/g
修饰符时,它将返回一个匹配项,从每次调用开始,直到不再有匹配项为止,此时它返回null
,并且lastIndex
的值重置为0
但是,由于您已使用$
锚定表达式,因此不会有多个匹配项,因此您可以改为使用并丢失/g
修饰符:
var domainRegex = /(?:\.|^)([a-z0-9\-]+\.[a-z0-9\-]+)$/;
'mail-we0-f174.google.com'.match(domainRegex); // [".google.com", "google.com"]
每次运行正则表达式的exec方法时,都会得到下一个匹配项 一旦到达字符串末尾,它将返回
null
,让您知道您已获得所有匹配项。下一次,它又从头开始
由于只有一个匹配项(返回完整匹配项和括号中的匹配项的数组),第一次,正则表达式从一开始就开始搜索。它找到匹配项并返回。下一次,它到达末尾并返回null。因此,如果在循环中有此项,则可以执行类似的操作来循环所有匹配项:
while(regExpression.exec(string)){
// do something
}
然后下一次,它再次从位置0开始
“有办法吗?”
如果您知道只有一个匹配项,或者您只需要第一个匹配项,那么可以将te结果保存到变量中。无需恢复
.exec
。如果您对所有的匹配都感兴趣,那么您需要继续进行,直到得到null
为什么不使用简单的匹配方法来进行类似字符串的匹配呢
'mail-we0-f174.google.com'.match(/(?:\.|^)([a-z0-9\-]+\.[a-z0-9\-]+)$/)
使用
RegExp
执行全局搜索时,exec方法从开始匹配
这个lastIndex
属性在每次exec
调用和
设置为上次找到匹配项后的位置。如果匹配失败,lastIndex将重置为0,这将导致exec
从一开始就再次匹配
var a = 'asdfeeeasdfeedxasdf'
undefined
var p = /asdf/g
p.lastIndex
4
p.exec(a)
["asdf"]
p.lastIndex
11
p.exec(a)
["asdf"]
p.lastIndex
19
p.exec(a)
null //match failed
p.lastIndex
0 //lastIndex reset. next match will start at the beginning of the string a
p.exec(a)
["asdf"]
回复的其他信息:
您还可以设置
或者只是为每次执行创建一个新的正则表达式,我发现它更干净
new RegExp(myRgx).exec(someString);
这可能与@GDR重复,因为(请阅读“描述”部分)。@Jack我认为相关问题的答案是相同的?@Ozzy解释了为什么会这样,但不同的答案是,方法是错误的:)因为在循环的每次迭代中创建一个新的Regex对象实例的性能很差。除非您需要分配它,否则您永远无法使用该值<代码>while((match=myRe.exec(str))!==null){
new RegExp(myRgx).exec(someString);