未在所有比赛中执行正则表达式替换

时间:2015-04-23 20:03:11

标签: javascript regex

有谁可以看到为什么以下代码不对所有{{...}}占位符执行正则表达式操作?下面的输入字符串只是原始文件的精简版。

https://jsfiddle.net/2L12jr3u/2/

var input = "{{ %1$@ }} / {{ %1$@ }} ({{ %2$@ }}) {{ %1$@ }} {{ %1$@ }} {{ %1$d }} {{ %1$@ }} of {{ %2$d }} of {{ %3$d }}";

var regex = /(\{\{ \%(\d)\$(.) \}\})/g;

var match;
while (match = regex.exec(input)) {
    console.log(match);
    input = input.replace(match[0], '%@' + match[2]);
}

console.log(input);

3 个答案:

答案 0 :(得分:3)

这是因为您在input尚未完成时更改exec变量。 索引正在向前发展,但字符串变短了。

添加另一个变量,或者包装在单独的函数中,或者按照@dfsq的建议使用replace



var input = "{{ %1$@ }} / {{ %1$@ }} ({{ %2$@ }}) {{ %1$@ }} {{ %1$@ }} {{ %1$d }} {{ %1$@ }} of {{ %2$d }} of {{ %3$d }}";

var regex = /(\{\{ \%(\d)\$(.) \}\})/g;
var output = input;
var match;

while (match = regex.exec(input)) {
    console.log(match);
    output = output.replace(match[1], '%@' + match[2]);
}

alert(output);




答案 1 :(得分:2)

由于您使用exec来匹配多个匹配项,因此在每次迭代中它都会从last matched index开始搜索:

  

如果正则表达式使用“g”标志,则可以多次使用exec()方法在同一字符串中查找连续匹配。执行此操作时,搜索从正则表达式的lastIndex属性指定的str的子字符串开始(test()也将使lastIndex属性前进)。

在您的情况下,使用String.prototype.replace方法更简单,更清晰:

var input = "{{ %1$@ }} / {{ %1$@ }} ({{ %2$@ }}) {{ %1$@ }} {{ %1$@ }} {{ %1$d }} {{ %1$@ }} of {{ %2$d }} of {{ %3$d }}";

var regex = /(\{\{ %(\d)\$(.) \}\})/g;

input = input.replace(regex, '%@$2');

alert(input);

答案 2 :(得分:0)

首先,我建议删除正则表达式中不必要的组,

/\{\{ %(\d)\$. \}\}/g代替/(\{\{ %(\d)\$(.) \}\})/g。 然后,替换你可以使用更短的方法(在我的观点中也更清楚):

var input = "{{ %1$@ }} / {{ %1$@ }} ({{ %2$@ }}) {{ %1$@ }} {{ %1$@ }} {{ %1$d }} {{ %1$@ }} of {{ %2$d }} of {{ %3$d }}";
var output = input.replace(/\{\{ %(\d)\$. \}\}/g, "%@$1");

输出的最终值为%@1 / %@1 (%@2) %@1 %@1 %@1 %@1 of %@2 of %@3