2015-04-23 51 views
2

任何人都可以看到爲什麼下面的代碼不對所有{{...}}佔位符執行正則表達式操作?下面的輸入字符串只是原始版本的簡化版本。正則表達式替換未在所有匹配中執行

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

var input = "{{ %[email protected] }}/{{ %[email protected] }} ({{ %[email protected] }}) {{ %[email protected] }} {{ %[email protected] }} {{ %1$d }} {{ %[email protected] }} 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

應的結果是什麼樣的? – garryp

回答

2

由於使用exec匹配多個出現,在每次迭代它從last matched index開始搜索:

如果您的常規表達n使用「g」標誌,您可以多次使用exec()方法在同一個字符串中查找連續的匹配項。當你這樣做的時候,搜索從正則表達式的lastIndex屬性指定的str的子字符串開始(test()也會推進lastIndex屬性)。

在你的情況下,它更簡單和更清潔的使用String.prototype.replace方法:

var input = "{{ %[email protected] }}/{{ %[email protected] }} ({{ %[email protected] }}) {{ %[email protected] }} {{ %[email protected] }} {{ %1$d }} {{ %[email protected] }} of {{ %2$d }} of {{ %3$d }}"; 
 

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

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

 
alert(input);

+0

我必須將每個不同的佔位符格式化字符串與js兼容版本進行轉換,所以我需要匹配不同的參數。 – chris

+0

乍一看,我錯過了'replace'(正則表達式,'%@ $ 2')'中的$ 2'用於第二場比賽。這很好地工作。 – chris

3

這是因爲你改變input變量而exec尚未完成。 索引正在向前移動,但字符串變短。

添加另一個變量,或在單獨的功能包,或者使用通過replace作爲@dfsq提示:

var input = "{{ %[email protected] }}/{{ %[email protected] }} ({{ %[email protected] }}) {{ %[email protected] }} {{ %[email protected] }} {{ %1$d }} {{ %[email protected] }} 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);

+0

啊,這是有道理的事情發生的原因。 – chris

0

首先,我建議刪除不必要的組在正則表達式,

/\{\{ %(\d)\$. \}\}/g代替/(\{\{ %(\d)\$(.) \}\})/g。 然後,代替你可以使用更短的方法(也包括我oppinion更清晰):

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

輸出的最終值是%@1/%@1 (%@2) %@1 %@1 %@1 %@1 of %@2 of %@3

+0

額外的組是必需的,只是在我發佈的字符串的縮短版本中不明顯。 – chris