문자열에서 문자의 모든 인스턴스를 바꾸는 가장 빠른 방법
JavaScript의 문자열에서 문자열 / 문자의 모든 인스턴스를 대체하는 가장 빠른 방법은 무엇입니까? A while
, for
루프, 정규 표현식?
가장 쉬운 방법은 g
플래그가 있는 정규식을 사용하여 모든 인스턴스를 대체하는 것입니다.
str.replace(/foo/g, "bar")
이렇게하면 문자열에서 모든 항목이 foo
로 bar
바뀝니다 str
. 문자열 만있는 경우 다음과 같이 RegExp 개체로 변환 할 수 있습니다.
var pattern = "foobar",
re = new RegExp(pattern, "g");
이 replaceAll을 시도하십시오 : http://dumpsite.com/forum/index.php?topic=4.msg8#msg8
String.prototype.replaceAll = function(str1, str2, ignore)
{
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
}
매우 빠르며 다른 많은 사람들이 실패하는 이러한 모든 조건에서 작동합니다.
"x".replaceAll("x", "xyz");
// xyz
"x".replaceAll("", "xyz");
// xyzxxyz
"aA".replaceAll("a", "b", true);
// bb
"Hello???".replaceAll("?", "!");
// Hello!!!
깨뜨릴 수 있는지 또는 더 나은 것이 있는지 알려주십시오. 그러나이 4 가지 테스트를 통과 할 수 있는지 확인하십시오.
var mystring = 'This is a string';
var newString = mystring.replace(/i/g, "a");
newString은 이제 'Thas as a strang'입니다.
또한 시도해 볼 수 있습니다.
string.split('foo').join('bar');
다음을 사용할 수 있습니다.
newStr = str.replace(/[^a-z0-9]/gi, '_');
또는
newStr = str.replace(/[^a-zA-Z0-9]/g, '_');
이것은 문자 나 숫자가 아닌 모든 문자를 ( '_')로 대체합니다. 대체하려는 항목의 밑줄 값을 간단히 변경하십시오.
속도 문제에서 생각해 보면 위의 링크에 제공된 대소 문자 구분 예제가 가장 빠른 솔루션이라고 생각합니다.
var token = "\r\n";
var newToken = " ";
var oldStr = "This is a test\r\nof the emergency broadcasting\r\nsystem.";
newStr = oldStr.split(token).join(newToken);
newStr은 "이것은 비상 방송 시스템의 테스트입니다."입니다.
진짜 대답은 그것이 당신의 입력이 어떻게 생겼는지에 완전히 달려 있다는 것입니다. 나는 JsFiddle 을 만들어서 다양한 입력에 대해 이것들과 몇 가지를 시도했습니다. 결과를 어떻게 보더라도 확실한 승자는 없습니다.
- RegExp는 어떤 테스트 케이스에서도 가장 빠르지는 않았지만 나쁘지 않았습니다.
- 분할 / 결합 접근 방식은 희소 교체의 경우 가장 빠릅니다.
내가 쓴 이것은 작은 입력과 고밀도 대체에 대해 가장 빠른 것 같습니다.
function replaceAllOneCharAtATime(inSource, inToReplace, inReplaceWith) { var output=""; var firstReplaceCompareCharacter = inToReplace.charAt(0); var sourceLength = inSource.length; var replaceLengthMinusOne = inToReplace.length - 1; for(var i = 0; i < sourceLength; i++){ var currentCharacter = inSource.charAt(i); var compareIndex = i; var replaceIndex = 0; var sourceCompareCharacter = currentCharacter; var replaceCompareCharacter = firstReplaceCompareCharacter; while(true){ if(sourceCompareCharacter != replaceCompareCharacter){ output += currentCharacter; break; } if(replaceIndex >= replaceLengthMinusOne) { i+=replaceLengthMinusOne; output += inReplaceWith; //was a match break; } compareIndex++; replaceIndex++; if(i >= sourceLength){ // not a match break; } sourceCompareCharacter = inSource.charAt(compareIndex) replaceCompareCharacter = inToReplace.charAt(replaceIndex); } replaceCompareCharacter += currentCharacter; } return output; }
다음과 같이 Regex 개체를 사용하십시오.
var regex = new RegExp('"', 'g'); str = str.replace(regex, '\'');
의 모든 항목을 "
로 대체합니다 '
.
가장 빠른 것이 무엇인지 모르겠지만 가장 읽기 쉬운 것이 무엇인지 알고 있습니다. 가장 짧고 간단한 것이 무엇인지 압니다. 다른 솔루션보다 조금 느리더라도 사용할 가치가 있습니다.
따라서 다음을 사용하십시오.
"string".replace("a", "b");
"string".replace(/abc?/g, "def");
그리고 더 빠르고 (음 ... 1/100000 초는 차이가 없습니다) 못생긴 코드 대신 좋은 코드를 즐기십시오. ;)
10 년 전에 작성한 구현이 실제로 완전히 작동하지 않는다는 사실을 깨닫고 이러한 제안을 여러 번 시도해 보았습니다 (오래 잊혀진 시스템의 불쾌한 프로덕션 버그가 항상 그런 것은 아닙니까?!). ... 내가 알아 차린 것은 내가 시도한 것 (모두 시도하지 않았 음)이 내 것과 동일한 문제를 가지고 있다는 것입니다. 즉, 그들은 모든 발생을 대체하지 않을 것입니다. ".."를 "."로 대체하여 "test .... txt"를 "test.txt"로 가져 오는 중 ... 어쩌면 정규식 상황을 놓쳤을까요? 하지만 나는 빗나 갔다 ...
그래서 다음과 같이 구현을 다시 작성했습니다. 그것은 매우 간단합니다. 비록 가장 빠르지는 않다고 생각하지만, 물론 타이트한 루프 안에서 이것을 수행하지 않는 한, 현대 JS 엔진에서는 그 차이가 중요하지 않을 것이라고 생각합니다. 그러나 그것은 항상 모든 경우에 해당됩니다.
function replaceSubstring(inSource, inToReplace, inReplaceWith) {
var outString = inSource;
while (true) {
var idx = outString.indexOf(inToReplace);
if (idx == -1) {
break;
}
outString = outString.substring(0, idx) + inReplaceWith +
outString.substring(idx + inToReplace.length);
}
return outString;
}
누군가에게 도움이되기를 바랍니다!
// Find, Replace, Case
// i.e "Test to see if this works? (Yes|No)".replaceAll('(Yes|No)', 'Yes!');
// i.e.2 "Test to see if this works? (Yes|No)".replaceAll('(yes|no)', 'Yes!', true);
String.prototype.replaceAll = function(_f, _r, _c){
var o = this.toString();
var r = '';
var s = o;
var b = 0;
var e = -1;
if(_c){ _f = _f.toLowerCase(); s = o.toLowerCase(); }
while((e=s.indexOf(_f)) > -1)
{
r += o.substring(b, b+e) + _r;
s = s.substring(e+_f.length, s.length);
b += e+_f.length;
}
// Add Leftover
if(s.length>0){ r+=o.substring(o.length-s.length, o.length); }
// Return New String
return r;
};
개체 의 replace()
방법을 사용하십시오 String
.
선택한 답변에서 언급했듯이 문자열에서 하위 문자열의 모든 인스턴스 를 바꾸려면 정규식에서 / g 플래그를 사용해야 합니다.
방금 벤치 마크를 코딩하고 처음 3 개의 답변을 테스트했습니다. 짧은 문자열 (<500 자)의
경우 세 번째로 많이 득표 한 답변이 두 번째로 많이 득표 한 답변보다 빠릅니다.
긴 문자열 (테스트 문자열에 ".repeat (300)"추가)의 경우 답 1 다음에 두 번째와 세 번째가 더 빠릅니다.
노트 :
위의 내용은 v8 엔진 (크롬 / 크롬 등)을 사용하는 브라우저에 해당됩니다.
파이어 폭스 (SpiderMonkey 엔진)를 사용하면 결과가 완전히 다릅니다.
스스로 확인하십시오 !! 세 번째 솔루션을 사용하는 Firefox
는 첫 번째 솔루션을 사용하는 Chrome보다 4.5 배 이상 빠른 것 같습니다. 미친 : D
function log(data) {
document.getElementById("log").textContent += data + "\n";
}
benchmark = (() => {
time_function = function(ms, f, num) {
var z;
var t = new Date().getTime();
for (z = 0;
((new Date().getTime() - t) < ms); z++) f(num);
return (z / ms)
} // returns how many times the function was run in "ms" milliseconds.
function benchmark() {
function compare(a, b) {
if (a[1] > b[1]) {
return -1;
}
if (a[1] < b[1]) {
return 1;
}
return 0;
}
// functions
function replace1(s) {
s.replace(/foo/g, "bar")
}
String.prototype.replaceAll2 = function(_f, _r){
var o = this.toString();
var r = '';
var s = o;
var b = 0;
var e = -1;
// if(_c){ _f = _f.toLowerCase(); s = o.toLowerCase(); }
while((e=s.indexOf(_f)) > -1)
{
r += o.substring(b, b+e) + _r;
s = s.substring(e+_f.length, s.length);
b += e+_f.length;
}
// Add Leftover
if(s.length>0){ r+=o.substring(o.length-s.length, o.length); }
// Return New String
return r;
};
String.prototype.replaceAll = function(str1, str2, ignore) {
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, "\\$&"), (ignore ? "gi" : "g")), (typeof(str2) == "string") ? str2.replace(/\$/g, "$$$$") : str2);
}
function replace2(s) {
s.replaceAll("foo", "bar")
}
function replace3(s) {
s.split('foo').join('bar');
}
function replace4(s) {
s.replaceAll2("foo", "bar")
}
funcs = [
[replace1, 0],
[replace2, 0],
[replace3, 0],
[replace4, 0]
];
funcs.forEach((ff) => {
console.log("Benchmarking: " + ff[0].name);
ff[1] = time_function(2500, ff[0], "foOfoobarBaR barbarfoobarf00".repeat(10));
console.log("Score: " + ff[1]);
})
return funcs.sort(compare);
}
return benchmark;
})()
log("Starting benchmark...\n");
res = benchmark();
console.log("Winner: " + res[0][0].name + " !!!");
count = 1;
res.forEach((r) => {
log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
});
log("\nWinner code:\n");
log(res[0][0].toString());
<textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>
버튼을 클릭하면 테스트가 10 초 (+2 초) 동안 실행됩니다.
내 결과 (같은 PC에서) :
Chrome/Linux Ubuntu 64:
1. replace1 score: 100% *winner* (766.18)
2. replace4 score: 99.07% speed of winner. (759.11)
3. replace3 score: 68.36% speed of winner. (523.83)
4. replace2 score: 59.35% speed of winner. (454.78)
Firefox/Linux Ubuntu 64
1. replace3 score: 100% *winner* (3480.1)
2. replace1 score: 13.06% speed of winner. (454.83)
3. replace4 score: 9.4% speed of winner. (327.42)
4. replace2 score: 4.81% speed of winner. (167.46)
엉망진창 어?
더 많은 테스트 결과를 추가 할 자유를 얻었습니다.
Chrome/Windows 10
1. replace1 score: 100% *winner* (742.49)
2. replace4 score: 85.58% speed of winner. (635.44)
3. replace2 score: 54.42% speed of winner. (404.08)
4. replace3 score: 50.06% speed of winner. (371.73)
Firefox/Windows 10
1. replace3 score: 100% *winner* (2645.18)
2. replace1 score: 30.77% speed of winner. (814.18)
3. replace4 score: 22.3% speed of winner. (589.97)
4. replace2 score: 12.51% speed of winner. (331.13)
Edge/Windows 10
1. replace1 score: 100% *winner* (1251.24)
2. replace2 score: 46.63% speed of winner. (583.47)
3. replace3 score: 44.42% speed of winner. (555.92)
4. replace4 score: 20% speed of winner. (250.28)
Galaxy Note 4의 Chrome
1. replace4 score: 100% *winner* (99.82)
2. replace1 score: 91.04% speed of winner. (90.88)
3. replace3 score: 70.27% speed of winner. (70.15)
4. replace2 score: 38.25% speed of winner. (38.18)
@Gumbo 추가 답변 추가-user.email.replace (/ foo / gi, "bar");
/foo/g - Refers to the all string to replace matching the case sensitive
/foo/gi - Refers to the without case sensitive and replace all For Eg: (Foo, foo, FoO, fOO)
'Development Tip' 카테고리의 다른 글
Spring Framework는 정확히 무엇입니까? (0) | 2020.10.02 |
---|---|
두 개의 std :: vector 연결 (0) | 2020.10.02 |
현재 활동에서 루트보기 가져 오기 (0) | 2020.10.02 |
코드 우선 vs 모델 / 데이터베이스 우선 [종료] (0) | 2020.10.02 |
'if'문에서 여러 줄 조건을 스타일링합니까? (0) | 2020.10.02 |