여러 문자열을 여러 다른 문자열로 교체


213

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

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

이미 바뀐 단어를 바꾸지 않고 문자열의 여러 단어를 다른 여러 단어로 바꾸고 싶습니다.
Anderson Green

다른 쿼리를했습니다. 사용자가 고양이 또는 개 또는 염소를 입력한다는 것을 알고 있다면 (임의로옵니다)이 단어가 올 때마다 '동물'이라고 바꿔야합니다. 이 시나리오 얻는 방법
프라 사나 Sasne

답변:


445

특정 솔루션

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

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 등 의 폴리 필을 추가하십시오 .


4
JavaScript 문자열에서 허용되는 문자가 JavaScript 식별자에서 허용되는 문자 (예 : 여기에서 사용되는 키)와 같지 않기 때문에이 함수를 사용하여 모든 유형의 문자열을 바꿀 수 있는지 확실하지 않습니다. .
앤더슨 그린

2
임의의 문자열을 자바 스크립트 속성으로 사용할 수 있습니다. 중요하지 않습니다. .이러한 모든 속성에 표기법을 사용할 수는 없습니다 . 대괄호 표기법은 모든 문자열에서 작동합니다.
벤 맥코믹

2
실제로 훌륭하게 작동합니다. 나는이 솔루션 ( '특정')을 성공적으로 사용하여 영어 숫자 표기법을 유럽 표기법 (24,973.56에서 24.973,56)으로 사용 map={'.': ',', ',': '.'}하고 regex 사용 /\.|,/g합니다.
Sygmoral

5
이 솔루션을 좋아하지만 에서 대소 문자를 구분하는 키를 사용한 return mapObj[matched.toLowerCase()];직후 로 바꿔야 return mapObj[matched];했습니다 mapObj.
Michal Moravcik

2
정규식의 키를 이스케이프 할 수 있습니다 Object.keys(mapObj).map(key => key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|').. 이 답변에서 영감을 얻은
robsch

9

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

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'

8

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

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

흥미 롭군 바꾸기 기능의 논리를 설명 할 수 있습니까?
Eric Hepperle-CodeSlayer2010

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"


문자열에 정규식 문자가 포함되어 있으면 작동하지 않습니다.
Roemer

"확장하지 마십시오 ...": 문자열을 확장하여 대소 문자를 구분하지 않는 두 문자열을 비교했습니다. 이 기능은 String에서 제공하지 않지만 언젠가는 앱이 중단 될 수 있습니다. 그러한 함수를 안전하게 포함하기 위해 "서브 클래스"또는 "확장"문자열을 사용할 수있는 방법이 있습니까, 아니면 단순히 앱 라이브러리의 일부로 새로운 2 인수 함수를 정의해야합니까?
David Spector

4

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


가장 좋은 답변입니다. 그러나 ${f}누적 값으로 f 대신 사용해야하는 이유가 있습니까?
David Spector

1
첫 번째 문자열뿐만 아니라 주어진 문자열을 모두 바꾸려면 g 플래그를 추가하십시오. "const result1 = arrayOfObjects.reduce ((f, s) => ${f}.replace (new RegExp (Object.keys (s) [ 0], 'g'), s [Object.keys (s) [0]], 문장 1) "
David Spector

2

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

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

하, 하 ... 잘 분석 ... 엄지 손가락
디파 MG

1

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

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

건너 뛰기를 알지 못하지만 정답이 아니라고 말하지 마십시오. 저의 경우 "{"a ": 1,"b ": 2}"와 같은 방식으로 위의 방법으로 교체했습니다. 다른 사람이 다른 사람을 원한다면 도움이된다면 대답은 당신만을위한 것이 아닙니다. @Carr
KARTHIKEYAN.A

다시 말하지만, 당신은 의미없는 대답을 제공했습니다. 당신이하는 일은 이미 질문에서 할 수있는 사람입니다.이 대답은 사람들이 새로운 것으로 생각하고 RegExp물체를 활용 하여 문제를 해결할 수 있다고 오도 할 것입니다
Carr

이 경우에도 여전히 할 때 asker의 질문과 같은 문제가 있습니다var i = new RegExp('}','g'), j = new RegExp('{','g'), k = data.replace(i,'{').replace(j,'}');
Carr

1

내로 교체-번 패키지, 다음을 수행 할 수 있습니다 :

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

이 패키지는 놀랍습니다 :) 정확히 예상대로 작동
Vishnu Prassad

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

3
영업 이익 "은 여러 다른 문자열 여러 문자열을 대체 할 수 있는가 물었다 동시에 ". 이것은 세 가지 단계입니다.
LittleBobbyTables-Au Revoir 2014 년

1

구분자를 사용하여 문자열을 찾아서 바꿀 수 있습니다.

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

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

console.log(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;
}


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

/ * replace 문자열에 대해 몇 가지 메소드를 사용합니다. 원하는만큼 인수를 사용하고 모든 문자열을 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/


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>

0

이 npm 패키지 stringinject https://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" 

0

이를 위해 https://www.npmjs.com/package/union-replacer 를 사용할 수 있습니다 . 기본적으로 string.replace(regexp, ...)대응되는 기능 으로, 모든 힘을 유지하면서 한 번에 여러 번의 교체가 가능합니다 string.replace(...).

공개 : 나는 저자입니다. 이 라이브러리는보다 복잡한 사용자 구성 가능 대체를 지원하도록 개발되었으며 캡처 그룹, 역 참조 및 콜백 함수 대체와 같은 모든 문제를 해결합니다.

위의 솔루션은 정확한 문자열 교체에 충분합니다.


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

"blah blah 234433 blah blah"를 반환합니다.

이렇게하면 일치하는 단어가 아닌 mapObj의 키와 일치합니다 '


// 쓸모없는 : replaceAll ( "나는 고양이, 개, 염소가있다.", {고양이 : "개", 개 : "염소", 염소 : "고양이"}) // 생성 : "고양이가있다 , 고양이, 고양이. "
devon

-3

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

이 솔루션에는 JQuery가 필요합니까?
Anderson Green

자바 스크립트 태그가 추가되었으며 jquery는 자바 스크립트의 라이브러리입니다.
슈퍼 모델

2
@Super javascript tag added in question, and jquery is a libarary of javascript.Hmmm은 논리가 꺼져 있고, 다른 방식으로 진행되어야하며, 자바 스크립트 태그 정보에서 다음과 같이 진행됩니다. " 프레임 워크 / 라이브러리에 다른 태그가 포함되어 있지 않으면 순수한 JavaScript 응답이 필요합니다. "
Traxo

@Anderson Green, 예 위의 스크립트에는 jquery가 필요했습니다.
슈퍼 모델

@ Traxo, 대부분의 웹 애플리케이션에서 프레임 워크 (bootstrap / google material)를 사용합니다. Jquery는 모든 최신 프레임 워크에 포함됩니다. 따라서 웹 애플리케이션에는 jquery가 필요합니다.
슈퍼 모델
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.