JavaScript에서 문자열의 모든 발생을 바꾸는 방법


질문

 

내 JavaScript 코드 에이 문자열이 있습니다.

"Test abc test test abc test test test abc test test abc"

행위:

str = str.replace('abc', '');

위의 문자열에서 ABC의 첫 번째 발생 만 제거하는 것 같습니다.

그것의 모든 발생을 어떻게 대체 할 수 있습니까?


답변

 

2020 년 8 월 현재 : 현대 브라우저는 ECMAScript 2021 언어 사양에 의해 정의 된 String.replaceall () 메소드에 대한 지원을받습니다.


이전 / 레거시 브라우저의 경우 :

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

이 대답이 어떻게 진화하는지 여기에 있습니다.

str = str.replace(/abc/g, '');

의견에 대한 응답으로 " 'IF'ABC '가 변수로 전달됩니까?":

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

upvote의 댓글을 클릭하면 더 많은 것을 단순화 할 수 있습니다.

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

참고 : 정규 표현식에는 특수 (메타) 문자가 포함되어 있으며 그 문자를 이스케이프로 처리하지 않고 위의 찾기 기능에 눈을 맹목적으로 전달하는 것이 위험합니다.정규 표현식에 대한 Mozilla Developer Network의 JavaScript 가이드에서 다룹니다.이 유틸리티 함수 (이 답변이 원래 작성된 이후 적어도 두 번 변경되었으므로 잠재적 인 업데이트를 위해 MDN 사이트를 확인하십시오).

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

따라서 ExplaIBL () 기능을보다 안전하게 만드려면 EscApereGEXP도 포함하는 경우 다음으로 수정할 수 있습니다.

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}


답변

완전성을 위해, 나는 이것을하기 위해 어떤 방법을 사용해야하는지 생각해야합니다.이 페이지에서 다른 답변에서 제안한대로 기본적으로 두 가지 방법이 있습니다.

참고 : 일반적으로 JavaScript에서 기본 제공 프로토 타입을 확장하는 것은 일반적으로 권장되지 않습니다.String Prototype에 대한 확장자로서 삽화의 목적으로 간단히 제공되어 문자열 내장 프로토 타입의 가상 표준 메소드의 다른 구현을 보여줍니다.


정규 표현식 기반 구현

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

분할 및 조인 (기능) 구현

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

효율성 측면에서 정규식이 장면 뒤에서 일하는 방식에 대해 너무 많이 알지 못하면서 나는 공연에 대해 생각하지 않고 과거에 분할을 향하고 이행을 가입시키는 경향이있었습니다.내가 더 효율적이었던 궁금해했을 때, 나는 어떤 마진에 의해 그것을 알아내는 변명으로 그것을 사용했다.

내 크롬 Windows 8 컴퓨터에서 정규 표현식 기반 구현은 가장 빠르고 분할 및 조인 구현이 53 % 느립니다.의미있는 Lorem IPsum 입력에 대해 정규식이 두 배나 빠르게 두 배나 빠릅니다.

이 두 구현을 서로에 대해 실행하는이 벤치 마크를 확인하십시오.


@thomasleduc 및 다른 사람들이 아래의 의견에 명시된대로 정규 표현식에서 특수 문자로 예약 된 특정 문자가 포함 된 특정 문자가 포함되어있는 경우 정규 표현식 기반 구현에 문제가있을 수 있습니다.구현은 발신자가 자열을 미리 탈출하거나 정규 표현식 (MDN)의 테이블의 문자가없는 문자열 만 전달할 것으로 가정합니다.

MDN은 또한 우리의 문자열을 피할 수있는 구현을 제공합니다.이것이 regexp.escape (str)로 표준화되었지만 Alas는 존재하지 않으면 좋을 것입니다.

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

우리는 String.Prototype.ReplaceAll 구현에서 EscApereGEXP를 호출 할 수 있지만, 이것이 성능에 영향을 미치는지 확실하지 않습니다 (잠재적으로 모든 영숫자 문자열처럼 탈출이 필요하지 않은 문자열의 경우).



답변

업데이트 : 가장 인기있는 브라우저의 최신 버전에서는 replaceall을 사용할 수 있습니다. 여기에 표시된대로 :

let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"

그러나 Tranch를 사용하여 타겟팅하는 브라우저가 처음에 지원을 추가했는지 확인하려면 먼저 사용할 수 있습니까?


For Node and compatibility with older/non-current browsers:

Note: Don't use the following solution in performance critical code.

As an alternative to regular expressions for a simple literal string, you could use

str = "Test abc test test abc test...".split("abc").join("");

The general pattern is

str.split(search).join(replacement)

This used to be faster in some cases than using replaceAll and a regular expression, but that doesn't seem to be the case anymore in modern browsers.

Benchmark: https://jsben.ch/TZYzj

Conclusion:

If you have a performance critical use case (e.g processing hundreds of strings), use the Regexp method. But for most typical use cases, this is well worth not having to worry about special characters.



답변

G 플래그 세트가있는 정규 표현식을 사용하면 모두를 대체합니다.

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

여기를 참조하십시오



답변

다음은 허용 된 답변을 기반으로하는 문자열 프로토 타입 함수입니다.

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

편집하다

찾기에 특수 문자가 포함되어 있으면이를 이스케이프해야합니다.

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

바이올린 : http://jsfiddle.net/cdbzl/



답변

업데이트:

업데이트가 다소 늦었지만, 나는이 질문에 방금 뒤틀었고, 이전의 답변이 하나가 아니라는 것을 알아 차렸다.질문은 단일 단어를 대체하는 것과 관련이 있기 때문에, 믿을 수없는 아무도 워드 경계 (\ b)를 사용한다고 생각하지 않습니다.

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

이것은 대부분의 경우 단어의 일부를 교체하는 것을 피하는 간단한 정규식입니다.그러나 대시는 여전히 단어 경계로 간주됩니다.따라서 쿨 고양이와 같은 문자열을 교체하지 않으려면이 경우 조건부를 사용할 수 있습니다.

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

Basically, this question is the same as the question here: Javascript replace " ' " with " '' "

@Mike, check the answer I gave there... regexp isn't the only way to replace multiple occurrences of a subsrting, far from it. Think flexible, think split!

var newText = "the cat looks like a cat".split('cat').join('dog');

Alternatively, to prevent replacing word parts -which the approved answer will do, too! You can get around this issue using regular expressions that are, I admit, somewhat more complex and as an upshot of that, a tad slower, too:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

The output is the same as the accepted answer, however, using the /cat/g expression on this string:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

Oops indeed, this probably isn't what you want. What is, then? IMHO, a regex that only replaces 'cat' conditionally. (ie not part of a word), like so:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

My guess is, this meets your needs. It's not fullproof, of course, but it should be enough to get you started. I'd recommend reading some more on these pages. This'll prove useful in perfecting this expression to meet your specific needs.

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info


Final addition:

Given that this question still gets a lot of views, I thought I might add an example of .replace used with a callback function. In this case, it dramatically simplifies the expression and provides even more flexibility, like replacing with correct capitalisation or replacing both cat and cats in one go:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar
출처:https://stackoverflow.com/questions/1144783/how-to-replace-all-occurrences-of-a-string-in-javascript