15

所以我有以下内容:

var token = '[token]';
var tokenValue = 'elephant';
var string = 'i have a beautiful [token] and i sold my [token]';
string = string.replace(token, tokenValue);

以上将仅替换第一个[token],而将第二个单独保留。

如果我要使用正则表达式,我可以像这样使用它

string = string.replace(/[token]/g, tokenValue);

这将取代我所有的[tokens]

但是我不知道如何在不使用的情况下做到这一点//

4

7 回答 7

21

对于我的大多数情况,我发现拆分/加入足够令人满意。一个真实的例子:

myText.split("\n").join('<br>');
于 2016-11-29T20:06:50.780 回答
9

为什么不用 do while 循环每次出现时都替换令牌?

var index = 0;
do {
    string = string.replace(token, tokenValue);
} while((index = string.indexOf(token, index + 1)) > -1);
于 2013-05-29T01:24:37.203 回答
2
string = string.replace(new RegExp("\\[token\\]","g"), tokenValue);
于 2013-05-29T01:17:59.867 回答
1

Caution with the accepted answer, the replaceWith string can contain the inToReplace string, in which case there will be an infinite loop...

Here a better version:

function replaceSubstring(inSource, inToReplace, inReplaceWith)
{
    var outString = [];
    var repLen = inToReplace.length;

    while (true)
    {
        var idx = inSource.indexOf(inToReplace);
        if (idx == -1)
        {
            outString.push(inSource);
            break;
        }

        outString.push(inSource.substring(0, idx))
        outString.push(inReplaceWith);

        inSource = inSource.substring(idx + repLen);
    }

    return outString.join("");
}
于 2015-04-22T10:41:18.107 回答
0
"[.token.*] nonsense and [.token.*] more nonsense".replace("[.token.*]", "some", "g");

将产生:

“一些废话和一些废话”

于 2014-11-13T17:00:53.070 回答
0

我意识到@TheBestGuest 的答案不适用于以下示例,因为您最终将陷入无限循环:

var stringSample= 'CIC'; 
var index = 0; 
do { stringSample = stringSample.replace('C', 'CC'); } 
while((index = stringSample.indexOf('C', index + 1)) > -1);

所以这是我对用 TypeScript 编写的 replaceAll 方法的建议:

let matchString = 'CIC';
let searchValueString= 'C';
let replacementString ='CC';
    
matchString = matchString.split(searchValueString).join(replacementString);
     console.log(matchString);

于 2017-09-22T09:15:54.600 回答
0

不幸的是,由于 Javascript 的字符串replace()函数不允许您从特定索引开始,并且无法对字符串进行就地修改,因此很难像在更理智的语言中那样有效地做到这一点。

  • .split().join()这不是一个好的解决方案,因为它涉及创建大量字符串(尽管我怀疑 V8 做了一些黑魔法来优化它)。
  • 循环调用replace()是一个糟糕的解决方案,因为 replace 每次都从字符串的开头开始搜索。这将导致 O(N^2) 行为!如此处的答案所述,它还存在无限循环问题。
  • 如果您的替换字符串是编译时间常数,那么正则表达式可能是最好的解决方案,但如果不是,那么您就不能真正使用它。您绝对应该尝试通过转义将任意字符串转换为正则表达式。

一种合理的方法是使用适当的替换来构建一个新字符串:

function replaceAll(input: string, from: string, to: string): string {
  const fromLen = from.length;
  let output = "";
  let pos = 0;
  for (;;) {
    let matchPos = input.indexOf(from, pos);
    if (matchPos === -1) {
      output += input.slice(pos);
      break;
    }
    output += input.slice(pos, matchPos);
    output += to;
    pos = matchPos + fromLen;
  }
  return output;
}

我将它与所有其他解决方案进行了基准测试(除了在循环中调用会很糟糕),它比正则表达式稍微快一点,大约是/replace()的两倍。splitjoin

编辑:这与 Stefan Steiger 的回答几乎相同,由于某种原因我完全错过了。.join()然而,由于某种原因,他的答案仍然使用,这使得它比我的慢 4 倍。

于 2020-02-20T09:18:43.687 回答