Concrete Javascript Regex pour caractères accentués (Diacritics)

J'ai regardé Stack Overflow (en remplaçant les caractères … eh , comment JavaScript ne suit pas la norme Unicode concernant RegExp , etc.) et n'a pas vraiment trouvé une réponse concrète à la question:

How can JavaScript match for accented characters (those with diacritical marks)?

Je oblige un champ dans une interface utilisateur à faire correspondre le format: last_name, first_name (last [comma space] first) , et je souhaite fournir un support pour les diacritics, mais évidemment en JavaScript, c'est un peu plus difficile que d'autres langues / plates-formes.

C'était ma version originale, jusqu'à ce que je voulais ajouter un support diacritique:

/^[a-zA-Z]+,\s[a-zA-Z]+$/

Actuellement, je discute de l'une des trois méthodes pour ajouter du soutien, dont j'ai testé et travaillé (du moins dans une certaine mesure, je ne sais pas vraiment ce que l'expression "l'étendue" est de la deuxième approche). Les voici:

Liste explicite de tous les caractères accentués que je souhaiterais accepter comme valides (mécontents 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àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/ 
  • Ceci correspond correctement à un dernier / prénom avec l'un des caractères accentués pris en charge dans les caractères accentedCharacters .

Mon autre approche était d'utiliser le . Classe de caractères, pour avoir une expression plus simple:

 var regex = /^.+,\s.+$/; 
  • Cela correspondrait à presque n'importe quoi, du moins sous la forme de: something, something . C'est bon 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és et en cours d'exécution, mais je n'ai pas essayé quelque chose de fou, juste les choses normales que je vois dans notre département de langues pour les noms des membres du corps professoral.

Voici mes préoccupations:

  1. La première solution est trop limitée, et négligée et alambiquée à ce sujet. Il faudrait changer si j'ai oublié un ou deux personnages, ce qui n'est tout simplement pas très pratique.
  2. La deuxième solution est meilleure, concise, mais elle correspond probablement beaucoup plus à ce qu'elle devrait réellement. Je ne pouvais trouver aucune documentation réelle sur exactement quoi . Correspond à la généralisation de "tout caractère sauf le caractère de la nouvelle ligne" (d'un tableau sur le MDN ).
  3. La troisième solution semble être la plus précise, mais y a-t-il des problèmes? Je ne suis pas très familier avec Unicode, du moins dans la pratique, mais en regardant un tableau de code / continuation de cette table , \u00C0-\u017F semble être assez solide, du moins pour mes commentaires attendus.

    • La faculté ne soumettra pas de formulaires avec leur nom dans leur langue maternelle (p. Ex., Arabe, chinois, japonais, etc.), de sorte que je n'ai pas à m'inquiéter de personnages hors caractère latin

Donc la vraie question (s) : Laquelle de ces trois approches est la plus adaptée à la tâche? Ou y a-t-il de meilleures solutions?

Laquelle de ces trois approches est la plus adaptée à la tâche?

Dépend de la tâche 🙂 Pour 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 pourrait être fait en utilisant la classe de caractères \S

Je oblige un champ dans une interface utilisateur à faire correspondre le format: last_name, first_name (last [comma space] first)

Le problème le plus fondamental que je vois ici n'est pas diacritique, mais les espaces blancs. Il existe quelques noms qui comportent plusieurs mots, par exemple pour les titres. Donc, vous devriez aller avec le plus générique, ce qui permet tout sauf la virgule qui distingue d'abord son nom de famille:

 /[^,]+,\s[^,]+/ 

Mais votre deuxième solution avec le . La classe de personnage est tout aussi bien, vous devrez peut-être vous soucier de plusieurs commats.

La façon la plus simple d'accepter tous les accents est la suivante:

 [A-zÀ-ú] // accepts lowercase and uppercase characters [A-zÀ-ÿ] // as above but including letters with an umlaut 

La bibliothèque XRegExp possède un plugin nommé Unicode qui aide à résoudre des tâches comme celle-ci.

 <script src="xregexp.js"></script> <script src="addons/unicode/unicode-base.js"></script> <script> var unicodeWord = XRegExp("^\\p{L}+$"); unicodeWord.test("Русский"); // true unicodeWord.test("日本語"); // true unicodeWord.test("العربية"); // true </script> 

Il est mentionné dans les commentaires à la question, mais il est facile de manquer. Je l'ai remarqué seulement après avoir soumis cette réponse.

La gamme latine accentuée \u00C0-\u017F n'était pas suffisante pour ma base de données de noms, donc j'ai étendu le regex à [a-zA-Z\u00C0-\u024F] .

Si vous avez besoin de plus de points de code, vous pouvez trouver plus de gammes sur la liste des caractères Unicode de Wikipédia.

Le regex original s'arrête à \u017F borked sur le nom "Şenol". Selon l'analyseur Unicode de FontSpace , ce premier caractère est \u0218 , LATIN CAPITAL LETTER S AVEC COMMA CI-DESSOUS. (Ouais, il est généralement écrit avec une cédille-S \u015E , "Şenol". Mais je ne vais pas dire que "Vous écrivez votre nom à tort!")

À partir de ce wiki: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin

Pour les lettres latines, j'utilise

 /^[A-zÀ-ÖØ-öø-ÿ]+$/ 

Il évite les traits d'union et les charmes spéciaux

Que dis-tu de ça?

 /^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/