source

여러 문자열을 여러 문자열로 바꿉니다.

goodcode 2023. 1. 19. 21:32
반응형

여러 문자열을 여러 문자열로 바꿉니다.

문자열에 있는 여러 단어를 다른 여러 단어로 바꾸려고 합니다.끈은 "나는 고양이, 개, 그리고 염소가 있다"입니다.

그러나 이것은 "나는 개, 염소, 고양이를 가지고 있다"는 것이 아니라 "나는 고양이, 고양이, 고양이를 가지고 있다"는 것을 생산한다.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 예시

일반화

regex를 동적으로 유지하고 맵에 향후 교환만 추가할 경우 이 작업을 수행할 수 있습니다.

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과 원하는 치환 맵을 함수에 전달하면 변환된 문자열이 반환됩니다.

기능을 만지작거리다

오브젝트를 보증합니다.키는 오래된 브라우저에서 작동합니다. MDN 또는 Es5에서 폴리필을 추가합니다.

이에 대한 답변:

최신 답변을 구하다

현재 예시와 같이 "words"를 사용하는 경우 캡처하지 않은 그룹을 사용하여 Ben McCormick의 답변을 확장하고 단어 경계를 추가할 수 있습니다.\b왼쪽과 오른쪽에서 부분적인 일치를 방지합니다.

\b(?:cathy|cat|catch)\b
  • \b 단어
  • (?:비캡처 그룹
    • cathy|cat|catch 중 를 택하다
  • ) capture (비캡처 그룹 )
  • \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);

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

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은 문자열을 숫자로 변환한 다음 1을 빼서 애완동물 배열을 인덱싱합니다.

%number는 배열 인덱스의 문자열로 대체됩니다.

/g를 지정하면 각 번호로 람다 함수가 반복적으로 호출되며, 이 함수는 배열의 문자열로 대체됩니다.

최신 JavaScript:-

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

이 경우 정확한 요구 사항을 충족하지 못할 수 있지만 일반적인 솔루션으로서 문자열의 여러 매개 변수를 대체할 수 있는 유용한 방법을 발견했습니다.참조 횟수에 관계없이 파라미터의 모든 인스턴스가 교체됩니다.

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'

Array.protype.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

이 방법은 효과가 있었습니다.

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"

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

주의!

동적으로 제공되는 매핑을 사용하는 경우 이 솔루션으로는 충분하지 않습니다.

이 경우, 이 문제를 해결하는 방법은 (1) 분할 결합 기술을 사용하는 방법과 (2) 특수 문자 이스케이프 기술을 사용하는 Regex를 사용하는 방법 두 가지가 있습니다.

  1. 이것은 스플릿 조인(split-join) 기술로, 다른 것보다 훨씬 빠릅니다(최소 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. 이것은 Regex 특수 문자 이스케이프 기술입니다.이 기술도 동작하지만 매우 느립니다.

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

후자의 장점은 대소문자를 구분하지 않는 검색에서도 사용할 수 있다는 것입니다.

원본 포스터의 솔루션이 작동하지 않는 이유를 궁금해 하는 경우:

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

이 솔루션은 단어 전체를 대체하도록 조정될 수 있습니다. 따라서 "catch", "ducat" 또는 "locator"는 "cat"를 검색할 때 찾을 수 없습니다.이는 부정적인 뒷모습을 사용하여 수행할 수 있습니다.(?<!\w) 부정적인 전망(?!\w)정규 표현의 각 단어 앞뒤에 있는 단어 문자:

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

JSFiddle 데모: http://jsfiddle.net/mfkv9r8g/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))

사용자 정규 함수를 사용하여 대체할 패턴을 정의한 다음 치환 함수를 사용하여 입력 문자열에 대한 작업을 수행합니다.

var i = new RegExp('"{','g'),
    j = new RegExp('}"','g'),
    k = data.replace(i,'{').replace(j,'}');
    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."
/\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);

가능한 해결책 중 하나는 매퍼 표현 함수를 사용하는 것입니다.

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.

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
}

구분 기호를 사용하여 문자열을 검색 및 바꿀 수 있습니다.

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

var text = "Hello {firstname}, Your firstname is {firstname} and 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;
}

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

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

저는 이 npm 패키지 스트링을 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" 

이 목적으로 https://www.npmjs.com/package/union-replacer 를 사용할 수 있습니다.기본적으로는string.replace(regexp, ...)할 수 1개의 패스로 할 수 .이것에 의해, 1개의 패스로 모든 파워를 유지할 수 있습니다.string.replace(...).

공개:나는 작가다.라이브러리는 보다 복잡한 사용자 구성 가능한 치환을 지원하기 위해 개발되었으며 캡처 그룹, 백 레퍼런스, 콜백 함수 치환 등 모든 문제를 해결합니다.

위의 솔루션은 스트링을 정확하게 치환하기에 충분합니다.

프로토타입 기능을 사용하여 키와 값, 재현 가능한 텍스트와 함께 객체를 전달함으로써 쉽게 대체할 수 있습니다.

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

, , 에서 하고 모든 정상적으로 합니다.REGEXREPLACE를 참조해 주세요.

아래 두 개의 오리지널 솔루션에서는 1개의 연결과 1개의 regex만 사용합니다.

방법 #1: 치환값 조회

대체 값이 문자열에 아직 없는 경우 값을 추가하는 것이 좋습니다.그런 다음 단일 regex를 사용하여 필요한 모든 교환을 수행합니다.

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))'고양이이죠. 않으면 " 가 캡처됩니다일치하는 경우 정방향 조회는 "dog"를 그룹 1로 캡처하고 그렇지 않은 경우 "를 캡처합니다.
  • 그룹 2로 "gog"를 캡처하는 "dog"와 그룹 3으로 "cat"을 캡처하는 "gog"도 마찬가지입니다.
  • 「」로 됩니다."$1$2$3"그룹 ) 중에 대해 항상 " "(3개, "dog", "cat"은 "cat"이 됩니다.
  • 요.str+"||||cat,dog,goat"을 매칭하여 합니다.\|\|\|\|.*$ "$1$2$3"이렇게 해서 '이렇게 하면 안 돼요.

방법 #2: 교환 쌍 조회

Method #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|sublic) 또는 다른 것으로 대체될 수 있는 "임의의 단어"를 지정합니다.
  • (?=[\s\S]*...)는 일반적으로 치환 맵이 끝날 때까지 문서의 끝으로 이동하는 순방향 룩업입니다.
    • ,\1=>는 "쉼표와 오른쪽 화살표 사이에서 일치하는 단어를 찾아야 한다"는 의미입니다.
    • ([^,]*)"이 화살표 뒤에 있는 모든 것을 다음 쉼표 또는 문서의 끝에 일치시킬 때까지"를 의미합니다.
  • |\|\|\|\|.*$대체 맵을 삭제하는 방법입니다.

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

이거 드셔보세요.현명하게 사지 마세요.

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);
Out put: I have a dog, a goat, and a cat.

@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 blah"를 반환합니다.

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

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

언급URL : https://stackoverflow.com/questions/15604140/replace-multiple-strings-with-multiple-other-strings

반응형