모든 문자열을 바꾸는 방법?


4377

이 문자열이 있습니다.

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

하기:

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

abc위의 문자열에서 첫 번째 항목 만 제거하는 것 같습니다 .

모든 발생을 어떻게 교체 할 수 있습니까?


5
모든 항목 교체시 aba에서 ababaca예상 할 결과,? caba? abca? cca?
reinierpost

String.prototype.replaceAll()Safari 13.1에 출시되었으며 현재 Firefox Nightly 및 Chrome Dev 및 Canary에 있으며 Firefox 77 및 Chrome 85에 제공됩니다. 아직 MDN에 문서화되어 있지 않지만 github.com/tc39/proposal-string-replaceall#high-level-api "경우 설명자을 가지고 searchValue이 문자열 인, String.prototype.replaceAll대체 모두 의 발생 searchValue을 (것처럼 .split(searchValue).join(replaceValue)또는 글로벌 및 제대로 이스케이프 정규 표현식을 사용했다). 경우 searchValue이 비전 역 정규 표현식은, String.prototype.replaceAll예외 "가 발생합니다
sideshowbarker

답변:


1608

참고 : 성능이 중요한 코드에는이 코드를 사용하지 마십시오.

간단한 리터럴 문자열에 대한 정규식의 대안으로 다음을 사용할 수 있습니다.

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

일반적인 패턴은

str.split(search).join(replacement)

예전 replaceAll에는 정규 표현식을 사용하는 것보다 빠르지 만 더 이상 최신 브라우저에서는 그렇지 않습니다.

벤치 마크 : https://jsperf.com/replace-all-vs-split-join

결론 : 성능이 중요한 사용 사례 (예 : 수백 개의 문자열 처리)가있는 경우 Regexp 메서드를 사용하십시오. 그러나 가장 일반적인 사용 사례의 경우 특수 문자에 대해 걱정할 필요가 없습니다.


147
이 방법이 더 많은 객체를 할당하고 더 많은 가비지를 생성하므로 시간이 더 오래 걸릴 것으로 예상했지만 실제로 브라우저에서 테스트했을 때이 방법은 허용되는 응답보다 일관되게 약 20 % 빠릅니다. 물론 결과는 다를 수 있습니다.
MgSam

42
궁금해서 jsperf.com/replace-all-vs-split-join 설정했습니다 . v8은 다른 자바 스크립트 엔진과 비교하여 배열을 분할 / 결합하는 데 미친 듯이 빠릅니다.
fabi

8
매우 훌륭함-또한 특수 문자를 전달할 때 잘못된 RegExps 가능성을 방지합니다. 객체 속성에서 "find this and replace it"에 대한 일반 플래그를 추가하고 있지만 ""를 교체해야하는지 걱정했습니다. " 또는 "}"이며 3 개월 후에 RegEx를 사용하고 있다는 사실을 잊었습니다!
tobriand

9
그리고 String.prototype으로 : String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}. 사용법 : "My string".replaceAll('st', '');"내 반지"를 생성합니다
MacroMan

8
경고가 프로덕션에서 이것을 사용하지 않아야 할 이유가 없습니다. 여러 번의 교체를 원하기 때문에 정규 표현식을 탈출하는 것보다 해킹은 아니지만 처음에는 정규 표현식이 필요하지 않습니다. 이 replaceAll기능을 "hack"이라고하는 멋진 기능으로 감싸면 다른 것과 마찬가지로 읽을 수있게됩니다. 성능이 나쁘지 않기 때문에이 솔루션을 피할 이유가 없습니다.
youn

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

의견에 대한 답변 :

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

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

Click Upvote 의 의견에 대한 답변으로 더 많은 것을 단순화 할 수 있습니다.

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

참고 : 정규식에는 특수 (메타) 문자가 포함되어 있으므로 find위 의 함수 에서 사전 처리하지 않고 해당 문자를 이스케이프 처리하지 않고 맹목적으로 인수를 전달하는 것은 위험합니다 . 이 내용은 정규 표현식 에 대한 Mozilla 개발자 네트워크JavaScript 안내서에서 다루며 다음과 같은 유틸리티 기능을 제공합니다 (이 답변이 처음 작성된 이후 최소한 두 번 변경되었으므로 잠재적 인 업데이트가 있는지 MDN 사이트를 확인하십시오).

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

따라서 replaceAll()위 의 기능을 더 안전하게 만들기 위해 다음을 포함하면 다음과 같이 수정할 수 있습니다 escapeRegExp.

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

4
정규식은 고유 한 'replaceAll'메소드를 구현하지 않고 "바로"이를 수행 할 수있는 유일한 방법입니다. 나는 그것들을 사용하기 위해 그들의 사용을 제안하지는 않습니다.
Sean Bright

10
이것은이 의견에서 내 자신의 기능입니다 : function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
클릭 Upvote

47
replaceAll구현 의 주요 경고는 find메타 문자 가 포함되어 있으면 작동하지 않는다는 것 입니다.
Martin Ender

1
@SeanBright 당신이 맞아요. 나는 PHP 코드에서 자바 스크립트를 사용했기 때문에 탈출하기 위해 백 슬래시를 추가해야했습니다. 바이올린에서 코드는 완벽합니다. 확인 했어야했는데 사과 jsfiddle.net/7y19xyq8
Onimusha


2437

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

참고 : 일반적으로 JavaScript로 내장 프로토 타입을 확장하는 것은 권장되지 않습니다. String내장 프로토 타입 에 대한 가상 표준 방법의 다양한 구현을 보여주기 위해 단순히 설명을 목적으로 String 프로토 타입에 대한 확장을 제공하고 있습니다 .


정규식 기반 구현

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

효율성 측면에서 정규 표현식이이면에서 어떻게 작동하는지에 대해 너무 많이 알지 못했지만 성능에 대해 생각하지 않고 과거에 분할 및 구현에 의존하는 경향이있었습니다. 어느 쪽이 더 효율적이고 어떤 마진으로 궁금해했을 때 나는 그것을 핑계로 사용했습니다.

내 크롬 윈도우 8 시스템에서, 정규 표현식 기반 구현이 가장 빠른 으로, 분할 및 구현 53 % 느리게되고 가입 . 정규 표현식이 내가 사용한 lorem ipsum 입력의 두 배 빠름을 의미합니다.

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


아래 @ThomasLeduc 및 기타 의견에서 언급했듯이 정규 표현식 에서 특수 문자로search 예약 된 특정 문자가 포함 된 경우 정규 표현식 기반 구현에 문제가있을 수 있습니다 . 구현에서는 호출자가 미리 문자열을 이스케이프하거나 정규 표현식 (MDN) 의 테이블에 문자가없는 문자열 만 전달한다고 가정합니다 .

MDN은 또한 문자열을 이스케이프하기위한 구현을 제공합니다. 이것이 또한로 표준화 RegExp.escape(str)되었지만 좋을 것입니다 .하지만 아예 존재하지 않습니다.

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

그러나 구현 escapeRegExp내에서 호출 할 수는 String.prototype.replaceAll있지만 이것이 성능에 얼마나 영향을 미칠지 잘 모르겠습니다 (모든 영숫자 문자열과 같이 이스케이프가 필요하지 않은 문자열의 경우에도).


8
Android 4.1에서는 정규 표현식 방법이 15 % 빠르지 만 검색 할 표현식을 이스케이프하지 않으므로이 벤치 마크가 불완전합니다.
andreszs

33
이 솔루션에 문제가 있습니다. 검색 문자열이 정규 표현식의 특수 문자를 포함하는 것으로 해석되면 해석됩니다. @Sandy Unitedwolf 답변을 추천합니다.
Thomas Leduc

2
첫 번째 작업은 다음과 같습니다. 'bla.bla'.replaceAll ('. ','_ '); "_______". 두 번째는 'bla_bla'을 수행하는데, 이는 일반적으로 원하는 것입니다.
RobKohr

1
@ThomasLeduc 당신이 lodash =>으로 해결할 수 있습니다 언급 한 문제처럼 보인다 lodash.com/docs/4.17.5#escapeRegExp
마태 복음 벡

1
네이티브 객체를 확장하는 것이 왜 좋지 않은지 궁금해하는 미래의 시청자들을 위해 여기에 남겨
Ben Cooper

691

g플래그가 설정된 정규식을 사용하면 모든 것이 대체됩니다.

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

여기도 참조


15
바보 같은 생각이지만 JS 전역 정규 표현식은 여러 번 대체 할 수있는 유일한 방법입니다.
Mike

5
물론 기술적으로 당신은을 통해 루프 수 var sourceText인스턴스 (수 계산 numOfInstances)를 사용하여 substring또는 분할을 그리고 (다른 전략들)의 길이를 계산 thatWhichYouWantToReplace한 후 수행 for (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');} 또는 더 쉽게 바로 사용 루프 (동안 while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)) 그러나 당신이 원하는 것이 왜 표시되지 않습니다 사용 /g이 너무 쉽고 아마도 더 성능이 좋을 때 그렇게하십시오.
Zargold

@Zargold 교체 후에도 모든 인스턴스를 교체했는지 확인하기 위해 루프를 수행하려고합니다. 이는 상당히 일반적인 문제입니다. 아래의 답변을 참조하십시오 stackoverflow.com/a/26089052/87520
SamGoody

109

허용되는 답변을 기반으로 한 문자열 프로토 타입 함수는 다음과 같습니다.

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

편집하다

당신의 find의지에 특수 문자가 포함되어 있으면 탈출해야합니다.

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

피들 : http://jsfiddle.net/cdbzL/


5
그러나 경우는 find같은 문자가 포함 .또는 $정규 표현식에서 특별한 의미를 가질 수?
callum

1
@callum이 경우 찾기 변수를 이스케이프해야합니다 (위의 편집 참조).
jesal


jesal, 이것은 내가 만난 문자열 교체 문제에 대한 훌륭한 솔루션이며 JavaScript에서 문자열의 "불변성"을 극복합니다. 이 프로토 타입 함수가 어떻게 문자열의 불변성을 재정의하는지 설명 할 수 있습니까? 이것은 작동 합니다; 나는이 부수적 인 질문을 이해하고 싶습니다.
Tom

1
@Tom : 불변성을 전혀 극복 하지 못합니다 : 메소드가 적용 var str = this되는 불변 문자열에 대한 두 번째 참조를 만들고 replace결과적으로 새로운 불변 ​​문자열을 반환 합니다 . 당신이 쓸 수있을 거라고하지 않을 경우 이러한 프로토 타입 기능, 새로운 불변의 문자열을 반환 someStrVar.replaceAll('o', '0');하고 someStrVar변경할 수있다. 대신, 새로운 불변 ​​문자열someStrVar = someStrVar.replaceAll('o', '0'); 을 보유하도록 var를 설정하려면 <-reassign 을 작성해야 합니다 . 그 주위에 방법이 없습니다. 콘솔에서 시도 :x = 'foobar'; x.replaceAll('o', '0'); x;
Elias Van Ootegem

87

최신 정보:

업데이트가 다소 늦었지만 방금이 질문에 걸려서 이전 답변이 내가 만족하지 않는 것으로 나타났습니다. 문제는 한 단어를 바꾸는 것과 관련이 있기 때문에 아무도 단어 경계를 사용한다고 생각하지 않습니다 ( \b)

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

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

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

기본적으로이 질문은 다음 질문과 동일합니다. Javascript replace " '" "" ""

@Mike, 내가 준 대답을 확인하십시오 ... regexp가 subsrting의 여러 항목을 대체하는 유일한 방법은 아닙니다. 유연하게 생각하고 분할 생각하십시오!

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

또는 승인 된 답변이 수행하는 단어 부분의 교체를 방지하기 위해! 좀 더 복잡하고 그 결과로 약간 더 느린 정규식을 사용 하여이 문제를 해결할 수 있습니다.

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

그러나 출력은이 문자열에서 / cat / g 표현식을 사용하여 허용되는 답변과 동일합니다.

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

실제로, 이것은 아마도 당신이 원하는 것이 아닐 것입니다. 그렇다면 무엇입니까? 조건부로 'cat'만 바꾸는 정규식 IMHO (즉, 단어의 일부가 아님)

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"

내 생각에, 이것은 당신의 요구를 충족시킵니다. 물론 완전하지는 않지만 시작하기에 충분해야합니다. 이 페이지에서 더 많은 것을 읽는 것이 좋습니다. 이는 특정 요구를 충족하기 위해이 표현을 완성하는 데 유용합니다.

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

http://www.regular-expressions.info


최종 추가 :

이 질문에 여전히 많은 견해 .replace가 있으므로 콜백 함수와 함께 사용되는 예를 추가 할 수 있다고 생각했습니다 . 이 경우, 극적으로 표현을 단순화 하고 올바른 대문자로 교체 또는 둘 모두를 교체처럼, 더 많은 유연성을 제공 cat하고 cats하나의 이동에 :

'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

추가 흥미로운 부분이 바닥에 배치되어야한다고 생각합니다. 추신 : 나는 지금 첫 번째 줄의 절반이 영역을 벗어났다는 것을 알았습니다.

69

전역 정규 표현식과 일치

anotherString = someString.replace(/cat/g, 'dog');

60

한 번만 사용하는 경우 :

var res = str.replace('abc', "");

여러 번 교체하려면 다음을 사용하십시오.

var res = str.replace(/abc/g, "");

누군가 \ n을 교체해야한다면 다음과 같이하면됩니다 :replace(/\n/g, '<br/>')
Phan Van Linh

58

가장 일반적이고 읽기 쉬운 방법입니다.

var str = "Test abc test test abc test test test abc test test abc"

방법 1 :

str = str.replace(/abc/g, "replaced text");

방법 2 :

str = str.split("abc").join("replaced text");

방법 3 :

str = str.replace(new RegExp("abc", "g"), "replaced text");

방법 4 :

while(str.includes("abc")){
    str = str.replace("abc", "replaced text");
}

산출:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text

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

또는 여기에서 replaceAll 함수를 시도하십시오.

내장 객체를 확장하는 유용한 JavaScript 메소드는 무엇입니까?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

편집 : replaceAll 가용성에 대한 설명

'replaceAll'메소드가 String의 프로토 타입에 추가됩니다. 이는 모든 문자열 객체 / 리터럴에 사용할 수 있음을 의미합니다.

예 :

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'

2
프로토 타입을 사용하지 않는 사용자를 위해 replaceAll () 함수를 다시 작성할 수 있습니까?
Upvote를 클릭하십시오

@Click Upvote .... 프로토 타입을 사용하고 있으며 모든 JS 객체의 일부입니다. JS 라이브러리를 prototype.js에 대해 생각하고 있다고 생각합니다.
seth

세스, 약간의 수정. 프로토 타입에 메소드를 추가하면 해당 유형의 모든 오브젝트에서 메소드를 사용할 수 있습니다. replceAll 메소드는 문자열 프로토 타입에 추가되었으며 모든 문자열 오브젝트에 대해 작동해야합니다.
SolutionYogi

@solutionyogi-예, 전에 프로토 타입을 사용했습니다. 방금 Prototype.js를 의미한다고 가정 한 "prototype을 사용하지 않는다"는 OP의 의견을 언급 한 것입니다 (아마도 틀렸습니까?). JavaScript 객체에 프로토 타입이 있다고 말하려고하면서 "프로토 타입"이라고 말해야했습니다. 따라서 OP는 이미 "간접적"방식이지만 이미 프로토 타입을 사용하고있었습니다. 간접적 인 용어는 여기서 사용하기에 잘못된 용어 일지 모르지만 나는 너무나 피곤해서 메 파라다.
seth

41

사용 RegExp자바 스크립트를 잊지 마세요, 단순히 코드를 다음과 같이 할, 당신을 위해 일을 할 수있는 /g에있는 뛰어난 이후 글로벌 :

var str ="Test abc test test abc test test test abc test test abc";
str = str.replace(/abc/g, '');

재사용을 생각한다면, 그것을 위해 함수를 작성하십시오.하지만 한 줄 함수이므로 권장되지 않지만 다시 이것을 많이 사용하면 다음과 같이 작성할 수 있습니다.

String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
  return this.replace(new RegExp(string, 'g'), replaced);
};

아래 코드와 같이 코드에서 반복해서 사용하십시오.

var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');

그러나 앞에서 언급했듯이, 작성되는 줄이나 성능 측면에서 큰 차이는 없지만 함수를 캐싱하는 것만으로 긴 문자열에서 더 빠른 성능을 발휘할 수 있으며 재사용하려는 경우 DRY 코드를 잘 활용할 수 있습니다.


40

모든 'abc'를 'x'로 바꾸고 싶다고 가정 해보십시오.

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def

문자열 프로토 타입을 수정하는 것보다 더 간단한 것을 생각하려고했습니다.


1
간단하고, 쉽고, 아마도 가장 성능이 좋은 옵션 : 좋은 답변.
machineghost

실제로 개인적으로 측정하지는 않았지만 split / join은 일반적으로 성능이 뛰어난 솔루션입니다.
machineghost

1
크롬에서도 파이어 폭스에서는 100 % 빠르며 IE에서는 50 % 느립니다 ... : jsperf.com/replace-regex-split-join
Olivier


32

작은 따옴표 바꾸기 :

function JavaScriptEncode(text){
    text = text.replace(/'/g,'&apos;')
    // More encode here if required

    return text;
}

2
문자열을 대체하기 위해 두 번째 줄을 어떻게 바꿀 수 있습니까? 작동하지 않습니다 : text = text.replace ( 'hey', 'hello'); 어떤 생각?
Stefan Đorđević

2
슈테판, 여기 코드가 있습니다 ... text = text.replace (/ hey / g, 'hello');
Chris Rosete

26

// 숫자가 0이 될 때까지 반복합니다. 또는 단순히 복사 / 붙여 넣기

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }

23
이 방법은 위험하므로 사용하지 마십시오. 대체 문자열에 검색 키워드가 포함되면 무한 루프가 발생합니다. 최소한 결과를 .indexOf변수에 저장 하고이 변수를 두 번째 매개 변수 .indexOf(키워드 빼기 길이, 대체 문자열 길이 더하기)로 사용하십시오.
Rob W

먼저 검색 패턴을 위 어드 유니 코드 문자로 바꾸는 것에 대해 생각하고 있습니다. 입력 문자열에 사용되지 않는 것이 확실합니다. 개인 공간에서 U + E000처럼. 그런 다음 다시 대상으로 교체하십시오. 나는 그것을 여기에 구축했습니다. . 좋은 생각인지 확실하지 않습니다.
Lux

26
str = str.replace(new RegExp("abc", 'g'), "");

위의 답변보다 나를 위해 더 잘 작동했습니다. 따라서 텍스트 ( ) 의 new RegExp("abc", 'g')모든 발생 ( 'g'플래그) 과 일치하는 RegExp를 만듭니다 "abc". 두 번째 부분은 빈 문자열 ( "") 로 대체됩니다 . str는 문자열이며 replace(...)결과 만 반환하지만 재정의는하지 않으므로 재정의해야합니다. 경우에 따라 사용할 수도 있습니다.


이 코드 스 니펫이 해결책이 될 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 실제로 도움이됩니다. 앞으로 독자들에게 질문에 대한 답변을 제공하므로 해당 사람들이 코드 제안의 이유를 모를 수도 있습니다.
yivi

그래, 당신 말이 맞아. 추가되었습니다. 또한 원래 질문에 대답하도록 편집 :)
csomakk

참고 : 정규식 수단에 g 플래그는 세계 모든 항목을 일치합니다 플래그입니다
firstpostcommenter을

25

이것은이다 빠른 버전의 정규 표현식을 사용하지 않습니다 .

수정 된 jsperf

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

split 및 join 방법 보다 거의 두 배 빠릅니다.

여기 주석에서 지적했듯이 omit변수가 포함 된 경우 place: 에서처럼 replaceAll("string", "s", "ss")단어가 항상 다른 단어를 대체 할 수 있기 때문에 작동하지 않습니다 .

내 재귀 대체에 변형이있는 또 다른 jsperf가 더 빠릅니다 ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • 2017 년 7 월 27 일 업데이트 : RegExp가 최근에 출시 된 Chrome 59에서 가장 빠른 성능을 가진 것으로 보입니다.

나는 당신의 해결책을 사랑했습니다 ... 나는 당신에게 +10을 줄 수 있기를 바랍니다. 그러나 여기는 내 +1입니다. 무한 루프 문제를 피하기 위해 하위 색인에서 일치하는 항목을 찾으면 교체 된 하위 문자열의 색인을 저장하고 다음 문자열로 이동할 수 있다고 생각합니다. 테스트하지 않았기 때문에 성능에 대해 언급 할 수는 없지만이 우수성에 대해서는 2 센트입니다.
Fr0zenFyr

@ fr0zenfyr 생략 자리에 당신이 좋아하는 조건부을 할 수있는 (무한 루프를 방지하기 위해) 인 경우 당신은 확인하고 싶은 경우 if(place.replace(omit) === omit) {는 루프 대신 사용하는 것이 안전합니다, 그래서 일치 } else {일치 그렇게 분할과 같은 다른 방법을 사용하여 가입}
콜 로렌스

흠 ..하지만 두 솔루션을 결합한 요점은 무엇입니까? 어쨌든 나는 어쨌든 split / join 접근의 팬이 아니다. 조언에 감사드립니다.
Fr0zenFyr

@ Fr0zenFyr 두 솔루션을 결합하는 목적은 더 빠른 방법을 사용할 수없는 경우 (예 : 루프가 무한 할 때) 느린 방법으로 대체하는 것입니다. 따라서 기능은 효율적이지만 장애 가능성은없는 안전한 보호 장치가됩니다.
Cole Lawrence

@momomo 어떻게 결함?
SandRock

24

공연

오늘 27.12.2019 선택한 솔루션에 대해 macOS v10.13.6 (High Sierra)에서 테스트를 수행 합니다.

결론

  • str.replace(/abc/g, '');( C는 ) 모든 문자열에 대한 좋은 크로스 브라우저 빠른 솔루션입니다.
  • split-join( A, B ) 또는 replace( C, D ) 기반 솔루션 은 빠릅니다
  • while( E, F, G, H ) 기반 솔루션 은 느립니다. 일반적으로 작은 줄의 경우 ~ 4 배 느리고 긴 줄의 경우 ~ 3000 배 (!) 느립니다.
  • 반복 솔루션 ( RA, RB )은 느리고 긴 문자열에는 작동하지 않습니다.

나는 또한 내 자신의 솔루션을 만듭니다. 현재 질문 작업을 수행하는 것이 가장 짧은 것 같습니다.

str.split`abc`.join``

세부

테스트는 Chrome 79.0, Safari 13.0.4 및 Firefox 71.0 (64 비트)에서 수행되었습니다. 테스트 RARB재귀를 사용합니다. 결과

여기에 이미지 설명을 입력하십시오

짧은 문자열-55 자

여기 에서 컴퓨터에서 테스트를 실행할 수 있습니다 . Chrome 결과 :

여기에 이미지 설명을 입력하십시오

긴 문자열 : 275 000 자

재귀 솔루션 RARB

RangeError : 최대 호출 스택 크기를 초과했습니다

1M 캐릭터의 경우 Chrome을 손상시킵니다.

여기에 이미지 설명을 입력하십시오

다른 솔루션에 대해 1M 문자에 대한 테스트를 시도하지만 E, F, G, H 는 브라우저가 스크립트를 중단하도록 요청하는 데 많은 시간이 걸리므로 테스트 문자열을 275K 문자로 줄입니다. 여기 에서 컴퓨터에서 테스트를 실행할 수 있습니다 . Chrome에 대한 결과

여기에 이미지 설명을 입력하십시오

테스트에 사용 된 코드


1
이제 이것은 깊이있는 답변 중 하나입니다! 대단히 감사합니다! 그래도 궁금한 점은 "새로운 RegExp (...)"구문이 그토록 개선 된 이유입니다.
Márk Gergely Dolinka

21

찾고자하는 문자열이 이미 있고 정규 표현식 이스케이프가없는 경우 join / split을 사용할 수 있습니다.

    function replaceMulti(haystack, needle, replacement)
    {
        return haystack.split(needle).join(replacement);
    }

    someString = 'the cat looks like a cat';
    console.log(replaceMulti(someString, 'cat', 'dog'));


감사! 이 솔루션은 내 문제에 완벽하게 작동합니다 :)
xero399

19
function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}

하위 문자열이 기본이거나 문자 배열을 통해 새 문자를 만드는 것이 얼마나 잘 수행되는지 궁금합니다.
mmm

16

나는이 방법을 좋아한다 (약간 깨끗해 보인다) :

text = text.replace(new RegExp("cat","g"), "dog"); 

1
좋아, 문자열을 어떻게 정규식 패턴으로 사용하기 위해 탈출합니까?
rakslice 2016 년

나는 보통 텍스트로 사용한다
Owen

15

정규 표현식을 사용하지 않고이를 수행하는 가장 간단한 방법은 다음 코드와 같이 분할되고 결합됩니다.

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



13

문자열에 비슷한 패턴이 포함되어 있으면 abccc다음을 사용할 수 있습니다.

str.replace(/abc(\s|$)/g, "")

13

이전 답변은 너무 복잡합니다. 다음과 같이 바꾸기 기능을 사용하십시오.

str.replace(/your_regex_pattern/g, replacement_string);

예:

var str = "Test abc test test abc test test test abc test test abc";

var res = str.replace(/[abc]+/g, "");

console.log(res);


10

교체 후에도 찾고있는 문자열이 존재하지 않도록하려면 루프를 사용해야합니다.

예를 들면 다음과 같습니다.

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

완료되면 여전히 'test abc'가 있습니다!

이를 해결하는 가장 간단한 루프는 다음과 같습니다.

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

그러나 각 사이클마다 교체가 두 번 실행됩니다. 약간 더 효율적이지만 읽기 어려운 형태로 결합 될 수있는 (투표 될 위험이 있음) :

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

중복 문자열을 찾을 때 특히 유용합니다.
예를 들어 'a ,,, b'가 있고 모든 중복 쉼표를 제거하려는 경우.
[이 경우 .replace (/, + / g, ',') 할 수 있지만 어떤 시점에서 정규 표현식은 복잡하고 대신 반복하기에 충분히 느립니다.]


10

사람들은 정규식 사용을 언급했지만 텍스트의 경우에 관계없이 텍스트를 바꾸려면 더 나은 방법이 있습니다. 대문자 또는 소문자처럼. 아래 구문 사용

//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');

//Output will be all the occurrences removed irrespective of casing.

자세한 예는 여기를 참조 하십시오 .


예제 사이트에서 : "/ toBeReplacedString / gi는 사용해야하는 정규 표현식입니다. 여기서 g는 전역 일치를 나타내고 i는 대소 문자를 구분하지 않습니다. 기본적으로 정규 표현식은 대소 문자를 구분합니다"
alikuli

8

아래 방법을 간단하게 사용할 수 있습니다

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};

7

그냥 추가 /g

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/g 글로벌을 의미

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.