Comment puis-je utiliser des expressions régulières compatibles Unicode en JavaScript?
Par exemple, il devrait y avoir quelque chose de semblable \w
qui puisse correspondre à n'importe quel point de code dans la catégorie Lettres ou Marques (pas seulement celles ASCII), et espérons-le avoir des filtres comme [[P *]] pour la ponctuation, etc.
javascript
regex
unicode
character-properties
Peter Mortensen
la source
la source
Réponses:
Situation pour ES 6
La prochaine spécification du langage ECMAScript, édition 6, inclut des expressions régulières compatibles Unicode. Le support doit être activé avec le
u
modificateur sur l'expression régulière. Voir Expressions régulières compatibles Unicode dans ES6 .Jusqu'à ce que ES 6 soit terminé et largement adopté par les fournisseurs de navigateurs, vous êtes toujours seul. Mise à jour: il existe désormais un transpileur nommé regexpu qui traduit les expressions régulières Unicode ES6 en ES5 équivalent. Il peut être utilisé dans le cadre de votre processus de génération. Essayez-le en ligne.
Situation pour ES 5 et moins
Même si JavaScript fonctionne sur les chaînes Unicode, il n'implémente pas de classes de caractères compatibles Unicode et n'a aucun concept de classes de caractères POSIX ou de blocs / sous-plages Unicode.
Problèmes avec Unicode dans les expressions régulières JavaScript
Vérifiez vos attentes ici: Javascript RegExp Unicode Character Class tester ( Edit: la page d'origine est en bas, Internet Archive en a toujours une copie .)
Flagrant Badassery a un article sur JavaScript, Regex et Unicode qui éclaire la question.
Lisez également Regex et Unicode ici sur SO. Vous devez probablement créer votre propre "classe de caractères de ponctuation".
Consultez le générateur Expression régulière: correspondre à la plage de blocs Unicode , qui vous permet de créer une expression régulière JavaScript qui correspond aux caractères qui se trouvent dans un nombre quelconque de blocs Unicode spécifiés.
Je viens de le faire pour les sous-plages "Ponctuation générale" et "Ponctuation supplémentaire", et le résultat est aussi simple et direct que je l'aurais cru:
Il existe également XRegExp , un projet qui apporte la prise en charge Unicode à JavaScript en offrant un moteur regex alternatif avec des capacités étendues.
Et bien sûr, lecture obligatoire: mathiasbynens.be - JavaScript a un problème Unicode :
la source
u
drapeau ainsi que d'autres ES6 caractéristiques pour travailler avec Unicode.u
expressions régulières."a品cd!e f".replace(/[^\w]/ug, "")
et mais l'expression régulière résultante (exécutée dans Chrome 59) supprime toujours le品
personnage et ne revient que"acdef"
Personnellement, je préfère ne pas installer une autre bibliothèque juste pour obtenir cette fonctionnalité. Ma réponse ne nécessite aucune bibliothèque externe, et elle peut également fonctionner avec peu de modifications pour les saveurs regex en plus de JavaScript.
Le site Web d'Unicode fournit un moyen de traduire les catégories Unicode en un ensemble de points de code. Comme il s'agit du site Web d' Unicode , les informations qu'il contient doivent être exactes.
Notez que vous devrez exclure les caractères haut de gamme, car JavaScript ne peut gérer que les caractères inférieurs à
FFFF
(hex). Je suggère de cocher les cases Abbreviate Collate et Escape, qui établissent un équilibre entre éviter les caractères non imprimables et minimiser la taille de l'expression régulière.Voici quelques extensions courantes de différentes propriétés Unicode:
\p{L}
(Des lettres):\p{Nd}
(Nombre de chiffres décimaux):\p{P}
(Ponctuation):La page reconnaît également un certain nombre de classes de caractères obscures, telles que
\p{Hira}
, qui ne sont que les caractères Hiragana (japonais):Enfin, il est possible de brancher une classe char avec plus d'une propriété Unicode pour obtenir une expression rationnelle plus courte que celle que vous obtiendriez en les combinant simplement (tant que certains paramètres sont vérifiés).
la source
\p
-Syntax ne semble pas fonctionner dans JS,/\p{L}/.test('a')
estfalse
N'ayant pas non plus trouvé de bonne solution, j'ai écrit un petit script il y a longtemps, en téléchargeant des données à partir de la spécification unicode (v.5.0.0) et en générant des intervalles pour chaque catégorie et sous-catégorie unicode dans le BMP (récemment remplacé par un petit Programme Java qui utilise son propre support Unicode natif).
Fondamentalement, il se convertit
\p{...}
en une plage de valeurs, un peu comme la sortie de l' outil mentionné par Tomalak, mais les intervalles peuvent finir par être assez grands (car il ne s'agit pas de blocs, mais de caractères dispersés à travers de nombreux endroits différents).Par exemple, une Regex écrite comme ceci:
Sera converti en quelque chose comme ceci:
Je ne l'ai pas beaucoup utilisé dans la pratique, mais cela semble bien fonctionner de mes tests, donc je poste ici au cas où quelqu'un le trouverait utile. Malgré la longueur des expressions rationnelles résultantes (l'exemple ci-dessus a 3591 caractères lorsqu'il est développé), les performances semblent être acceptables (voir les tests sur jsFiddle; merci à @modiX et @Lwangaman pour les améliorations).
Voici la source de (cru, 27.5KB; minifiés , 24.9KB, pas beaucoup mieux ...). Il pourrait être réduit en déséchappant les caractères unicode, mais OTOH courra le risque de problèmes de codage, donc je laisse tel quel. Espérons qu'avec ES6, ce genre de chose ne sera plus nécessaire.
Mise à jour : cela ressemble à la même stratégie adoptée dans le plug-in XRegExp Unicode mentionné par Tim Down, sauf que dans ce cas, des expressions régulières JavaScript sont utilisées.
la source
/^\p{L}+$/
devrait donc correspondre,東海林
mais ce n'est pas le cas. Chaque fois que vous mettez à jour la collection, veuillez m'en informer. Merci beaucoup.\p{Lo}
, vous manquez les deux tables Kanji.Comme mentionné dans d'autres réponses, les expressions rationnelles JavaScript ne prennent pas en charge les classes de caractères Unicode. Cependant, il existe une bibliothèque qui fournit cela: l'excellent XRegExp de Steven Levithan et son plug-in Unicode .
la source
[^\u0000-\u007F]+
pour tous les caractères qui ne sont pas inclus des caractères ASCII.Par exemple:
Voici quelques références parfaites:
Générateur RegExp gamme Unicode
Expressions régulières Unicode
Tableaux des codes de caractères Unicode 10.0
Faire correspondre la plage de blocs Unicode
la source
Septembre 2018 (mis à jour en février 2019)
Il semble que l'expression rationnelle
/\p{L}/u
pour les lettres de correspondance (en tant que catégories unicode )Voici un exemple de travail
Je signale ce bug ici .
Mettre à jour
Après plus de 2 ans selon: 1500035 > 1361876 > 1634135 enfin ce bug est corrigé et sera disponible dans Firefox v.78 +
la source
Cela le fera:
Il sélectionne explicitement une plage de caractères Unicode. Cela fonctionnera pour les caractères latins, mais d'autres caractères étranges peuvent être hors de cette plage.
la source
\u0100
et\u0280
: beaucoup de ceux-ci peuvent être considérés comme des caractères latins mais d'autres pas: var s = ''; pour (var i = 0xff; i <= 0x280; i ++) {s + = String.fromCharCode (i)} "ÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏ ... ǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀ"En JavaScript, \ w et \ d sont ASCII, tandis que \ s est Unicode. Ne me demandez pas pourquoi. JavaScript prend en charge \ p avec les catégories Unicode, que vous pouvez utiliser pour émuler un \ w et \ d prenant en charge Unicode.
Pour \ d, utilisez \ p {N} (nombres)
Pour \ w, utilisez [\ p {L} \ p {N} \ p {Pc} \ p {M}] (lettres, chiffres, traits de soulignement, marques)
Mise à jour: Malheureusement, je me trompais à ce sujet. JavaScript ne prend pas non plus officiellement en charge \ p, bien que certaines implémentations puissent toujours le prendre en charge. La seule prise en charge Unicode dans les expressions régulières JavaScript correspond à des points de code spécifiques avec \ uFFFF. Vous pouvez les utiliser dans des plages de classes de caractères.
la source
/\p{L}+/u
Si vous utilisez Babel alors le support Unicode est déjà disponible.
J'ai également publié un plugin qui transforme votre code source afin que vous puissiez écrire des expressions régulières comme
/^\p{L}+$/
. Ceux-ci seront ensuite transformés en quelque chose que les navigateurs comprennent.Voici la page projet du plugin:
babel-plugin-utf-8-regex
la source
Je réponds à cette question
Quel serait l'équivalent pour \ p {Lu} ou \ p {Ll} dans regExp pour js?
car il a été marqué comme un double exact de l'ancienne question actuelle.
En interrogeant la base de données UCD d'Unicode 12, \ p {Lu} génère 1 788 points de code.
La conversion en UTF-16 donne l'équivalence de construction de classe.
Ce n'est qu'une chaîne de caractères de 4k et est facilement réalisable dans tous les moteurs d'expression régulière.
L'interrogation de la base de données UCD d'Unicode 12, \ p {Ll} génère 2 151 points de code.
La conversion en UTF-16 donne l'équivalence de construction de classe.
Notez qu'une implémentation regex de \ p {Lu} ou \ p {Pl} appelle en fait une
fonction non standard pour tester la valeur.
Les classes de personnages présentées ici sont faites différemment et sont linéaires, standard
et assez lentes, lorsqu'elles sont principalement regroupées en une seule classe.
Quelques informations sur la façon dont un moteur Regex (en général) implémente les classes de propriétés Unicode:
Examiner ces caractéristiques de performances entre la propriété
et le bloc de classe (comme ci-dessus)
Wow quelle différence !!
Permet de voir comment les propriétés peuvent être implémentées
Tableau de pointeurs [10FFFF] où chaque index est un point de code
Chaque pointeur du tableau correspond à une structure de classification.
Une structure de classification contient des élémets de champ fixe.
Certains sont NULS et ne s'appliquent pas.
Certains contiennent des classifications de catégorie.
Exemple: catégorie générale
Il s'agit d'un élément bitmap qui utilise 17 bits sur 64.
Tout ce que ce point de code prend en charge a des bits définis comme masque.
-Close_Punctuation
-Connector_Punctuation
-Control
-Currency_Symbol
-Dash_Punctuation
-Decimal_Number
-Enclosing_Mark
-Final_Punctuation
-Formater
-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
-Spacing_Mark
-Surrogate
-Titlecase_Letter
-Unassigned
-Uppercase_Letter
Lorsqu'un regex est analysé avec quelque chose comme ceci \ p {Lu} il
est traduit directement en
Un autre exemple, quand une expression régulière est analysée avec la propriété de ponctuation \ p {P}, elle
est traduite en
Une vérification de cet élément pour l'un de ces éléments bits, qui sont joints dans un masque:
-Close_Punctuation
-Connector_Punctuation
-Dash_Punctuation
-Final_Punctuation
-Initial_Punctuation
-Open_Punctuation
-Other_Punctuation
Le décalage et le bit ou le bit (masque) sont stockés en tant qu'étape d'expression régulière pour cette propriété.
La table de recherche est créée une fois pour tous les points de code Unicode utilisant ce tableau.
Lorsqu'un caractère est vérifié, c'est aussi simple que d'utiliser le CP comme index dans ce tableau et de vérifier l'élément spécifique de la structure de classification pour ce bit (masque).
Cette structure est extensible et indirecte pour fournir des recherches beaucoup plus complexes. Ceci est juste un exemple simple.
Comparez cette recherche directe avec une recherche de classe de caractères:
Toutes les classes sont une liste linéaire d'éléments recherchés de gauche à droite.
Dans cette comparaison, étant donné que notre chaîne cible ne contient que les lettres Unicode majuscules complètes, la loi des moyennes prédirait que la moitié des éléments de la classe devraient être vérifiés pour trouver une correspondance.
C'est un énorme inconvénient en termes de performances.
Cependant, si les tables de recherche ne sont pas là ou ne sont pas à jour avec la dernière version d'Unicode (12 à partir de cette date),
ce serait le seul moyen.
En fait, c'est surtout le seul moyen d'obtenir les
caractères Emoji complets car il n'y a aucune propriété (ou raisonnement) spécifique à leur affectation.
la source
Vous pouvez aussi utiliser:
la source