Problembeschreibung
Eine leere Zeichenfolge "" wird angezeigt, wenn eine Zeichenfolge mithilfe der Split -Methode von JavaScript geteilt wird, insbesondere bei der Verwendung regulärer Ausdrücke als Grenzwerte.
Verwandte Fragen
JavaScript reguläre Ausdrücke erzeugen beim Gruppieren von Zeichenfolgen eine leere String -Gruppe?
In der obigen Frage verwendete der Fragesteller den regulären Ausdruck, um die Zeichenfolge zu teilen, und erzeugte mehrere leere Zeichenfolgen "" und der Code lautet wie folgt:
Die Codekopie lautet wie folgt:
'Zhang SDF Four Methoden Asdf Wengf aa33net S'Ssplit (/([/u4e00-/u9fa5] {1})/gi);
// Ausgabe ["", "Zhang", "SDF", "Four", "Up", "", "Law", "Asdf", "Weng", "", "," Fen "," Aa33 "," Net "," S "]
Was ist der Grund für diese leeren Saiten?
Problemanalyse
Nachdem ich bei Google gesucht hatte, stellte ich fest, dass es nicht viele verwandte Ergebnisse gab. Selbst wenn es gäbe, gab es nicht viele detaillierte Erklärungen. Ich sagte es grob und gab dann einen Link zur ECMAScript -Spezifikation. Wenn Sie den wahren Grund kennen möchten, können Sie nur die Kugel beißen und die Normen betrachten.
Verwandte Standards
Gehen Sie dann laut internationaler Praxis zuerst in das Standard -Stadtgebäude von ECMascript.
Die Codekopie lautet wie folgt:
String.Prototype.split (Separator, Grenze)
In diesem Kapitel werden die Ausführungsschritte der Split -Methode im Detail vorgestellt. Wenn Sie interessiert sind, können Sie es Schritt für Schritt sorgfältig lesen. Ich werde nur die Schritte im Zusammenhang mit der Erzeugung leerer Saiten hier erklären. Wenn es unangemessene Punkte gibt, ist jeder willkommen, sie zu erwähnen.
Verwandte Schritte
Teilweise zu extrahieren:
Der wichtigste Schritt im gesamten Prozess ist der 13. Zyklus, und die wichtigsten Dinge, die dieser Zyklus bewirkt, sind wie folgt:
• Definieren Sie die Werte von p und q. Die Werte von p und q sind zu Beginn jeder Schleife gleich (dieser Schritt liegt außerhalb der Schleife);
• Aufrufen von SplitMatch (s, q, r) Methode, um die Zeichenfolge zu teilen;
• Führen Sie verschiedene Zweige gemäß den zurückgegebenen Ergebnissen aus, und die Hauptzweige sind Zweige.
• Der Zweig ist in 8 kleine Schritte unterteilt, um das zurückgegebene Ergebnis in das vordefinierte Array a zu füllen
• In diesen 8 kleinen Schritten besteht der Zweck von Schritt 1 darin, eine Substring der ursprünglichen Zeichenfolge zurückzugeben, die Startposition P (enthalten) und die Endposition q (enthalten). HINWEIS: In diesem Schritt wird eine leere Zeichenfolge erzeugt, und ich habe sie als Abfangen der Zeichenfolge markiert, um unten zu zitieren.
• Fügen Sie das Substring aus dem vorherigen Schritt zum Array A hinzu
• In den nächsten Schritten werden die relevanten Variablen aktualisiert und die nächste Schleife fortgesetzt. (Der Zweck von Schritt 7 besteht darin, die Erfassungsgruppierung im regulären Ausdruck in Array A zu speichern, was nichts mit der Erzeugung einer leeren Zeichenfolge zu tun hat)
SplitMatch (s, q, r)
Als nächstes müssen wir verstehen, was die Methode der SplitMatch (S, Q, R) tut. Diese Methode wird unten in der Split -Spezifikation erwähnt. Was es hauptsächlich tut, ist, entsprechende Operationen entsprechend der Art des Separators durchzuführen:
• Wenn der Trennzeichen vom Typ regexp vom Typ ist, rufen Sie die interne Methode von Regexp auf, um mit der Zeichenfolge übereinzustimmen. Wenn das Match fehlschlägt, geben Sie den Fehler zurück. Andernfalls geben Sie ein MatchResult -Ergebnis zurück.
• Wenn der Trennzeichen eine Zeichenfolge ist, wird das Übereinstimmungsurteil durchgeführt, das Versagen wird zurückgegeben und ein Ergebnis des MatchResult -Typs wird erfolgreich zurückgegeben.
MatchResult
In den obigen Schritten wird eine Variable des Typs MatchResult eingeführt. Durch die Suche nach dem Dokument wurde festgestellt, dass Variablen dieses Typs zwei Attribute EndIndex und Erfassungen haben. Der Wert von EndIndex ist die Position, die mit der Zeichenfolge plus 1 entspricht. Erfassungen können als Array verstanden werden. Wenn der Trennzeichen ein regulärer Ausdruck ist, sind die Elemente darin die Werte, die von der Gruppe erfasst wurden. Wenn der Trennzeichen eine Zeichenfolge ist, handelt es sich um ein leeres Array.
Nächste
Aus den obigen Schritten können wir sehen, dass die geteilte Zeichenfolge im Schritt der Abfangen der Zeichenfolge erzeugt wird (mit Ausnahme der Gruppenaufnahme regulärer Ausdrücke). Seine Funktion besteht darin, die Zeichenfolge zwischen dem angegebenen Start (enthalten) und der Endposition (enthalten) abzufangen. Wann wird er "" zurückgegeben? Es gibt einen Sonderfall, in dem die Werte der Startposition und die Endposition gleich sind, was nur eine Vermutung ist, da die Spezifikation nicht die Spezifikationsschritte zum Abfangen der Zeichenfolge angibt.
Wir sind alle hierher gekommen, warum nicht einen Schritt nach vorne machen?
Ich habe also versucht, nach einem V8 -Quellcode zu suchen, um festzustellen, ob ich eine bestimmte Implementierungsmethode finden könnte. Ich habe den relevanten Code, den Quellcode -Link gefunden, gefunden
Hier sind einige von ihnen:
Die Codekopie lautet wie folgt:
Funktion Stringsplitjs (Separator, Limit) {
...
...
// Der Trennzeichen ist eine Zeichenfolge
if (! is_regexp (separator)) {
var separator_string = to_string_inline (separator);
if (limit === 0) return [];
// ECMA-262 sagt, dass das Ergebnis, wenn der Trennzeichen undefiniert ist, das Ergebnis
// Seien Sie ein Array der Größe 1, das die gesamte Zeichenfolge enthält.
if (is_undefined (Separator)) return [Subjekt];
var separator_length = separator_string.length;
// Das Trennzeichen ist eine leere Zeichenfolge, die das Zeichenarray direkt zurückgibt
if (separator_length === 0) return %StringToArray (Subjekt, Limit);
var result = %Stringsplit (Subjekt, separator_string, limit);
Rückgabeergebnis;
}
if (limit === 0) return [];
// Wenn der Trennzeichen ein regelmäßiger Ausdruck ist, rufen Sie Stringsplitonregexp auf
return stringsplitonregexp (Subjekt, Trennzeichen, Grenze, Länge);
}
// Hier werden mehrere Codes weggelassen
Ich habe in dem Code festgestellt, dass beim Ausfüllen des Arrays die %_Substring -Methode aufgerufen wird, um die Zeichenfolge abzufangen. Leider fand ich seine relevante Definition nicht. Wenn es Schüler gibt, die es gefunden haben, lassen Sie es mich bitte wissen. Ich stellte jedoch fest, dass die Stringsubstring -Methode, die der Substring -Methode in JavaScript entspricht, die %_substring -Methode aufruft und das Ergebnis zurückgibt. Wenn dann 'ABC'.Substring (1,1) zurückgibt, bedeutet dies, dass die %_Substring -Methode zurückgibt "", wenn die Startposition und die Endposition gleich sind. Sie können das Ergebnis erkennen, indem Sie es versuchen.
Wann tritt die Startposition gleich der Endposition (d. H. Q === P) auf? Ich folgte Schritt für Schritt den obigen Schritten und fand schließlich:
• Wenn die ursprüngliche Zeichenfolge S mit dem Trennzeichen einmal danach übereinstimmt, stimmt die nächste Position der String S auch mit dem Trennzeichen überein. Zum Beispiel: 'abbbc'.split (' b '),' abbbc'.split (/(b) {1}/)
• Ein weiterer Fall ist, dass ein oder mehrere Zeichen am Anfang einer Zeichenfolge mit dem Separator übereinstimmen. Zum Beispiel: 'abc'.split (' a '),' abc'.split (/ab/)
• Es gibt einen anderen Fall, in dem ein oder mehrere Zeichenfolgen am Ende der Zeichenfolge mit dem Trennzeichen übereinstimmen, und der entsprechende Schritt ist Schritt 14.
Zum Beispiel: 'abc'.split (' c '),' abc'.split (/bc/)
Bei der Verwendung regulärer Ausdrücke als Grenzwerte kann undefined im zurückgegebenen Ergebnis möglicherweise nicht festgelegt.
Zum Beispiel: 'abc'.split (/(d)*/)
Schauen wir uns das Beispiel am Anfang an. Befriedigt es die oben genannten Situationen?
Off -Thema
Dies ist das erste Mal, dass ich die Standardspezifikationen von ECMascript so sorgfältig gelesen habe. Der Prozess des Lesens ist in der Tat sehr schmerzhaft, aber nachdem ich es verstanden habe, fühle ich mich sehr glücklich. Vielen Dank für diese Frage und die Follow-up-Frage.
Wenn ein regulärer Ausdruck als Trennzeichen verwendet wird, wird übrigens der globale Modifikator G ignoriert, was ebenfalls ein zusätzlicher Gewinn darstellt.