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

然而,这并不会产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。是否有可能在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".

当前回答

使用我的replace-once包,您可以执行以下操作:

const replaceOnce = require('replace-once')

var str = 'I have a cat, a dog, and a goat.'
var find = ['cat', 'dog', 'goat']
var replace = ['dog', 'goat', 'cat']
replaceOnce(str, find, replace, 'gi')
//=> 'I have a dog, a goat, and a cat.'

其他回答

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

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中的键,而不是匹配的单词'

使用我的replace-once包,您可以执行以下操作:

const replaceOnce = require('replace-once')

var str = 'I have a cat, a dog, and a goat.'
var find = ['cat', 'dog', 'goat']
var replace = ['dog', 'goat', 'cat']
replaceOnce(str, find, replace, 'gi')
//=> 'I have a dog, a goat, and a cat.'

你可以试试这个。买不聪明。

var str = "我有一只猫,一只狗,和一只山羊。"; console.log (str); str = str.replace(/cat/gi, "XXX"); console.log (str); STR = STR .replace(/goat/gi, "cat"); console.log (str); STR = STR .replace(/dog/gi, "goat"); console.log (str); str = str.replace(/XXX/gi, "dog"); console.log (str); 把: 我有一只狗,一只山羊和一只猫。

具体的解决方案

您可以使用一个函数来替换每一个。

var str = "I have a cat, a dog, and a goat.";
var mapObj = {
   cat:"dog",
   dog:"goat",
   goat:"cat"
};
str = str.replace(/cat|dog|goat/gi, function(matched){
  return mapObj[matched];
});

jsfiddle例子

概括它

如果您想动态地维护正则表达式,并且只是将未来的交换添加到映射中,您可以这样做

new RegExp(Object.keys(mapObj).join("|"),"gi"); 

生成正则表达式。就像这样

var mapObj = {cat:"dog",dog:"goat",goat:"cat"};

var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
str = str.replace(re, function(matched){
  return mapObj[matched];
});

要添加或更改任何替换,您只需编辑地图。

摆弄动态正则表达式

可重复使用

如果你想让它成为一般形式你可以把它变成这样一个函数

function replaceAll(str,mapObj){
    var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

    return str.replace(re, function(matched){
        return mapObj[matched.toLowerCase()];
    });
}

然后你可以把str和你想要的替换的映射传递给函数它会返回转换后的字符串。

摆弄函数

确保对象。key适用于旧的浏览器,添加一个填充,例如从MDN或Es5。

使用Array.prototype.reduce ():

更新(更好)答案(使用对象): 此函数将替换所有出现的情况,并且不区分大小写

/**
 * Replaces all occurrences of words in a sentence with new words.
 * @function
 * @param {string} sentence - The sentence to modify.
 * @param {Object} wordsToReplace - An object containing words to be replaced as the keys and their replacements as the values.
 * @returns {string} - The modified sentence.
 */
function replaceAll(sentence, wordsToReplace) {
  return Object.keys(wordsToReplace).reduce(
    (f, s, i) =>
      `${f}`.replace(new RegExp(s, 'ig'), wordsToReplace[s]),
      sentence
  )
}

const americanEnglish = 'I popped the trunk of the car in a hurry and in a hurry I popped the trunk of the car'
const wordsToReplace = {
  'popped': 'opened',
  'trunk': 'boot',
  'car': 'vehicle',
  'hurry': 'rush'
}

const britishEnglish = replaceAll(americanEnglish, wordsToReplace) 
console.log(britishEnglish)
// I opened the boot of the vehicle in a rush and in a rush I opened the boot of the vehicle

原始答案(使用对象数组):

    const arrayOfObjects = [
      { plants: 'men' },
      { smart:'dumb' },
      { peace: 'war' }
    ]
    const sentence = 'plants are smart'
    
    arrayOfObjects.reduce(
      (f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence
    )

    // as a reusable function
    const replaceManyStr = (obj, sentence) => obj.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence)

    const result = replaceManyStr(arrayOfObjects , sentence1)

Example // ///////////// 1. replacing using reduce and objects // arrayOfObjects.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence) // replaces the key in object with its value if found in the sentence // doesn't break if words aren't found // Example const arrayOfObjects = [ { plants: 'men' }, { smart:'dumb' }, { peace: 'war' } ] const sentence1 = 'plants are smart' const result1 = arrayOfObjects.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence1) console.log(result1) // result1: // men are dumb // Extra: string insertion python style with an array of words and indexes // usage // arrayOfWords.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence) // where arrayOfWords has words you want to insert in sentence // Example // replaces as many words in the sentence as are defined in the arrayOfWords // use python type {0}, {1} etc notation // five to replace const sentence2 = '{0} is {1} and {2} are {3} every {5}' // but four in array? doesn't break const words2 = ['man','dumb','plants','smart'] // what happens ? const result2 = words2.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence2) console.log(result2) // result2: // man is dumb and plants are smart every {5} // replaces as many words as are defined in the array // three to replace const sentence3 = '{0} is {1} and {2}' // but five in array const words3 = ['man','dumb','plant','smart'] // what happens ? doesn't break const result3 = words3.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence3) console.log(result3) // result3: // man is dumb and plants