Heim > Web-Frontend > js-Tutorial > Lösung für das Nullzeichen, das entsteht, wenn JavaScript einen string_javascript-Tipp teilt

Lösung für das Nullzeichen, das entsteht, wenn JavaScript einen string_javascript-Tipp teilt

WBOY
Freigeben: 2016-05-16 16:35:13
Original
1641 Leute haben es durchsucht

Problembeschreibung

Einige leere Zeichenfolgen „“ erscheinen, wenn die Split-Methode von JavaScript zum Teilen einer Zeichenfolge verwendet wird, insbesondere wenn reguläre Ausdrücke als Trennzeichen verwendet werden.

Verwandte Fragen

Der reguläre Javascript-Ausdruck erzeugt beim Gruppieren von Zeichenfolgen eine leere Zeichenfolgengruppe?

Als der Betreff in der obigen Frage reguläre Ausdrücke zum Teilen der Zeichenfolge verwendete, wurden mehrere leere Zeichenfolgen „“ generiert. Der Code lautet wie folgt:

Code kopieren Der Code lautet wie folgt:

'张sdf四上法asdfwengfenaa33网s'.split(/([u4e00-u9fa5]{1})/gi);
//Ausgabe ["", "张", "sdf", "四", "", "上", "", "法", "asdf", "王", "", "fen", "aa33 ", "网", "s"]

Was ist also der Grund für diese leeren Zeichenfolgen?

Problemanalyse

Nachdem ich bei Google gesucht habe, habe ich festgestellt, dass es nicht viele verwandte Ergebnisse gibt, und selbst wenn, gibt es nicht viele detaillierte Erklärungen. Ich habe eine kurze Einführung gegeben und dann einen Link zur ECMAScript-Spezifikation angegeben. Es scheint, dass man, wenn man den wahren Grund wissen will, in den sauren Apfel beißen und die Vorschriften lesen muss.

Verwandte Standards

Als nächstes beginnen wir in Übereinstimmung mit der internationalen Praxis mit dem Standard-Rathaus von ECMAScript.

Code kopieren Der Code lautet wie folgt:

String.prototype.split (Trennzeichen, Grenze)

In diesem Kapitel werden die Ausführungsschritte der Split-Methode ausführlich beschrieben. Wenn Sie interessiert sind, können Sie die Schritte zum Generieren einer leeren Zeichenfolge hier nur erläutern. Jeder ist willkommen.

Verwandte Schritte

Einige Schritte extrahieren:

Der wichtigste Schritt im gesamten Prozess ist der Zyklus von Schritt 13, und die wichtigsten Dinge, die dieser Zyklus bewirkt, sind folgende:
•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). •Rufen Sie die SplitMatch(S, q, R)-Methode auf, um die Zeichenfolge zu teilen; •Entsprechend den unterschiedlichen zurückgegebenen Ergebnissen werden unterschiedliche Zweige ausgeführt, und der Hauptzweig ist Zweig ⅲ; •Zweig ⅲ ist in 8 kleine Schritte unterteilt, um die zurückgegebenen Ergebnisse in das vordefinierte Array A
zu füllen •In diesen 8 kleinen Schritten besteht die Funktion von Schritt 1 darin, einen Teilstring des ursprünglichen Strings zurückzugeben. Die Startposition ist p (einschließlich) und die Endposition ist q (nicht enthalten). Hinweis: In diesem Schritt handelt es sich um einen leeren String generiert, den ich zur leichteren Bezugnahme unten als abgeschnittene Zeichenfolge markiere.
•Fügen Sie den Teilstring aus dem vorherigen Schritt zu Array A
hinzu •Die nächsten Schritte bestehen darin, die relevanten Variablen zu aktualisieren und mit dem nächsten Zyklus fortzufahren. (Die Funktion von Schritt 7 besteht darin, die Capture-Gruppe im regulären Ausdruck in Array A zu speichern und hat nichts mit der Generierung einer leeren Zeichenfolge zu tun)

SplitMatch(S, q, R)

Als nächstes müssen wir verstehen, was die SplitMatch(S, q, R)-Methode bewirkt. Diese Methode wird weiter unten in der Split-Spezifikation erwähnt. Die Hauptaufgabe besteht darin, entsprechende Vorgänge je nach Trennzeichentyp auszuführen:
•Wenn das Trennzeichen vom Typ RegExp ist, rufen Sie die interne Methode [[Match]] auf, um die Zeichenfolge abzugleichen. Wenn die Übereinstimmung fehlschlägt, wird ein Fehler zurückgegeben.

•Wenn das Trennzeichen eine Zeichenfolge ist, wird die Übereinstimmung beurteilt, ein Fehler zurückgegeben und ein Ergebnis vom Typ MatchResult wird erfolgreich zurückgegeben.


MatchResult

Mit den obigen Schritten wird eine weitere Variable vom Typ MatchResult eingeführt. Bei der Überprüfung der Dokumentation haben wir festgestellt, dass dieser Variablentyp zwei Attribute hat: endIndex und Captures. Der Wert von endIndex ist die Zeichenfolge, die mit der Position plus 1 übereinstimmt. Captures können als Array verstanden werden, wenn das Trennzeichen ein regulärer Ausdruck ist darin ist der von der Gruppe erfasste Wert; wenn das Trennzeichen eine Zeichenfolge ist, ist es ein leeres Array.

Weiter

Aus den obigen Schritten können wir ersehen, dass die geteilte Zeichenfolge im Schritt des Abfangens der Zeichenfolge generiert wird (mit Ausnahme der Gruppenerfassung regulärer Ausdrücke). Seine Funktion besteht darin, die Zeichenfolge zwischen der angegebenen Startposition (einschließlich) und Endposition (nicht enthalten) abzufangen. Es gibt einen Sonderfall, bei dem die Werte der Startposition und der Endposition gleich sind. Dies ist nur eine Vermutung, da die Spezifikation keine Standardschritte zum Abfangen der Zeichenfolge vorsieht.

Wir sind so weit gekommen, warum nicht noch einen Schritt nach vorne machen?

Also habe ich versucht, etwas V8-Quellcode zu durchsuchen, um zu sehen, ob ich eine bestimmte Implementierungsmethode finden könnte. Ich habe den relevanten Code und den Quellcode-Link

gefunden

Hier ist ein Auszug aus einem davon:


Code kopieren Der Code lautet wie folgt:

Funktion StringSplitJS(separator, limit) {
...
...
//Wenn das Trennzeichen eine Zeichenfolge ist
if (!IS_REGEXP(separator)) {
var separator_string = TO_STRING_INLINE(separator);

if (limit === 0) return [];

// ECMA-262 besagt, dass das Ergebnis
sein sollte, wenn das Trennzeichen undefiniert ist // ein Array der Größe 1 sein, das die gesamte Zeichenfolge enthält.
If (IS_UNDEFINED(separator)) return [subject];

var Separator_Length = Separator_String.Length;

// Das Trennzeichen ist eine leere Zeichenfolge und das Zeichenarray wird direkt zurückgegeben
If (separator_length === 0) return %StringToArray(subject, limit);

var result = %StringSplit(subject, separator_string, limit);

Ergebnis zurückgeben;
}

if (limit === 0) return [];

// Wenn das Trennzeichen ein regulärer Ausdruck ist, rufen Sie StringSplitOnRegExp
auf Rückgabe StringSplitOnRegExp(subjekt, trennzeichen, grenze, länge);
}

//Lassen Sie hier einige Codes weg

Ich habe im Code festgestellt, dass die Methode %_SubString aufgerufen wird, um die Zeichenfolge beim Füllen des Arrays abzufangen. Wenn Sie sie finden, lassen Sie es mich bitte wissen. Ich habe jedoch festgestellt, dass die StringSubstring-Methode, die der Teilstring-Methode in JavaScript entspricht, die %_SubString-Methode aufruft und das Ergebnis zurückgibt. Wenn 'abc'.substring(1,1) dann „“ zurückgibt, bedeutet dies, dass die %_SubString-Methode „“ zurückgibt, wenn die Startposition und die Endposition identisch sind. Sie werden das Ergebnis kennen, nachdem Sie es ausprobiert haben.

Wann ist also die Startposition gleich der Endposition (d. h. q === p)? Ich habe Schritt für Schritt gemäß den oben genannten Schritten analysiert und schließlich Folgendes gefunden:
•Nachdem die ursprüngliche Zeichenfolge S einmal mit dem Trennzeichen übereinstimmt, stimmt auch die nächste Position der Zeichenfolge S mit dem Trennzeichen überein. Zum Beispiel: 'abbbc'.split('b'), 'abbbc'.split(/(b){1}/)
•Eine andere Situation liegt vor, wenn ein oder mehrere Zeichen am Anfang der Zeichenfolge mit dem Trennzeichen übereinstimmen. Zum Beispiel: 'abc'.split('a'), 'abc'.split(/ab/)
•Es gibt auch den Fall, dass eine oder mehrere Zeichenfolgen am Ende der Zeichenfolge mit dem Trennzeichen übereinstimmen und der entsprechende Schritt Schritt 14 ist.
Zum Beispiel: 'abc'.split('c'), 'abc'.split(/bc/)

Außerdem kann bei der Verwendung regulärer Ausdrücke als Trennzeichen undefiniert in den zurückgegebenen Ergebnissen erscheinen.
Zum Beispiel: 'abc'.split(/(d)*/)

Gehen Sie zurück und schauen Sie sich das Beispiel am Anfang an. Erfüllt es die oben genannten Bedingungen?

Exkurs

Dies ist das erste Mal, dass ich die ECMAScript-Standardspezifikation so sorgfältig gelesen habe. Der Prozess des Lesens ist zwar schmerzhaft, aber nachdem ich sie verstanden habe, bin ich sehr glücklich. Vielen Dank auch an den Fragesteller, der diese Frage gestellt und weiterverfolgt hat.
Wenn ein regulärer Ausdruck als Trennzeichen verwendet wird, wird übrigens der globale Modifikator g ignoriert, was einen zusätzlichen Vorteil darstellt.

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage