打破替换全局循环

时间:2014-01-29 15:52:02

标签: javascript regex replace global break

我有一个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");

如果可能,我该如何突破字符串全局搜索?

由于

可能的解决方案

一个解决方案(出于性能原因在我的场景中不起作用,因为我有非常大的字符串,其中包含数千个可能匹配的非常复杂的RegExp运行数百或数千次):

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");

3 个答案:

答案 0 :(得分: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以防止无限循环。

答案 1 :(得分: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

问候。

答案 2 :(得分:0)

您可以使用try-catch并使用undeclared变量退出替换函数

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