用多个其他字符串替换多个字符串

hc8w905p  于 2021-09-13  发布在  Java
关注(0)|答案(26)|浏览(411)

我正在尝试用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”
然而,这并不产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。在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".
oug3syen

oug3syen1#

作为对以下问题的答复:
正在寻找最新的答案
如果您在当前示例中使用“单词”,则可以使用非捕获组扩展ben mccormick的答案,并添加单词边界 \b 在左侧和右侧,以防止部分匹配。

\b(?:cathy|cat|catch)\b
``` `\b` 防止部分匹配的单词边界 `(?:` 非捕获组 `cathy|cat|catch` 匹配一个备选方案 `)` 关闭非捕获组 `\b` 防止部分匹配的单词边界
原始问题的示例:

let str = "I have a cat, a dog, and a goat.";
const mapObj = {
cat: "dog",
dog: "goat",
goat: "cat"
};
str = str.replace(/\b(?:cat|dog|goat)\b/gi, matched => mapObj[matched]);
console.log(str);

注解中的示例似乎效果不好:

let str = "I have a cat, a catch, and a cathy.";
const mapObj = {
cathy: "cat",
cat: "catch",
catch: "cathy"

};
str = str.replace(/\b(?:cathy|cat|catch)\b/gi, matched => mapObj[matched]);
console.log(str);

iqjalb3h

iqjalb3h2#

特定溶液

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

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];
});

JSFIDLE示例

概括起来

如果您想动态地维护regex,并且只需将未来的交换添加到Map中,您可以这样做

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];
});

要添加或更改任何其他替换,您只需编辑Map即可
摆弄动态正则表达式

使其可重复使用

如果你想让它成为一个通用模式,你可以把它拉出来,变成这样一个函数

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

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

因此,您只需将str和替换的Map传递给函数,它就会返回转换后的字符串。
玩弄功能
为了确保object.keys在较旧的浏览器中工作,请从mdn或es5添加polyfill。

hmtdttj4

hmtdttj43#

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

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'
cnwbcb6i

cnwbcb6i4#

使用编号的项目以防止再次更换。如

let str = "I have a %1, a %2, and a %3";
let pets = ["dog","cat", "goat"];

然后

str.replace(/%(\d+)/g, (_, n) => pets[+n-1])

工作原理:-%\d+查找%后面的数字。括号表示数字。
该数字(作为字符串)是lambda函数的第二个参数n。
+n-1将字符串转换为数字,然后减去1以索引pets数组。
然后将%数字替换为数组索引处的字符串。
/g导致使用每个数字重复调用lambda函数,然后用数组中的字符串替换这些数字。
在现代javascript中:-

replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])
eoigrqb6

eoigrqb65#

使用array.prototype.reduce():

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)

例子

// /////////////    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
lh80um4z

lh80um4z6#

这对我很有用:

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

function replaceAll(str, map){
    for(key in map){
        str = str.replaceAll(key, map[key]);
    }
    return str;
}

//testing...
var str = "bat, ball, cat";
var map = {
    'bat' : 'foo',
    'ball' : 'boo',
    'cat' : 'bar'
};
var new = replaceAll(str, map);
//result: "foo, boo, bar"
jei2mxaa

jei2mxaa7#

使用我的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.'
7qhs6swi

7qhs6swi8#

万一有人想知道为什么原始海报的解决方案不起作用:

var str = "I have a cat, a dog, and a goat.";

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

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

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

bwleehnv9#

此解决方案可以调整为仅替换整个单词-因此,例如,“catch”、“ducat”或“locator”在搜索“cat”时不会被找到。这可以通过使用负查找来完成 (?<!\w) 消极前瞻 (?!\w) 关于正则表达式中每个单词前后的单词字符:

(?<!\w)(cathy|cat|ducat|locator|catch)(?!\w)

JSFIDLE演示:http://jsfiddle.net/mfkv9r8g/1/

y1aodyip

y1aodyip10#

使用常规函数定义要替换的模式,然后使用替换函数处理输入字符串,

var i = new RegExp('"{','g'),
    j = new RegExp('}"','g'),
    k = data.replace(i,'{').replace(j,'}');
2nc8po8w

2nc8po8w11#

var str = "I have a cat, a dog, and a goat.";

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

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

    str = str.replace(/cat/i, "dog");
    // now str = "I have a dog, a goat, and a cat."
nkkqxpd9

nkkqxpd912#

您可以使用分隔符查找和替换字符串。

var obj = {
  'firstname': 'John',
  'lastname': 'Doe'
}

var text = "My firstname is {firstname} and my lastname is {lastname}"

alert(mutliStringReplace(obj,text))

function mutliStringReplace(object, string) {
      var val = string
      var entries = Object.entries(object);
      entries.forEach((para)=> {
          var find = '{' + para[0] + '}'
          var regExp = new RegExp(find,'g')
       val = val.replace(regExp, para[1])
    })
  return val;
}
nbnkbykc

nbnkbykc13#

注意!

如果您使用的是动态提供的Map,那么这里的任何解决方案都不够!

在这种情况下,有两种方法可以解决这个问题,(1)使用分割连接技术,(2)使用带有特殊字符转义技术的正则表达式。
这是一种拆分联接技术,比另一种快得多(至少快50%):

var str = "I have {abc} a c|at, a d(og, and a g[oat] {1} {7} {11."
var mapObj = {
   'c|at': "d(og",
   'd(og': "g[oat",
   'g[oat]': "c|at",
};
var entries = Object.entries(mapObj);
console.log(
  entries
    .reduce(
      // Replace all the occurrences of the keys in the text into an index placholder using split-join
      (_str, [key], i) => _str.split(key).join(`{${i}}`), 
      // Manipulate all exisitng index placeholder -like formats, in order to prevent confusion
      str.replace(/\{(?=\d+\})/g, '{-')
    )
    // Replace all index placeholders to the desired replacement values
    .replace(/\{(\d+)\}/g, (_,i) => entries[i][1])
    // Undo the manipulation of index placeholder -like formats
    .replace(/\{-(?=\d+\})/g, '{')
);

这是一种正则表达式特殊字符转义技术,它也可以工作,但速度要慢得多:

var str = "I have a c|at, a d(og, and a g[oat]."
var mapObj = {
   'c|at': "d(og",
   'd(og': "g[oat",
   'g[oat]': "c|at",
};
console.log(
  str.replace(
    new RegExp(
      // Convert the object to array of keys
      Object.keys(mapObj)
        // Escape any special characters in the search key
        .map(key => key.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'))
        // Create the Regex pattern
        .join('|'), 
      // Additional flags can be used. Like `i` - case-insensitive search
      'g'
    ), 
    // For each key found, replace with the appropriate value
    match => mapObj[match]
  )
);

后者的优点是,它还可以用于不区分大小写的搜索。

iezvtpos

iezvtpos14#

我修改了ben mccormick的答案,以便与您的新测试用例一起使用。
我只是在正则表达式中添加了单词边界:

/\b(cathy|cat|catch)\b/gi

“运行代码段”以查看以下结果:

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

console.log(str);
dpiehjr4

dpiehjr415#

String.prototype.replaceSome = function() {
    var replaceWith = Array.prototype.pop.apply(arguments),
        i = 0,
        r = this,
        l = arguments.length;
    for (;i<l;i++) {
        r = r.replace(arguments[i],replaceWith);
    }
    return r;
}

/*replacesome方法用于字符串,它接受我们想要的参数,并使用我们指定的最后一个参数替换所有参数。2013版权保存为:max ahmed这是一个示例:

var string = "[hello i want to 'replace x' with eat]";
var replaced = string.replaceSome("]","[","'replace x' with","");
document.write(string + "<br>" + replaced); // returns hello i want to eat (without brackets)
  • /

jsfiddle:http://jsfiddle.net/cpj89/

相关问题