[javascript] 모든 문자열을 바꾸는 방법?
이 문자열이 있습니다.
"Test abc test test abc test test test abc test test abc"
하기:
str = str.replace('abc', '');
abc
위의 문자열에서 첫 번째 항목 만 제거하는 것 같습니다 .
모든 발생을 어떻게 교체 할 수 있습니까?
답변
참고 : 성능이 중요한 코드에는이 코드를 사용하지 마십시오.
간단한 리터럴 문자열에 대한 정규식의 대안으로 다음을 사용할 수 있습니다.
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 메서드를 사용하십시오. 그러나 가장 일반적인 사용 사례의 경우 특수 문자에 대해 걱정할 필요가 없습니다.
답변
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);
}
답변
완벽을 기하기 위해 어떤 방법을 사용해야하는지 생각해야했습니다. 이 페이지의 다른 답변에서 제안한대로 기본적으로 두 가지 방법이 있습니다.
참고 : 일반적으로 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
있지만 이것이 성능에 얼마나 영향을 미칠지 잘 모르겠습니다 (모든 영숫자 문자열과 같이 이스케이프가 필요하지 않은 문자열의 경우에도).
답변
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);
};
답변
최신 정보:
업데이트가 다소 늦었지만 방금이 질문에 걸려서 이전 답변이 내가 만족하지 않는 것으로 나타났습니다. 문제는 한 단어를 바꾸는 것과 관련이 있기 때문에 아무도 단어 경계를 사용한다고 생각하지 않습니다 ( \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
답변
전역 정규 표현식과 일치
anotherString = someString.replace(/cat/g, 'dog');