문자열 지정:
s = "Test abc test test abc test test test abc test test abc";
이것은 첫 번째 발생만을 제거하는 것으로 보인다.abc
위의 문자열:
s = s.replace('abc', '');
발생하는 모든 것을 대체하려면 어떻게 해야 합니까?
질문에 대한 답변
2020년 8월 현재: 최신 브라우저는 ECMAScript 2021 언어 사양에서 정의된 방식을 지원합니다.
구형/레거시 브라우저의 경우:
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, '');
“abc가 변수로 전달되면 어떻게 됩니까?”라는 코멘트에 대한 응답입니다.“:
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 Developer Network의 JavaScript Guide on Regular Expressions에 기재되어 있습니다(이 답변이 처음 작성된 이후 적어도 두 번 변경되었으므로 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); }
저는 완성도를 높이기 위해 어떤 방법을 사용해야 할지 고민하게 되었습니다.이 페이지의 다른 답변에서 제시된 바와 같이 기본적으로 두 가지 방법이 있습니다.
참고: 일반적으로 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); };
효율면에서 정규 표현이 이면에서 어떻게 작용하는지 잘 모르기 때문에 과거에는 성과에 대해 생각하지 않고 분할하여 구현에 참여하는 경향이 있었습니다.어느 쪽이 더 효과적이고 어느 쪽이 더 효과적인지 궁금했을 때, 나는 그것을 핑계로 알아냈다.
Chrome Windows 8 머신의 경우 정규 표현식 기반 구현이 가장 빠르며 분할 및 가입 구현 속도가 53% 느립니다.즉, 정규 표현은 사용한 lorem ipsum 입력보다 2배 빠릅니다.
이 벤치마크에서는 이 두 가지 구현을 서로 비교합니다.
@ThomasLeduc 등의 코멘트에서 알 수 있듯이 정규 표현 기반 구현에 문제가 있을 수 있습니다.search
에는 정규 표현에서 특수 문자로 예약된 특정 문자가 포함되어 있습니다.실장에서는, 발신자가 사전에 문자열을 이스케이프 하거나, 정규 표현(MDN)의 테이블에 문자가 없는 문자열만을 건네주는 것을 전제로 하고 있습니다.
MDN은 당사의 문자열을 회피하기 위한 구현도 제공합니다.이것 또한 표준화가 되어 있으면 좋겠습니다.RegExp.escape(str)
하지만 안타깝게도, 그것은 존재하지 않는다.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}() []\]/g, "\$&"); // $& means the whole matched string }
전화하면 되지escapeRegExp
우리 안에서String.prototype.replaceAll
다만, 이것이 퍼포먼스에 어느 정도 영향을 미칠지는 알 수 없습니다(모든 영숫자 문자열과 같이 이스케이프가 필요 없는 문자열도 영향을 받을 수 있습니다).
업데이트: 가장 많이 사용되는 브라우저의 최신 버전에서는 다음과 같이 사용할 수 있습니다.
let result = "1 abc 2 abc 3".replaceAll("abc", "xyz"); // `result` is "1 xyz 2 xyz 3"
그러나 먼저 사용 가능 또는 다른 호환성 테이블을 선택하여 대상 브라우저가 먼저 지원 기능을 추가했는지 확인합니다.
노드 및 기존/비현행 브라우저와의 호환성의 경우:
주의: 퍼포먼스 크리티컬코드에 다음 솔루션을 사용하지 마십시오.
단순한 리터럴 문자열에 대한 정규 표현 대신
str = "Test abc test test abc test...".split("abc").join("");
일반적인 패턴은
str.split(search).join(replacement)
이 방법은 기존에는 사용하는 것보다 더 빠를 수 있습니다.replaceAll
그리고 정규 표현이지만, 현대 브라우저에서는 더 이상 그렇지 않은 것 같습니다.
벤치마크: https://jsben.ch/TZYzj
결론:
퍼포먼스가 중요한 사용 사례(예를 들어 수백 개의 스트링 처리)가 있는 경우 Regexp 방법을 사용합니다.그러나 대부분의 일반적인 사용 사례에서는 특수 문자에 대해 걱정할 필요가 없습니다.
에서 정규 표현 사용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); };
편집
만약 당신이find
에는 특수 문자가 포함되어 있으므로 이스케이프해야 합니다.
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-/\^$*+?.() []{}]/g, '\$&'), 'g'), replace); };
바이올린: http://jsfiddle.net/cdbzL/