I am trying to find for loop pattern in javascript code, and replace syntax (from : to in), using below regex way,
var str="for(var x in []) for(var y in [])";
str.replace( new RegExp( '(for\\s*\\(.+\\s+):(\\s+.+\\))', 'ig' ), "\$1in\$2" )
ie
for(var x : list)
{
// something
}
with
for(var x in list)
{
// something
}
However I am facing issues when there are multiple for loops in same line.
for(var x : list) { for(var y : list) {
// something
}
}
which is valid syntax, however due to Greedy regex approach it converts as below:
for(var x : list) { for(var y in list) {
// something
}
}
I tried to explore lazy regex syntax but couldn't make it work. How can I achieve this ?
You could add some lazy quantifiers to all *
and +
. and take for
as part of the replacement, because of matching.
var str = "for(var x : []) for(var y : [])"; console.log(str.replace(/for\\s*?(\\(.+?\\s+?):(\\s+?.+?\\))/ig, "for $1in$2"));
A bit shorter and it includes for
in the first group.
var str = "for(var x : []) for(var y : [])"; console.log(str.replace(/(for\\s*?\\(.+?):(.+?\\))/ig, "$1in$2"));
Instead of using lazy quantifiers, you can use negated character set as they perform better and you can use this regex,
(for\s*\([^:]+):([^)]+\))
and replace it with,
$1 in $2
Also, you don't have to use .+\\\\s+
as this is redundant and instead you can just write .+?
and even better to use negated character set for it to work faster and similarly after :
you can write \\\\s+.+
as .+?
but again negated character class is better choice like I mentioned in my answer.
Another point that could lead you into issues is, you should not use this \\$1in\\$2
for replacement, and instead use $1 in $2
firstly you don't need to escape $
as \\$
and secondly because in case your for loop is like this, for(var x:list)
ie without having space between colon and surrounding variables, then the output of replacement you may get is for(var xinlist)
which would make it invalid. Which is why I suggested above in my answer to replace with $1 in $2
so in
has space at both sides.
JS codes,
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'))
The lazy behaviour can be achived with a ?
after the quantifier.
const str = "for(var x : list) { for(var y : list) {"
str.replace( new RegExp( '(for\\s*?\\(.+?\\s+?):(\\s+.+\\))', 'ig' ), "\$1in\$2" )
btw. JavaScript RegEx literals are much easier to read:
str.replace( /(for\s*?\(.+?\s+?):(\s+.+\))/ig, "\$1in\$2" )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.