Wie kann ich Unicode-fähige reguläre Ausdrücke in JavaScript verwenden?
Zum Beispiel sollte es etwas Ähnliches geben, \w
das mit jedem Codepunkt in der Kategorie Buchstaben oder Markierungen (nicht nur mit den ASCII-Buchstaben) übereinstimmen kann und hoffentlich Filter wie [[P *]] für Interpunktion usw. enthält.
javascript
regex
unicode
character-properties
Peter Mortensen
quelle
quelle
Antworten:
Situation für ES 6
Die kommende ECMAScript-Sprachspezifikation, Ausgabe 6, enthält Unicode-fähige reguläre Ausdrücke. Die Unterstützung muss mit dem
u
Modifikator in der Regex aktiviert werden . Siehe Unicode-fähige reguläre Ausdrücke in ES6 .Bis ES 6 fertig ist und von den Browser-Anbietern weit verbreitet ist, sind Sie jedoch immer noch auf sich allein gestellt. Update: Es gibt jetzt einen Transpiler namens regexpu , der reguläre ES6-Unicode-Ausdrücke in äquivalente ES5 übersetzt. Es kann als Teil Ihres Erstellungsprozesses verwendet werden.Probieren Sie es online aus.
Situation für ES 5 und darunter
Obwohl JavaScript mit Unicode-Zeichenfolgen arbeitet, implementiert es keine Unicode-fähigen Zeichenklassen und hat kein Konzept für POSIX-Zeichenklassen oder Unicode-Blöcke / -Unterbereiche.
Probleme mit Unicode in regulären JavaScript-Ausdrücken
Überprüfen Sie hier Ihre Erwartungen: Javascript RegExp Unicode Character Class-Tester ( Bearbeiten: Die Originalseite ist nicht verfügbar, das Internetarchiv verfügt noch über eine Kopie .)
Flagrant Badassery hat einen Artikel über JavaScript, Regex und Unicode , der etwas Licht in die Sache bringt .
Lesen Sie auch Regex und Unicode hier auf SO. Wahrscheinlich müssen Sie Ihre eigene "Interpunktionszeichenklasse" erstellen.
Schauen Sie sich den Builder " Regulärer Ausdruck: Match Unicode Block Range" an , mit dem Sie einen regulären JavaScript-Ausdruck erstellen können, der Zeichen entspricht, die in eine beliebige Anzahl angegebener Unicode-Blöcke fallen.
Ich habe es gerade für die Unterbereiche "Allgemeine Interpunktion" und "Ergänzende Interpunktion" gemacht, und das Ergebnis ist so einfach und unkompliziert, wie ich es erwartet hätte:
Es gibt auch XRegExp , ein Projekt, das Unicode-Unterstützung für JavaScript bietet, indem es eine alternative Regex-Engine mit erweiterten Funktionen bietet.
Und natürlich muss gelesen werden: mathiasbynens.be - JavaScript hat ein Unicode-Problem :
quelle
u
Flagge sowie einige andere ES6 verfügt für mit Unicode arbeiten.u
regulären Ausdrücke zu transpilieren ."a品cd!e f".replace(/[^\w]/ug, "")
und aber die resultierende Regex (in Chrome 59 ausgeführt) entfernt immer noch den品
Charakter und kehrt nur zurück"acdef"
Persönlich würde ich lieber keine andere Bibliothek installieren, nur um diese Funktionalität zu erhalten. Meine Antwort erfordert keine externen Bibliotheken und kann neben JavaScript auch mit geringen Änderungen für Regex-Aromen funktionieren.
Die Unicode- Website bietet eine Möglichkeit, Unicode-Kategorien in eine Reihe von Codepunkten zu übersetzen. Da ist es Unicode -Website handelt, sollten die Informationen korrekt sein.
Beachten Sie, dass Sie die High-End-Zeichen ausschließen müssen, da JavaScript nur Zeichen verarbeiten kann, die kleiner als sind
FFFF
(hex) sind. Ich schlage vor, die Kontrollkästchen Abbreviate Collate und Escape zu aktivieren, um ein Gleichgewicht zwischen der Vermeidung nicht druckbarer Zeichen und der Minimierung der Größe des regulären Ausdrucks herzustellen.Hier sind einige gängige Erweiterungen verschiedener Unicode-Eigenschaften:
\p{L}
(Briefe):\p{Nd}
(Dezimalstellen):\p{P}
(Interpunktion):Die Seite erkennt auch eine Reihe von obskuren Zeichenklassen, wie z. B.
\p{Hira}
die (japanischen) Hiragana-Zeichen:Schließlich ist es möglich, eine char-Klasse mit mehr als einer Unicode-Eigenschaft zu verbinden, um eine kürzere Regex zu erhalten, als wenn Sie sie nur kombinieren würden (sofern bestimmte Einstellungen aktiviert sind).
quelle
\p
-Syntax scheint nicht in JS zu funktionieren,/\p{L}/.test('a')
istfalse
Nachdem ich auch keine gute Lösung gefunden hatte, schrieb ich vor langer Zeit ein kleines Skript , indem ich Daten aus der Unicode- Spezifikation (v.5.0.0) herunterlud und Intervalle für jede Unicode-Kategorie und Unterkategorie im BMP generierte (kürzlich durch ein kleines ersetzt) Java-Programm , das seine eigene native Unicode-Unterstützung verwendet).
Grundsätzlich wird es
\p{...}
in einen Wertebereich konvertiert , ähnlich wie die Ausgabe des Werkzeugs von Tomalak erwähnt, aber die Intervalle recht groß am Ende (da es nicht mit Blöcken zu tun, sondern mit Zeichen durch viele verschiedene Orte verstreut).Zum Beispiel ein Regex, der so geschrieben ist:
Wird in so etwas umgewandelt:
Ich habe es in der Praxis nicht oft benutzt, aber es scheint nach meinen Tests gut zu funktionieren, also poste ich hier, falls jemand es nützlich findet. Trotz der Länge der resultierenden regulären Ausdrücke (das obige Beispiel hat 3591 Zeichen, wenn es erweitert wird) scheint die Leistung akzeptabel zu sein (siehe die Tests bei jsFiddle; danke an @modiX und @Lwangaman für die Verbesserungen).
Hier ist die Quelle (roh, 27,5 KB; minimiert , 24,9 KB, nicht viel besser ...). Es könnte sein durch URL - Kodierung , die Unicode - Zeichen kleiner gemacht werden, aber OTOH das Risiko der Codierung Probleme laufen, so verlasse ich , wie es ist. Hoffentlich wird so etwas mit ES6 nicht mehr nötig sein.
Update : Dies sieht aus wie die gleiche Strategie, die im von Tim Down erwähnten XRegExp Unicode-Plug-In angewendet wurde , außer dass in diesem Fall reguläre JavaScript-Regexes verwendet werden.
quelle
/^\p{L}+$/
sollten übereinstimmen ,東海林
aber es funktioniert nicht. Wann immer Sie die Sammlung aktualisieren, informieren Sie mich bitte. Vielen Dank.\p{Lo}
, vermissen Sie die beiden Kanji-Tabellen darin.Wie in anderen Antworten erwähnt, unterstützen JavaScript-Regexes keine Unicode-Zeichenklassen. Es gibt jedoch eine Bibliothek, die dies bietet: Steven Levithans exzellentes XRegExp und sein Unicode-Plug-In .
quelle
[^\u0000-\u007F]+
für alle Zeichen, die keine ASCII-Zeichen enthalten.Beispielsweise:
Hier sind einige perfekte Referenzen:
RegExp-Generator für den Unicode-Bereich
Reguläre Unicode-Ausdrücke
Unicode 10.0-Zeichencodetabellen
Match Unicode Block Range
quelle
September 2018 (aktualisiert Februar 2019)
Es scheint, dass regulärer Ausdruck
/\p{L}/u
für übereinstimmende Buchstaben (als Unicode-Kategorien )Hier ist ein Arbeitsbeispiel
Ich melde diesen Fehler hier .
Aktualisieren
Nach über 2 Jahren laut: 1500035 > 1361876 > 1634135 ist dieser Fehler endlich behoben und wird in Firefox v.78 + verfügbar sein
quelle
Dies wird es tun:
Es wird explizit ein Bereich von Unicode-Zeichen ausgewählt. Es funktioniert für lateinische Zeichen, aber andere seltsame Zeichen können außerhalb dieses Bereichs liegen.
quelle
\u0100
und\u0280
: Viele davon können als lateinische Zeichen betrachtet werden, andere nicht: var s = ''; für (var i = 0xff; i <= 0x280; i ++) {s + = String.fromCharCode (i)} "AvāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏ ... ǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀ"In JavaScript sind \ w und \ d ASCII, während \ s Unicode ist. Frag mich nicht warum. JavaScript unterstützt \ p mit Unicode-Kategorien, mit denen Sie Unicode-fähige \ w und \ d emulieren können.
Verwenden Sie für \ d \ p {N} (Zahlen)
Verwenden Sie für \ w [\ p {L} \ p {N} \ p {Pc} \ p {M}] (Buchstaben, Zahlen, Unterstriche, Markierungen)
Update: Leider habe ich mich geirrt. JavaScript unterstützt \ p auch offiziell nicht, obwohl einige Implementierungen dies möglicherweise noch unterstützen. Die einzige Unicode-Unterstützung in JavaScript-Regexen besteht darin, bestimmte Codepunkte mit \ uFFFF abzugleichen. Sie können diese in Bereichen in Zeichenklassen verwenden.
quelle
/\p{L}+/u
Wenn Sie Babel verwenden, wird Unicode unterstützt bereits verfügbar.
Ich habe auch ein Plugin veröffentlicht, das Ihren Quellcode so transformiert, dass Sie reguläre Ausdrücke wie schreiben können
/^\p{L}+$/
. Diese werden dann in etwas umgewandelt, das Browser verstehen.Hier ist die Projektseite des Plugins:
babel-plugin-utf-8-regex
quelle
Ich beantworte diese Frage
Was wäre das Äquivalent für \ p {Lu} oder \ p {Ll} in regExp für js?
da es als genaues Duplikat der aktuellen alten Frage markiert wurde.
Abfragen der UCD-Datenbank von Unicode 12 generiert \ p {Lu} 1.788 Codepunkte.
Die Konvertierung in UTF-16 ergibt die Klassenkonstruktäquivalenz.
Es ist nur eine 4k-Zeichenfolge und kann problemlos in Regex-Engines ausgeführt werden.
Beim Abfragen der UCD-Datenbank von Unicode 12 generiert \ p {Ll} 2.151 Codepunkte.
Die Konvertierung in UTF-16 ergibt die Klassenkonstruktäquivalenz.
Beachten Sie, dass eine Regex-Implementierung von \ p {Lu} oder \ p {Pl} tatsächlich a aufruft
nicht standardmäßige Funktion , um den Wert zu testen.
Die hier gezeigten Zeichenklassen werden unterschiedlich ausgeführt und sind linear, normal
und ziemlich langsam, wenn sie größtenteils in einer einzelnen Klasse zusammengefasst sind.
Einige Einblicke, wie eine Regex-Engine (im Allgemeinen) Unicode-Eigenschaftsklassen implementiert:
Untersuchen Sie diese Leistungsmerkmale zwischen der Eigenschaft
und dem Klassenblock (wie oben).
Wow was für ein Unterschied !!
Mal sehen, wie Eigenschaften implementiert werden könnten
Array von Zeigern [10FFFF], wobei jeder Index ein Codepunkt ist
Jeder Zeiger im Array verweist auf eine Klassifizierungsstruktur.
Eine Klassifizierungsstruktur enthält feste Feldelemente.
Einige sind NULL und gehören nicht dazu.
Einige enthalten Kategorienklassifikationen.
Beispiel: Allgemeine Kategorie
Dies ist ein Bitmap-Element, das 17 von 64 Bit verwendet.
Was auch immer dieser Codepunkt unterstützt, Bit (s) sind als Maske gesetzt.
-Close_Punctuation
-Connector_Punctuation
-Kontrolle
-Currency_Symbol
-Dash_Punctuation
-Decimal_Number
-Enclosing_Mark
-Final_Punctuation
-Format
-Initial_Punctuation
-Letter_Number
-Line_Separator
-Lowercase_Letter
-Math_Symbol
-Modifier_Letter
-Modifier_Symbol
-Nonspacing_Mark
-Open_Punctuation
-Other_Letter
-Other_Number
-Other_Punctuation
-Other_Symbol
-Paragraph_Separator
-Private_Use
-Space_Separator -Surrogat
-Spacing_Mark
-Titlecase_Letter
-Unassigned
-Uppercase_Letter
Wenn eine Regex mit so etwas wie \ p {Lu} analysiert wird,
wird sie direkt in übersetzt
Ein weiteres Beispiel: Wenn ein regulärer Ausdruck mit der Interpunktionseigenschaft \ p {P} analysiert wird,
wird er in übersetzt
Eine Überprüfung dieses Elements auf eines dieser Elementbits, die zu einer Maske verbunden sind:
-Close_Punctuation
-Connector_Punctuation
-Dash_Punctuation
-Final_Punctuation
-Initial_Punctuation
-Open_Punctuation
-Other_Punctuation
Der Offset und das Bit oder Bit (Maske) werden als Regex-Schritt für diese Eigenschaft gespeichert.
Die Nachschlagetabelle wird einmal für alle Unicode-Codepunkte mit diesem Array erstellt.
Wenn ein Zeichen überprüft wird, ist es so einfach, den CP als Index für dieses Array zu verwenden und das spezifische Element der Klassifizierungsstruktur für dieses Bit (Maske) zu überprüfen.
Diese Struktur ist erweiterbar und indirekt, um viel komplexere Suchvorgänge zu ermöglichen. Dies ist nur ein einfaches Beispiel.
Vergleichen Sie diese direkte Suche mit einer Zeichenklassensuche:
Alle Klassen sind eine lineare Liste von Elementen, die von links nach rechts durchsucht werden.
Da unsere Zielzeichenfolge in diesem Vergleich nur die vollständigen Unicode-Buchstaben in Großbuchstaben enthält, würde das Gesetz der Durchschnittswerte vorhersagen, dass die Hälfte der Elemente in der Klasse im Bereich überprüft werden müsste, um eine Übereinstimmung zu finden.
Dies ist ein großer Leistungsnachteil.
Wenn die Nachschlagetabellen jedoch nicht vorhanden sind oder nicht mit der neuesten Unicode-Version (12 ab diesem Datum) auf dem neuesten Stand sind, ist dies
der einzige Weg.
Tatsächlich ist dies meistens die einzige Möglichkeit, die vollständigen Emoji-
Zeichen zu erhalten, da ihre Zuordnung keine bestimmte Eigenschaft (oder Begründung) enthält.
quelle
Sie können auch verwenden:
quelle