有谁可以看到为什么以下代码不对所有{{...}}占位符执行正则表达式操作?下面的输入字符串只是原始文件的精简版。
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);
答案 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