Was ist der schnellste Weg, um alle Instanzen einer Zeichenfolge/eines Zeichens in einer Zeichenfolge in JavaScript zu ersetzen? Eine while
, eine for
-Schleife, ein regulärer Ausdruck?
Am einfachsten wäre es, einen regulären Ausdruck mit dem Flag g
zu verwenden, um alle Instanzen zu ersetzen:
str.replace(/foo/g, "bar")
Dadurch werden alle Vorkommen von foo
durch bar
in der Zeichenfolge str
ersetzt. Wenn Sie nur eine Zeichenfolge haben, können Sie diese wie folgt in ein RegExp-Objekt konvertieren:
var pattern = "foobar",
re = new RegExp(pattern, "g");
Versuchen Sie Folgendes: Alle ersetzen: 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);
}
Es ist sehr schnell, und es wird für ALLE diese Bedingungen funktionieren.
"x".replaceAll("x", "xyz");
// xyz
"x".replaceAll("", "xyz");
// xyzxxyz
"aA".replaceAll("a", "b", true);
// bb
"Hello???".replaceAll("?", "!");
// Hello!!!
Lass es mich wissen, wenn du es kaputt machen kannst oder etwas Besseres hast, aber stelle sicher, dass es diese 4 Tests bestehen kann.
var mystring = 'This is a string';
var newString = mystring.replace(/i/g, "a");
newString heißt jetzt "Thas wie ein Strang"
Sie können auch versuchen:
string.split('foo').join('bar');
Wenn ich nur aus Geschwindigkeitsgründen darüber nachdenke, glaube ich, dass das unter Link oben angegebene Fallbeispiel die bei weitem schnellste Lösung wäre.
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 wäre "Dies ist ein Test des Notrufsystems."
Sie können Folgendes verwenden:
newStr = str.replace(/[^a-z0-9]/gi, '_');
oder
newStr = str.replace(/[^a-zA-Z0-9]/g, '_');
Dies wird alle Zeichen ersetzen, bei denen es sich nicht um Buchstaben oder Zahlen handelt ('_'). Ändern Sie einfach den Unterstrichwert für das, was Sie ersetzen möchten.
Ich denke, die wirkliche Antwort ist, dass es völlig davon abhängt, wie Ihre Eingaben aussehen. Ich habe ein JsFiddle erstellt, um ein paar davon und ein paar eigene gegen verschiedene Eingaben zu testen. Egal wie ich die Ergebnisse betrachte, ich sehe keinen klaren Gewinner.
Dieser, den ich geschrieben habe, scheint bei kleinen Eingaben und dichtem Ersatz am schnellsten zu sein:
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;
}
Verwenden Sie ein Regex-Objekt wie dieses
var regex = new RegExp('"', 'g');
str = str.replace(regex, '\'');
Es ersetzt alle Vorkommen von "
in '
.
Verwenden Sie die replace()
-Methode des String
-Objekts.
Wie in der ausgewählten Antwort erwähnt, sollte das Flag/g im regulären Ausdruck verwendet werden, um alle -Instanzen des Teilstrings im String zu ersetzen.
Was am schnellsten ist, weiß ich nicht, aber ich weiß, was am lesbarsten ist - was am kürzesten und einfachsten ist. Auch wenn es etwas langsamer ist als andere Lösungen, lohnt es sich zu verwenden.
Verwenden Sie also:
"string".replace("a", "b");
"string".replace(/abc?/g, "def");
Und genieße guten Code statt schneller (gut ... 1/100000 Sek. Ist kein Unterschied) und hässlicher. ;)
Ich habe einige dieser Vorschläge ausprobiert, nachdem ich gemerkt hatte, dass eine Implementierung, die ich vor fast 10 Jahren geschrieben hatte, tatsächlich nicht vollständig funktionierte (böser Produktionsfehler in einem längst vergessenen System, ist das nicht immer der Fall ?!) ... was mir aufgefallen ist, dass die, die ich ausprobierte (ich habe sie nicht alle ausprobiert), das gleiche Problem hatten wie das meine, das heißt, sie würden nicht JEDES Vorkommen ersetzen, nur das erste, zumindest für meinen Testfall "test .... txt" runter zu "test.txt" bekommen, indem ".." durch "." ersetzt wird ... vielleicht habe ich die Regex-Situation so verpasst? Aber ich schweife ab...
Also habe ich meine Implementierung wie folgt umgeschrieben. Es ist ziemlich einfach, obwohl ich vermute, nicht der Schnellste zu sein, aber ich glaube auch nicht, dass der Unterschied bei modernen JS-Motoren von Bedeutung sein wird, es sei denn, Sie machen das natürlich in einer engen Schleife, aber das ist immer der Fall.
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;
}
Hoffe das hilft jemandem!
// 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;
};
Ich habe gerade einen Benchmark programmiert und die ersten 3 Antworten getestet. Es scheint, dass für kurze Zeichenfolgen (<500 Zeichen)
Die am dritthäufigsten gewählte Antwort ist schneller als die am zweithäufigsten gewählte.
Bei langen Zeichenfolgen (fügen Sie der Testzeichenfolge ".repeat (300)" hinzu) ist die Antwort 1 schneller, gefolgt von der zweiten und der dritten.
Anmerkung:
Dies gilt für Browser, die die v8-Engine (Chrom/Chrom usw.) verwenden.
Mit Firefox (SpiderMonkey-Engine) sind die Ergebnisse völlig anders
Prüft selbst !! Firefox mit der dritten Lösung scheint zu sein
mehr als 4,5-mal schneller als Chrome mit der ersten Lösung ... verrückt: 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>
Der Test dauert 10 Sekunden (+ 2 Sekunden), wenn Sie auf die Schaltfläche klicken.
Meine Ergebnisse (auf demselben 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)
Nettes Durcheinander, was?
Hat sich erlaubt, weitere Testergebnisse hinzuzufügen
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)
@Gumbo zusätzliche Antwort hinzufügen - 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)