[javascript] 여러 문자열을 여러 다른 문자열로 교체

문자열의 여러 단어를 다른 여러 단어로 바꾸려고합니다. 줄은 “고양이, 개, 염소입니다.”

그러나 이것은 “나는 개, 염소, 고양이가있다”를 생산하지 않고 대신에 “나는 고양이, 고양이, 고양이가있다”를 생산한다. 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".



답변

특정 솔루션

함수를 사용하여 각각을 교체 할 수 있습니다.

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가 작동하도록하려면 MDN 또는 Es5 등 의 폴리 필을 추가하십시오 .


답변

이것은이 인스턴스의 정확한 요구를 충족시키지 못할 수도 있지만 일반적인 해결책으로 문자열의 여러 매개 변수를 대체하는 유용한 방법을 찾았습니다. 참조 횟수에 관계없이 모든 매개 변수 인스턴스를 대체합니다.

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'


답변

다시 교체하지 않도록 번호가 매겨진 품목을 사용하십시오. 예 :

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 +는 % 뒤에 오는 숫자를 찾습니다. 대괄호는 숫자를 캡처합니다.

이 숫자 (문자열)는 람다 함수의 두 번째 매개 변수 n입니다.

+ n-1은 문자열을 숫자로 변환 한 다음 pets 배열을 인덱싱하기 위해 1을 뺍니다.

그런 다음 % number는 배열 인덱스에서 문자열로 바뀝니다.

/ g는 람다 함수가 각 숫자로 반복적으로 호출 된 다음 배열의 문자열로 대체됩니다.

현대 JavaScript에서 :-

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


답변

이것은 나를 위해 일했다 :

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"


답변

사용 ) (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


답변

누군가 원래 포스터의 솔루션이 작동하지 않는 이유를 궁금해하는 경우를 대비하여 :

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."


답변

바꿀 패턴을 정의한 다음 replace 함수를 사용하여 입력 문자열을 처리하는 사용자 일반 함수,

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