Javascript 正则表达式惰性匹配

Javascript RegEx Lazy match

我正在尝试在 javascript 代码中查找 for 循环模式,并使用下面的正则表达式替换语法(从 : 到 in),

var str="for(var x in []) for(var y in [])";

str.replace( new RegExp( '(for\s*\(.+\s+):(\s+.+\))', 'ig' ), "$1in$2" )

for(var x : list)
{
 // something
}

for(var x in list)
{
 // something
}

但是,当同一行中有多个 for 循环时,我会遇到问题。

for(var x : list) { for(var y : list) {
     // something
 }
}

这是有效的语法,但是由于贪婪正则表达式方法,它转换如下:

for(var x : list) { for(var y in list) {
         // something
 }
}

我尝试探索懒惰的正则表达式语法,但没能成功。我怎样才能做到这一点?

惰性行为可以通过在量词后添加 ? 来实现。

const str = "for(var x : list) { for(var y : list) {"
str.replace( new RegExp( '(for\s*?\(.+?\s+?):(\s+.+\))', 'ig' ), "$1in$2" )

顺便说一句。 JavaScript RegEx 文字更易于阅读:

str.replace( /(for\s*?\(.+?\s+?):(\s+.+\))/ig, "$1in$2" )

您可以为所有 *+ 添加一些惰性量词。并将for作为替换的一部分,因为匹配。

var str = "for(var x : []) for(var y : [])";

console.log(str.replace(/for\s*?(\(.+?\s+?):(\s+?.+?\))/ig, "for in"));

有点短,第一组中包括 for

var str = "for(var x : []) for(var y : [])";

console.log(str.replace(/(for\s*?\(.+?):(.+?\))/ig, "in"));

您可以使用否定字符集来代替惰性量词,因为它们的性能更好,您可以使用此正则表达式,

(for\s*\([^:]+):([^)]+\))

并将其替换为

 in 

此外,您不必使用 .+\s+ 因为这是多余的,您可以只写 .+? 甚至更好地使用否定字符集以使其更快地工作并且之后类似: 你可以把 \s+.+ 写成 .+? 但否定字符 class 是更好的选择,就像我在回答中提到的那样。

另一点可能导致您遇到问题的是,您不应该使用此 $1in$2 进行替换,而是首先使用 in 您不需要转义 $ 作为$ 其次因为如果你的 for 循环是这样的,for(var x:list) 即冒号和周围变量之间没有 space,那么你可能得到的替换输出是 for(var xinlist)这将使它无效。这就是为什么我在上面的回答中建议用 in 替换,所以 in 两边都有 space。

Regex Demo

JS代码,

const s = `for(var x : list)
{
 // something
}

for(var x : list) { for(var y : list) {
     // something
 }
}`

console.log(s.replace(/(for\s*\([^:]+):([^)]+\))/g, ' in '))