懒惰的正则表达式匹配实际上是贪婪的?

时间:2014-12-09 16:04:00

标签: javascript regex

http://regexr.com/3a1sp处提供的代码)

我有这个文字

a.bcd.efg.hij = function () {

我想得到这个

a.bcd.efg.hij = function hij() {

我尝试这种替换

"a.bcd.efg.hij = function () {"
   .replace( /\.(.+?) = function \(/, 
             ".$1 = function $1(" );

但结果是

a.bcd.efg.hij = function bcd.efg.hij() {

不应该吗?在\.(.+?)中使比赛变得非贪婪,即它应该与可能的短缺相匹配"。" +某种组合,即.hij?为什么匹配.bcd.efg.hij,贪婪的匹配不是吗?

2 个答案:

答案 0 :(得分:1)

我会推荐这种模式:

"a.bcd.efg.hij = function () {"
   .replace(/([^\.]+) = function \(/, 
             "$1 = function $1(" );

输出:"a.bcd.efg.hij = function hij() {"

它有效地查找除.之外的所有内容,这是您在这种情况下所寻找的内容。

问题是正则表达式引擎找到第一个.并且匹配。之后它停止寻找。 要使其正常工作,您需要在.

之前添加模式
"a.bcd.efg.hij = function () {"
   .replace( /(.*)\.(.+?) = function \(/, 
             "$1.$2 = function $2(" );

答案 1 :(得分:1)

问题在于,在尝试下一个索引的匹配之前,正则表达式引擎总是尝试找到最左边的匹配(从最小索引开始的匹配)。由于您的模式允许在索引1 .bcd.efg.hij = function () {处匹配,因此无需提前搜索。

要解决此问题,您需要在最终到达hij之前使正则表达式在每个位置失败。在这种情况下,您可以对函数名称的构成加强限制:

/\.([A-Za-z0-9_$]+) = function \(/

您可能希望允许间距灵活:

/\.([A-Za-z0-9_$]+)\s*=\s*function\s*\(/