Javascript 在没有正则表达式的情况下替换all在哪里可以使用G

Javascript 在没有正则表达式的情况下替换all在哪里可以使用G,javascript,regex,replace,Javascript,Regex,Replace,因此,我有以下几点: 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

因此,我有以下几点:

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]


但是,如果不使用
/

的话,我不知道如何做到这一点。为什么不在每次令牌出现时用do while循环替换它呢

string = string.replace(new RegExp("\\[token\\]","g"), tokenValue);
var index = 0;
do {
    string = string.replace(token, tokenValue);
} while((index = string.indexOf(token, index + 1)) > -1);
将产生:


“一些胡说八道,还有一些胡说八道”

注意:根据公认的答案,replaceWith字符串可以包含inToReplace字符串,在这种情况下,将有一个无限循环

这里有一个更好的版本:

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

我发现拆分/合并对于我的大多数情况来说都足够令人满意。 一个真实的例子:

myText.split("\n").join('<br>');
myText.split(“\n”).join(“
”);
我意识到@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';
让searchValueString='C';
让replacementString='CC';
matchString=matchString.split(searchValueString).join(replacementString);

log(匹配字符串)不幸的是,由于Javascript的string
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()
,这将非常糟糕),它的速度略快于正则表达式,大约是
split
/
join
的两倍



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

为什么
/
会产生不同?//在正则表达式中用于定义限制器。如果有一种方法可以添加g或“all”来替换,而不使用它,那么该方法是什么?用
/
包围任何事物的正确术语是,它使正则表达式成为文本。我所知道的在没有regex文本(或第三方库)的情况下进行replace all的唯一方法是使用
RegExp
对象构造函数(仍然使用regex,请参见Isaac的答案),或者创建一个精心构造的循环,搜索字符串中出现的
标记
,并将其替换为
标记值
,直到找不到出现的
标记
。如果你仍然能够使用正则表达式,我建议你使用Isaac的答案(不确定为什么你不会…)。我不能使用他的答案的原因是:issac你的答案很好,但没有解决我的问题,而且“[]”没有被替换-我也无法逃避“[]”。不,不能,即使我逃避了,仍然有一个问题。经过一些修改,看着我找到了如何转义
[]
您丢失了,我无法转义或更改变量标记的值,谢谢您的帮助though@NetaMeta现在可以理解了,您需要转义
[]
,但不能更改
标记的原始值。您可以使用答案或将
标记
字符串中的字符替换为等效的正则表达式元字符。然后您可以使用
令牌
作为正则表达式。请注意,如果用户输入regex,这将是一个糟糕的解决方案,因为他们可能会输入类似
[
。你的似乎就是我要找的,但是indexOF不存在浏览器不兼容的问题吗?如果你使用的话,在旧的IE版本中会有问题。但是,它是受支持的,所以在字符串上使用它应该不会有问题。这不起作用:
var strinSample='CIC';var index=0;do{strinSample=strinSample.replace('C','CC');}while((index=strinSample.indexOf('C',index+1))>-1);
是的,问题是它每次都从字符串的开头搜索。请注意,这只适用于已从Firefox中删除的flags参数,因此这在任何地方都不起作用。如果您不喜欢将
while(true)放在
在您的代码中,这里有一个带有显式条件的版本:附加到字符串比创建一个部分数组和
join(“”)要快得多
他们。看我的答案。@Timmm:据我所知,情况并非如此。我没有测量这个特定的片段,但通常join比concat快。你实际测量过吗?哪个浏览器?哪个版本?是的。Chrome到现在为止。它慢了4倍。@Timmm:hmm,过去快了100倍。但显然,最近的changes.result=String.prototype.concat.apply(“,arrayOfStrings”)的性能如何
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;
}