J'ai regardé Stack Overflow ( remplacement de caractères ... hein , comment JavaScript ne suit pas le standard Unicode concernant RegExp , etc.) et n'ai pas vraiment trouvé de réponse concrète à la question:
How can JavaScript match for accented characters (those with diacritical marks)?
Je force un champ dans une interface utilisateur à correspondre au format: last_name, first_name
(dernier [espace virgule] en premier) , et je veux fournir un support pour les signes diacritiques, mais évidemment en JavaScript, c'est un peu plus difficile que d'autres langages / plates-formes.
C'était ma version originale, jusqu'à ce que je veuille ajouter un support diacritique:
/^[a-zA-Z]+,\s[a-zA-Z]+$/
Actuellement, je suis en train de débattre de l'une des trois méthodes pour ajouter du support, que j'ai toutes testées et que je travaille (au moins dans une certaine mesure, je ne sais pas vraiment quelle est «l'étendue» de la deuxième approche). Les voici:
Liste explicite de tous les caractères accentués que je voudrais accepter comme valides (boiteux et trop compliqués):
var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
- Cela correspond correctement à un nom / prénom avec l'un des caractères accentués pris en charge dans
accentedCharacters
.
Mon autre approche était d'utiliser la .
classe de caractères, pour avoir une expression plus simple:
var regex = /^.+,\s.+$/;
- Cela correspond à peu près tout, au moins sous la forme de:
something, something
. C'est bien je suppose ...
La dernière approche, que je viens de trouver, pourrait être plus simple ...
/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
- Il correspond à une gamme de caractères Unicode - testé et fonctionnel, même si je n'ai rien essayé de fou, juste les trucs normaux que je vois dans notre département de langue pour les noms des professeurs.
Voici mes préoccupations:
- La première solution est beaucoup trop limitative, et bâclée et compliquée à cela. Il faudrait le changer si j'oubliais un personnage ou deux, et ce n'est tout simplement pas très pratique.
- La deuxième solution est meilleure, concise, mais elle correspond probablement beaucoup plus qu'elle ne le devrait réellement. Je n'ai pas trouvé de documentation réelle sur exactement ce qui
.
correspond, juste la généralisation de "n'importe quel caractère sauf le caractère de nouvelle ligne" (à partir d'une table sur le MDN ). La troisième solution semble la plus précise, mais y a-t-il des pièges? Je ne suis pas très familier avec Unicode, du moins en pratique, mais en regardant une table de code / suite de cette table ,
\u00C0-\u017F
semble être assez solide, du moins pour ma contribution attendue.- Les professeurs ne soumettront pas de formulaires avec leurs noms dans leur langue maternelle (par exemple, arabe, chinois, japonais, etc.), donc je n'ai pas à m'inquiéter des caractères non latins.
Donc la ou les vraies questions : laquelle de ces trois approches est la plus adaptée à la tâche? Ou existe-t-il de meilleures solutions?
la source
regex = /^[^,]+,\s[^,]+$/;
pour éviter cela..
atome correspond à tout sauf aux nouvelles lignes " est en fait assez exact :-)Réponses:
Le moyen le plus simple d'accepter tous les accents est le suivant:
Voir https://unicode-table.com/en/ pour les caractères répertoriés par ordre numérique.
la source
-
définit une plage, et cette technique exploite l'ordre des caractères dans le jeu de caractères pour définir une plage continue, ce qui en fait une solution super concise au problèmeZ
eta
)?La plage latine accentuée
\u00C0-\u017F
n'était pas tout à fait suffisante pour ma base de données de noms, j'ai donc étendu l'expression régulière àJ'ai ajouté ces blocs de code (
\u00C0-\u024F
comprend trois blocs adjacents à la fois):\u00C0-\u00FF
Supplément Latin-1\u0100-\u017F
Latin Extended-A\u0180-\u024F
Latin Extended-B\u1E00-\u1EFF
Latin étendu supplémentaireNotez que ce
\u00C0-\u00FF
n'est en fait qu'une partie du supplément Latin-1 . Cette plage ignore les signaux de commande non imprimables et tous les symboles, à l'exception de la multiplication ×\u00D7
et de la division ÷ mal placées\u00F7
.Si vous avez besoin de plus de points de code, vous pouvez trouver plus de plages sur la liste des caractères Unicode de Wikipedia . Par exemple, vous pouvez également ajouter Latin Extended-C , D et E , mais je les ai laissés de côté car seuls les historiens semblent intéressés par eux maintenant, et les ensembles D et E ne s'affichent même pas correctement dans mon navigateur.
La regex originale s'arrêtant à
\u017F
borked sur le nom "Șenol". Selon l'analyseur Unicode de FontSpace , ce premier caractère est\u0218
, LATIN MAJUSCULE S AVEC COMMA CI-DESSOUS. (Ouais, il est généralement orthographié avec une cédille-S\u015E
, "Şenol." Mais je ne prends pas l'avion pour la Turquie pour aller lui dire: "Vous avez mal orthographié votre nom!")la source
[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
Dépend de la tâche :-) Pour faire correspondre exactement tous les caractères latins et leurs versions accentuées, les gammes Unicode fournissent probablement la meilleure solution. Ils peuvent être étendus à tous les caractères non blancs, ce qui peut être fait en utilisant la
\S
classe de caractères.Le problème le plus fondamental que je vois ici ne sont pas les signes diacritiques, mais les espaces. Il existe quelques noms composés de plusieurs mots, par exemple pour les titres. Vous devriez donc opter pour le plus générique, qui autorise tout sauf la virgule qui distingue le premier du nom de famille:
Mais votre deuxième solution avec la
.
classe de caractères est tout aussi bien, vous n'aurez peut-être besoin que de vous soucier de plusieurs virgules.la source
any_character_not_a_comma, any_character_not_a_comma
? C'est ce que je pensais quand je l'ai lu pour la première fois, j'ai été un peu confus quand j'ai vu trois virgules là-dedans.s
pour l'espace blanc…[^\s]
à\S
La bibliothèque XRegExp a un plugin nommé Unicode qui aide à résoudre des tâches comme celle-ci.
C'est mentionné dans les commentaires sur la question, mais c'est facile à manquer. Je ne l'ai remarqué qu'après avoir soumis cette réponse.
la source
anything, anything
. Cela sera utile pour les futurs lecteurs :)Que dis-tu de ça?
la source
Šš
.Et ça?
Il correspondra à chaque mot avec des caractères accentués ou non.
la source
à partir de ce wiki: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin
pour les lettres latines, j'utilise
il évite les tirets et les caractères spéciaux
la source
Explication:
\pL
- correspond à tout type de lettre de n'importe quelle langue\pM
- attache un caractère destiné à être combiné avec un autre caractère (par exemple des accents, des trémas, des encadrés, etc.)\p{Zs}
- correspond à un caractère d'espacement invisible, mais qui prend de la placeu
- Les chaînes de motif et de sujet sont traitées comme UTF-8Contrairement à d'autres expressions régulières proposées (telles que
[A-Za-zÀ-ÖØ-öø-ÿ]
), cela fonctionnera avec tous les caractères spécifiques à la langue, par exempleŠš
correspond à cette règle, mais pas aux autres sur cette page.Malheureusement, JavaScript ne prend pas en charge ces classes de manière native. Cependant, vous pouvez utiliser
xregexp
, par exemplela source
Vous pouvez supprimer les signes diacritiques des alphabets en utilisant:
Il supprimera toutes les marques diacritiques, puis exécutera votre regex dessus
Référence:
https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/
la source