web-dev-qa-db-fra.com

Regex Javascript concret pour les caractères accentués (diacritiques)

J'ai regardé Stack Overflow ( remplacer les caractères .. eh , comment JavaScript ne suit pas la norme Unicode concernant RegExp , etc.) et je n'ai pas vraiment trouvé 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 [virgule] en premier) , et je souhaite 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 discute de l’une des trois méthodes d’ajout de prise en charge, que j’ai testées et que j’utilise (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é):


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 associe correctement un nom/prénom avec l'un des caractères accentués pris en charge dans accentedCharacters.

Mon autre approche consistait à utiliser la classe de caractères . pour obtenir une expression plus simple:

var regex = /^.+,\s.+$/;
  • Cela correspond à peu près à tout, du moins sous la forme de: something, something. C'est bon je suppose ...

La dernière approche, que je viens de trouvée 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 fonctionnels, bien que je n’aie rien essayé de fou, mais que je trouve dans le département de langue tout le contenu normal des noms de professeurs.

Voici mes préoccupations:

  1. La première solution est beaucoup trop limitative et peu soignée. Il me faudrait changer si j'oubliais un ou deux personnages, et ce n'est pas très pratique.
  2. 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 que . correspond, juste la généralisation de "tout caractère sauf le caractère de nouvelle ligne" (à partir d'un tableau situé sur le - MDN ).
  3. La troisième solution semble être la plus précise, mais y a-t-il des pièges? Je ne connais pas très bien Unicode, du moins dans la pratique, mais regarder table de codes / suite de ce tablea , \u00C0-\u017F semble être assez solide , au moins pour ma contribution attendue.

    • Les professeurs ne soumettront pas de formulaires avec leurs noms dans leur langue maternelle (par exemple, l'arabe, le chinois, le japonais, etc.), de sorte que je n'ai pas à m'inquiéter des caractères avec un jeu de caractères non latin.

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

117
Chris Cirefice

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

Dépend de la tâche :-) Pour faire correspondre exactement tous les caractères latins et leurs versions accentuées, les gammes Unicode constituent probablement la meilleure solution. Ils pourraient être étendus à tous les caractères non-blancs, ce qui pourrait être fait en utilisant la classe de caractères \S.

Je force un champ dans une interface utilisateur pour qu'il corresponde au format suivant: last_name, first_name (dernier [virgule] en premier)

Le problème le plus fondamental que je vois ici ne concerne pas les signes diacritiques, mais les espaces blancs. Quelques noms sont composés de plusieurs mots, par exemple: pour les titres. Donc, vous devriez utiliser le plus générique, c'est-à-dire tout autoriser sauf la virgule qui distingue le nom du nom de famille:

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

Mais votre deuxième solution avec la classe de caractères . est tout aussi bien, vous pourriez alors avoir besoin de vous soucier de plusieurs virgules.

17
Bergi

Le moyen le plus simple d'accepter tous les accents est le suivant:

[A-zÀ-ú] // accepts lowercase and uppercase characters
[A-zÀ-ÿ] // as above but including letters with an umlaut (includes [ ] ^ \ × ÷)
[A-Za-zÀ-ÿ] // as above but not including [ ] ^ \
[A-Za-zÀ-ÖØ-öø-ÿ] // as above but not including [ ] ^ \ × ÷

Voir https://unicode-table.com/en/ pour les caractères répertoriés par ordre numérique.

183
Maycow Moura

La plage accentuée latine \u00C0-\u017F n’était pas assez suffisante pour ma base de données de noms, j’ai donc étendu la regex à

[a-zA-Z\u00C0-\u024F]
[a-zA-Z\u00C0-\u024F\u1E00-\u1EFF] // includes even more Latin chars

J'ai ajouté ces blocs de code (\u00C0-\u024F comprend trois blocs adjacents à la fois):

Notez que \u00C0-\u00FF n'est en réalité qu'une partie de supplément Latin-1 . Cette plage ignore les signaux de commande non imprimables et tous les symboles, à l'exception de la multiplication mal positionnée × \u00D7 et de la division ÷ \u00F7.

  • \u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF peut remplacer \u00C0-\u00FF pour exclure ×

Si vous avez besoin de plus de points de code, vous pouvez trouver plus de plages sur la liste Liste des caractères Unicode de Wikipedia. Par exemple, vous pouvez également ajouter latin étendu-C , D et E , mais je les ai laissés de côté car seuls les historiens semble s'intéresser à eux maintenant, et les ensembles D et E ne se rendent même pas correctement dans mon navigateur.

La regex originale s'arrêtant à \u017F bougeait sous le nom "Șenol". Selon l'analyseur Unicode de FontSpace , ce premier caractère est \u0218, LETTRE MAJUSCULE LATINE S COMMA INFÉRIEUR. (Ouais, il est généralement orthographié avec un cedilla-S \u015E, "Şenol." Mais je ne vais pas aller en Turquie pour aller lui dire, "Vous écrivez mal votre nom!")

27
Chaim Leib Halbert

La bibliothèque XRegExp a n plugin nommé Unicode qui permet de 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>

C'est mentionné dans les commentaires à la question, mais c'est facile à manquer. Je ne l'ai remarqué qu'après avoir soumis cette réponse.

14
thorn̈

Que dis-tu de ça?

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

Et ça?

^([a-zA-Z]|[à-ú]|[À-Ú])+$

Cela correspond à tous les mots avec des caractères accentués ou non.

6
Javier Pallarés

depuis 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 caractères spéciaux

5
fdsfdsfdsfds