274

文字列内の複数の単語を他の複数の単語に置き換えようとしています。文字列は「猫、犬、山羊がいます」です。

ただし、これでは「犬、山羊、猫がいる」ではなく、「猫、猫、猫がいる」という結果になります。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".
4

27 に答える 27

551

特定のソリューション

関数を使用して、それぞれを置き換えることができます。

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と必要な置換のマップを関数に渡すだけで、変換された文字列が返されます。

機能をいじる

Object.keysが古いブラウザで確実に機能するようにするには、MDNEs5などのポリフィルを追加します。

于 2013-03-24T21:26:09.917 に答える
26

答えとして:

最新の答えを探しています

現在の例のように「単語」を使用している場合は、非キャプチャグループを使用してBen McCormick\bの回答を拡張し、部分的な一致を防ぐために左右に単語の境界を追加できます。

\b(?:cathy|cat|catch)\b
  • \b部分一致を防ぐための単語境界
  • (?:非キャプチャグループ
    • cathy|cat|catch選択肢の1つに一致する
  • )非キャプチャグループを閉じる
  • \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);

于 2021-05-03T19:24:06.750 に答える
16

番号の付いたアイテムを使用して、再度交換しないようにします。例えば

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 +は、%の後に続く数字を検索します。角かっこは数字を表します。

この数値(文字列として)は、ラムダ関数の2番目のパラメーターnです。

+ n-1は文字列を数値に変換し、1を引いてpets配列にインデックスを付けます。

次に、%numberは、配列インデックスの文字列に置き換えられます。

/ gを指定すると、ラムダ関数が各数値で繰り返し呼び出され、配列の文字列に置き換えられます。

最新のJavaScriptの場合:-

replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])
于 2018-05-18T12:39:32.010 に答える
13

この場合、これは正確なニーズを満たさない可能性がありますが、一般的な解決策として、これは文字列内の複数のパラメーターを置き換えるための便利な方法であることがわかりました。パラメータが何度参照されても、パラメータのすべてのインスタンスが置き換えられます。

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'
于 2013-03-24T23:59:18.907 に答える
6

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

于 2019-06-18T03:07:03.713 に答える
5

これは私のために働いた:

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"
于 2016-02-16T11:50:04.283 に答える
4

私の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.'
于 2018-03-04T18:14:04.523 に答える
3

誰かが元のポスターのソリューションが機能しない理由を疑問に思っている場合に備えて:

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."
于 2017-07-03T10:58:10.177 に答える
2

このソリューションは、単語全体を置き換えるように適合させることができます。たとえば、「cat」を検索しても「catch」、「ducat」、「locator」は見つかりません。これは、正規表現の各単語の前後の単語文字にネガティブルックビハインド(?<!\w)とネガティブルックアヘッドを使用することで実行できます。(?!\w)

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

JSFiddleデモ:http ://jsfiddle.net/mfkv9r8g/1/

于 2021-05-04T08:40:58.217 に答える
1

置換するパターンを定義し、置換関数を使用して入力文字列を処理するユーザー通常関数、

var i = new RegExp('"{','g'),
    j = new RegExp('}"','g'),
    k = data.replace(i,'{').replace(j,'}');
于 2017-08-18T07:08:55.233 に答える
1
    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."
于 2019-06-17T13:10:29.757 に答える
1

区切り文字を使用して文字列を検索および置換できます。

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

于 2019-11-14T17:40:50.347 に答える
1

ノート!

動的に提供されるマッピングを使用している場合、ここでの解決策のどれも十分ではありません!

この場合、この問題を解決するには、(1)分割結合手法を使用する方法、(2)特殊文字エスケープ手法で正規表現を使用する方法の2つがあります。

  1. これは分割結合手法であり、他の手法よりもはるかに高速です(少なくとも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, '{')
);

  1. これは、正規表現の特殊文字エスケープ手法です。これも機能しますが、はるかに低速です。

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

後者の利点は、大文字と小文字を区別しない検索でも機能することです。

于 2021-04-30T17:13:32.537 に答える
1
/\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);

于 2021-05-01T02:15:15.623 に答える
1

私の解決策を試してください。お気軽に改善してください

function multiReplace(strings, regex, replaces) {
  return str.replace(regex, function(x) {
    // check with replaces key to prevent error, if false it will return original value
    return Object.keys(replaces).includes(x) ? replaces[x] : x;
  });
}
var str = "I have a Cat, a dog, and a goat.";
//(json) use value to replace the key
var replaces = {
  'Cat': 'dog',
  'dog': 'goat',
  'goat': 'cat',
}
console.log(multiReplace(str, /Cat|dog|goat/g, replaces))

于 2021-07-02T04:36:30.213 に答える
0
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 CopyRights保存対象: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/

于 2013-12-01T13:34:16.553 に答える
0
<!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>
于 2016-08-13T10:42:03.903 に答える
0

私はこのnpmパッケージstringinjecthttps : //www.npmjs.com/package/stringinjectを作成しました。これにより、次のことが可能になります。

var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]);

これにより、{0}と{1}が配列アイテムに置き換えられ、次の文字列が返されます。

"this is a test string for stringInject"

または、プレースホルダーを次のようにオブジェクトのキーと値に置き換えることができます。

var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });

"My username is tjcafferkey on Github" 
于 2017-07-19T16:06:46.263 に答える
0

この目的のためにhttps://www.npmjs.com/package/union-replacerを使用できます。これは基本的にはstring.replace(regexp, ...)対応するものであり、のフルパワーを維持しながら、1回のパスで複数の置換を実行できますstring.replace(...)

開示:私は著者です。このライブラリは、より複雑なユーザー設定可能な置換をサポートするために開発され、キャプチャグループ、後方参照、コールバック関数の置換などの問題のあるすべての問題に対処します。

ただし、上記のソリューションは、文字列を正確に置き換えるには十分です。

于 2019-11-16T15:19:34.390 に答える
0

プロトタイプ関数を使用することで、オブジェクトをキーと値、および置き換え可能なテキストに渡すことで簡単に置き換えることができます

String.prototype.replaceAll=function(obj,keydata='key'){
 const keys=keydata.split('key');
 return Object.entries(obj).reduce((a,[key,val])=> a.replace(`${keys[0]}${key}${keys[1]}`,val),this)
}

const data='hids dv sdc sd ${yathin} ${ok}'
console.log(data.replaceAll({yathin:12,ok:'hi'},'${key}'))

于 2020-07-02T09:31:59.837 に答える
0

クロージャを使用するプログラミング言語(Coda、Excel、SpreadsheetなどREGEXREPLACE)に適用する場合を除いて、すべてのソリューションがうまく機能します。

以下の私の2つの元のソリューションは、1つの連結と1つの正規表現のみを使用します。

方法1:置換値を検索する

置換値がまだ文字列に含まれていない場合は、それらを追加するという考え方です。次に、単一の正規表現を使用して、必要なすべての置換を実行します。

var str = "I have a cat, a dog, and a goat.";
str = (str+"||||cat,dog,goat").replace(
   /cat(?=[\s\S]*(dog))|dog(?=[\s\S]*(goat))|goat(?=[\s\S]*(cat))|\|\|\|\|.*$/gi, "$1$2$3");
document.body.innerHTML = str;

説明:

  • cat(?=[\s\S]*(dog))「猫」を探すという意味です。一致する場合、前方参照は「犬」をグループ1としてキャプチャし、それ以外の場合は「」をキャプチャします。
  • グループ2として「ヤギ」を捕獲する「犬」とグループ3として「猫」を捕獲する「ヤギ」についても同じです。
  • (3つのグループすべての連結)に置き換え"$1$2$3"ます。これは、上記のいずれかの場合、常に「犬」、「猫」、または「山羊」のいずれかになります。
  • のように文字列に手動で置換を追加した場合は、str+"||||cat,dog,goat"も照合して削除します\|\|\|\|.*$。この場合、置換"$1$2$3"は空の文字列である「」と評価されます。

方法2:交換ペアを探す

方法1の問題の1つは、一度に9回の置換を超えることができないことです。これは、バックプロパゲーショングループの最大数です。方法2は、置換値だけを追加するのではなく、直接置換を追加することを示しています。

var str = "I have a cat, a dog, and a goat.";
str = (str+"||||,cat=>dog,dog=>goat,goat=>cat").replace(
   /(\b\w+\b)(?=[\s\S]*,\1=>([^,]*))|\|\|\|\|.*$/gi, "$2");
document.body.innerHTML = str;

説明:

  • (str+"||||,cat=>dog,dog=>goat,goat=>cat")文字列の最後に置換マップを追加する方法です。
  • (\b\w+\b)「任意の単語をキャプチャする」と述べています。これは「(cat | dog | goat)」などに置き換えることができます。
  • (?=[\s\S]*...)は、通常、置換マップが完了するまでドキュメントの最後に移動する前方参照です。
    • ,\1=>「コンマと右矢印の間に一致する単語を見つける必要がある」という意味です
    • ([^,]*)「この矢印の後、次のカンマまたはドキュメントの終わりまで一致する」という意味です
  • |\|\|\|\|.*$置換マップを削除する方法です。
于 2020-08-31T18:33:39.733 に答える
0

split()メソッドとjoin()メソッドを使用することもできます。

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

str=str.split("cat").map(x => {return x.split("dog").map(y => {return y.split("goat").join("cat");}).join("goat");}).join("dog");

console.log(str);

于 2021-05-03T14:22:28.823 に答える
0

考えられる解決策の1つは、マッパー式関数を使用することです。

const regex = /(?:cat|dog|goat)/gmi;
const str = `I have a cat, a dog, and a goat.`;

let mapper = (key) => {
  switch (key) {
    case "cat":
      return "dog"
    case "dog":
      return "goat";
    case "goat":
      return "cat"
  }
}
let result = str.replace(regex, mapper);

console.log('Substitution result: ', result);
//Substitution result1:  I have a dog, a goat, and a cat.
于 2021-05-06T19:02:48.027 に答える
0

あなたはこれを試すことができます。スマートではない購入。

var str = "I have a cat, a dog, and a goat.";
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);
アウトプット:私は犬、山羊、猫を飼っています。

于 2021-05-07T09:57:51.510 に答える
0

const str = 'Thanks for contributing an answer to Stack Overflow!'
    const substr = ['for', 'to']

    function boldString(str, substr) {
        let boldStr
        boldStr = str
        substr.map(e => {
                const strRegExp = new RegExp(e, 'g');
                boldStr= boldStr.replace(strRegExp, `<strong>${e}</strong>`);
            }
        )
        return boldStr
}

于 2021-12-14T10:16:17.157 に答える
-1

@BenMcCormicksを少し拡張しました。彼は通常の文字列で機能しましたが、文字やワイルドカードをエスケープした場合は機能しませんでした。これが私がしたことです

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)

「何とか何とか234433何とか何とか」を返します

このようにして、一致した単語ではなく、mapObjのキーと一致します。

于 2014-11-17T16:33:02.633 に答える
-5

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));
    });
});
于 2018-01-16T08:08:05.280 に答える