【问题标题】:Javascript RegEx Lazy matchJavascript RegEx 惰性匹配
【发布时间】:2026-02-11 11:40:01
【问题描述】:

我正在尝试在 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
 }
}

我尝试探索惰性正则表达式语法,但无法使其工作。我怎样才能做到这一点?

【问题讨论】:

  • 正则表达式不适合处理嵌套结构。我可以让它适用于当前场景,但是当你有更多的嵌套模式时,它通常仍然会失败。
  • 你不能像str.split(':').join(' in ')那样做吗?或者您只想将其作为 for 循环的一部分?
  • Icepickle,不,因为 ':' 以多种方式使用,即对象 ==> var objectA = {'A','Apple','B':'Banana'};跨度>
  • @PushpeshKumarRajwanshi 我该如何处理这个问题?使用递归匹配?或者任何其他可能的方式?
  • @Pratik: 添加为answer 请检查。

标签: javascript regex regex-greedy


【解决方案1】:

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

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

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

有点短,它在第一组中包含for

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

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

【讨论】:

  • .+?\s+?是多余的,可以写成.+?\s+?.+?一样
【解决方案2】:

您可以使用否定字符集,而不是使用惰性量词,因为它们的性能更好,并且您可以使用此正则表达式,

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

并将其替换为,

$1 in $2

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

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

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, '$1 in $2'))

【讨论】:

    【解决方案3】:

    可以在量词后使用? 来实现惰性行为。

    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" )
    

    【讨论】:

    • “实现使用”什么?