2014-01-29 69 views
1

我有一個RegExp,做一個字符串替換,全局設置。我只需要一個替換,但我使用全局,因爲有第二組模式匹配(一個數學方程,確定可接受的替換開始索引),我不能很容易地表示爲正則表達式的一部分。突破替換全局循環

var myString = //function-created string 
myString = myString.replace(myRegex, function(){ 
    if (/* this index is okay */){ 

     //!! want to STOP searching now !!// 
     return //my return string 

    } else { 
     return arguments[0]; 
     //return the string we matched (no change) 
     //continue on to the next match 
    } 
}, "g"); 

如果有可能,我該如何擺脫字符串全局搜索?

感謝

可能的解決方案

溶液(不,我由於性能原因情況下工作,因爲我有非常大的字符串數千可能的匹配非常複雜的正則表達式運行數百千次):

var matched = false; 
var myString = //function-created string 
myString = myString.replace(myRegex, function(){ 
    if (!matched && /* this index is okay */){ 
     matched = true; 
     //!! want to STOP searching now !!// 
     return //my return string 

    } else { 
     return arguments[0]; 
     //return the string we matched (no change) 
     //continue on to the next match 
    } 
}, "g"); 
+1

我'莫名其妙失蹤的正則表達式和簡單的輸入和預期的輸出樣本 – rene

+0

可你只是'第一match'他們,只是循環通過這些? – Wrikken

+0

@Wrikken從技術上講,這可能有效,但這是一個性能問題。我添加了一個可能的解決方案,只是匹配所有內容(類似於您所說的內容),但是在我的方案中,性能受到的影響非常嚴酷。 –

回答

2

改爲使用RegExp.exec()。由於您只需更換一次,我就利用這一事實來簡化更換邏輯。

var myString = "some string"; 
// NOTE: The g flag is important! 
var myRegex = /some_regex/g; 

// Default value when no match is found 
var result = myString; 
var arr = null; 

while ((arr = myRegex.exec(myString)) != null) { 
    // arr.index gives the starting index of the match 
    if (/* index is OK */) { 
     // Assign new value to result 
     result = myString.substring(0, arr.index) + 
       /* replacement */ + 
       myString.substring(myRegex.lastIndex); 
     break; 
    } 

    // Increment lastIndex of myRegex if the regex matches an empty string 
    // This is important to prevent infinite loop 
    if (arr[0].length == 0) { 
     myRegex.lastIndex++; 
    } 
} 

此代碼表現出相同的行爲String.match(),因爲它也increments the index by 1 if the last match is empty防止無限循環。

0

我質疑你的關於表現的邏輯。我認爲評論中提出的一些觀點是有效的。但是,我知道什麼...;)

但是,這是做你想做的一種方式。同樣,我想這一點,在性能方面,是不是最好的...:

var myString = "This is the original string. Let's see if the original will change..."; 
var myRegex = new RegExp('original', 'g'); 
var matched=false; 

document.write(myString+'<br>'); 

myString = myString.replace(myRegex, function (match) { 

    if (!matched) { 

     matched = true; 
     return 'replaced'; 

    } else { 
     return match; 
    } 
}); 

document.write(myString); 

這很像你的「可能的解決方案」。在替換之後它不會「中止」(因此我的表演保留)。但它確實符合你的要求。它取代了第一個實例,設置了一個標誌,之後只返回匹配的字符串。

看到它的工作here

問候。

0

你可以把的try-catch和使用未聲明的變量退出替換功能

var i = 0; 

try{ 
"aaaaa".replace (/./g, function(a, b){ 

    //Exit the loop on the 3-rd iteration 
    if (i === 3){ 

    stop; //undeclared variable 

    } 

    //Increment i 
    i++ 

}) 

} 
catch(err){ 
} 

alert ("i = " + i); //Shows 3