文字列内の複数の単語を複数の別の単語に置き換えようとしています。文字列は「私には猫、犬、ヤギがいます。」です。
しかし、これは「犬、ヤギ、猫を飼っています」ではなく、「猫、猫、猫を飼っています」という結果を生成します。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".
ベストアンサー1
具体的な解決策
関数を使用してそれぞれを置き換えることができます。
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];
});
一般化する
正規表現を動的に維持し、将来の交換をマップに追加したい場合は、次のようにします。
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()];
});
}
したがって、必要な置換文字列のマップと文字列を関数に渡すだけで、変換された文字列が返されます。
Object.keysが古いブラウザでも動作するようにするには、例えば次のようなポリフィルを追加します。翻訳またはエス5。