我在JavaScript中使用正则表达式否定前瞻来使用正则表达式匹配替换字符串中最后一次出现的字符串。
下面是我的代码片段:
var str = 'abc abc abc'
var regex1 = /abc(?!.*?abc)/
var regex2 = /abc(?!.*abc)/
var ematch1 = regex1.exec(str);
var ematch2 = regex2.exec(str);
console.log(ematch1, ematch1.index);
console.log(ematch2, ematch2.index);
这些正则表达式 - regex1和regex2 - 都得到了相同的结果。哪个是首选,为什么?或者是一种完全不同的方法?
答案 0 :(得分:2)
regex中有两位受过教育且活跃的人发表了两条有效评论,但我会提供一些补充。贪婪的令牌.*
大部分时间都会导致回溯步骤,它会吞下每一件事(或者事实上直到第一个换行符)然后向后退一步。 .*
的真正定义不应该是零或更多,而是全部,某些内容或任何内容。
因此,如果abc
发生在输入字符串.*
的末尾附近,则会比非贪婪的量词.*?
更早地满足引擎,否则引擎会回溯直到它有机会匹配{{1}或者在最坏的情况下没有。
话虽如此,回溯步骤的数量等于输入字符串的长度。相反,如果已知abc
在输入字符串的开头附近发生,特别是在大数据上,abc
会导致早于.*?
的匹配。
此外,由于其前瞻性行为,它不会在同一路径上进行回溯。
你有时可能会发现语言方法 - 除了坚持使用正则表达式 - 更快,更有帮助,如JS中的lastIndexOf()
。