我试图用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”

然而,这并不会产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。是否有可能在JavaScript中同时用多个其他字符串替换多个字符串,以便产生正确的结果?

var str = "I have a cat, a dog, and a goat.";
str = str.replace(/cat/gi, "dog");
str = str.replace(/dog/gi, "goat");
str = str.replace(/goat/gi, "cat");

//this produces "I have a cat, a cat, and a cat"
//but I wanted to produce the string "I have a dog, a goat, and a cat".

当前回答

所有的解决方案都很好,除了应用于闭包的编程语言(如Coda, Excel,电子表格的REGEXREPLACE)。

我下面的两个原始解决方案只使用1个连接和1个正则表达式。

方法#1:查找替换值

其思想是,如果替换值不在字符串中,则附加替换值。然后,使用一个regex,我们执行所有需要的替换:

var str = "我有一只猫,一只狗,和一只山羊。"; STR = (STR +"||||猫,狗,山羊").replace( /猫(? = [\ s \ s] *(狗))|狗(? = [\ s \ s] *(山羊))|山羊(? = [\ s \ s] *(猫 ))|\|\|\|\|.* $ / gi, " $ 1 $ 2 $ 3”); document.body.innerHTML = str;

解释:

cat(?=[\s\S]*(dog)) means that we look for "cat". If it matches, then a forward lookup will capture "dog" as group 1, and "" otherwise. Same for "dog" that would capture "goat" as group 2, and "goat" that would capture "cat" as group 3. We replace with "$1$2$3" (the concatenation of all three groups), which will always be either "dog", "cat" or "goat" for one of the above cases If we manually appended replacements to the string like str+"||||cat,dog,goat", we remove them by also matching \|\|\|\|.*$, in which case the replacement "$1$2$3" will evaluate to "", the empty string.

方法#2:查找替换对

方法#1的一个问题是它一次不能超过9个替换,这是反向传播组的最大数量。 方法#2声明不只是附加替换值,而是直接替换:

var str = "我有一只猫,一只狗,和一只山羊。"; str = (str + " | | | |,猫= >狗,狗= >山羊,山羊= >猫”).replace ( / (\ b \ w + \ b) (? = [\ s \ s] * \ 1 =>([^,]*))|\|\|\|\|.* $ / gi, " $ 2 "); document.body.innerHTML = str;

解释:

(str+"||||,cat=>dog,dog=>goat,goat=>cat") is how we append a replacement map to the end of the string. (\b\w+\b) states to "capture any word", that could be replaced by "(cat|dog|goat) or anything else. (?=[\s\S]*...) is a forward lookup that will typically go to the end of the document until after the replacement map. ,\1=> means "you should find the matched word between a comma and a right arrow" ([^,]*) means "match anything after this arrow until the next comma or the end of the doc" |\|\|\|\|.*$ is how we remove the replacement map.

其他回答

在这个实例中,这可能不能满足您的确切需求,但我发现这是一种有用的方法,可以替换字符串中的多个参数,作为通用解决方案。它将替换参数的所有实例,无论它们被引用了多少次:

String.prototype.fmt = function (hash) {
        var string = this, key; for (key in hash) string = string.replace(new RegExp('\\{' + key + '\\}', 'gm'), hash[key]); return string
}

你可以这样调用它:

var person = '{title} {first} {last}'.fmt({ title: 'Agent', first: 'Jack', last: 'Bauer' });
// person = 'Agent Jack Bauer'

我扩展了一下@本麦考密克斯。他的工作规则字符串,但不如果我转义字符或通配符。我是这么做的

str = "[curl] 6: blah blah 234433 blah blah";
mapObj = {'\\[curl] *': '', '\\d: *': ''};


function replaceAll (str, mapObj) {

    var arr = Object.keys(mapObj),
        re;

    $.each(arr, function (key, value) {
        re = new RegExp(value, "g");
        str = str.replace(re, function (matched) {
            return mapObj[value];
        });
    });

    return str;

}
replaceAll(str, mapObj)

返回"blah blah 234433 blah blah"

这样它将匹配mapObj中的键,而不是匹配的单词'

用Jquery解决方案(首先包括这个文件):用多个其他字符串替换多个字符串:

var replacetext = {
    "abc": "123",
    "def": "456"
    "ghi": "789"
};

$.each(replacetext, function(txtorig, txtnew) {
    $(".eng-to-urd").each(function() {
        $(this).text($(this).text().replace(txtorig, txtnew));
    });
});

为此,您可以使用https://www.npmjs.com/package/union-replacer。它基本上是一个字符串。Replace (regexp,…)对等体,它允许在一次传递中发生多次替换,同时保留string.replace(…)的全部功能。

披露:我是作者。开发这个库是为了支持更复杂的用户可配置替换,它解决了所有有问题的事情,比如捕获组、反向引用和回调函数替换。

上面的解决方案对于精确的字符串替换来说已经足够好了。

<!DOCTYPE html>
<html>
<body>



<p id="demo">Mr Blue 
has a           blue house and a blue car.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction() {
    var str = document.getElementById("demo").innerHTML;
    var res = str.replace(/\n| |car/gi, function myFunction(x){

if(x=='\n'){return x='<br>';}
if(x==' '){return x='&nbsp';}
if(x=='car'){return x='BMW'}
else{return x;}//must need



});

    document.getElementById("demo").innerHTML = res;
}
</script>

</body>
</html>