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。
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 '))
我正在尝试在 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。
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 '))