Expression régulière pour valider les noms et prénoms?

bien que cela semble comme une question triviale, je suis tout à fait sûr qu'il n'est pas :)

j'ai besoin de valider les noms et prénoms de personnes du monde entier. Comment puis-je faire avec une expression régulière? Si ce n'était que des Anglais, je pense que cela le couperait:

^[a-z -']+$

Cependant, j'ai besoin de soutien aussi ces cas:

  • d'autres signes de ponctuation tels qu'ils peuvent être utilisés dans différents pays (aucune idée de qui, mais peut-être vous faire!)
  • différents Unicode lettre (lettre accentuée, grec, japonais, chinois, et ainsi de suite)
  • pas de nombres ou de symboles ou de ponctuation ou runes inutiles, etc..

y a-t-il un moyen standard de valider ces champs que je peux implémenter pour s'assurer que les visiteurs de notre site Web ont une grande expérience et peuvent réellement utiliser leur nom lors de l'inscription?

je serais à la recherche de quelque chose de similaire à l'adresse de courriel "beaucoup" regexes que vous pouvez trouver sur google.

37
demandé sur Sklivvz 2009-05-20 20:05:25

12 réponses

en fait, je ne me donnerais pas la peine.

peu importe le regex que vous inventez, je peux trouver un nom quelque part dans le monde qui le cassera.

cela étant dit, vous devez nettoyer les entrées, pour éviter les Peu De Bobby Tables problème.

39
répondu Chris Cudmore 2009-05-20 16:23:22

je vais essayer de donner une réponse adéquate moi-même:

les seules ponctuations qui devraient être permises dans un nom sont FULL stop, apostrophe et trait d'Union. Je n'ai vu aucun autre cas dans la liste des cas du coin.

en ce qui concerne les nombres, il n'y a qu'un seul cas avec un 8. Je pense que je peux refuser.

en ce qui concerne les lettres, n'importe quelle lettre est valide.

je veux aussi inclure l'espace.

Ce serait somme jusqu'à ce regex:

^[\p{L} \.'\-]+$

ceci présente un problème, c'est-à-dire que l'apostrophe peut être utilisée comme vecteur d'attaque. Il doit être codé.

donc le code de validation devrait être quelque chose comme ceci (non testé):

var name = nameParam.Trim();
if (!Regex.IsMatch(name, "^[\p{L} \.\-]+$")) 
    throw new ArgumentException("nameParam");
name = name.Replace("'", "'");  //' does not work in IE

est-ce que quelqu'un peut penser à une raison pour laquelle un nom ne devrait pas passer ce test ou une Injection XSS ou SQL qui pourrait passer?


solution testée complète

using System;
using System.Text.RegularExpressions;

namespace test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var names = new string[]{"Hello World", 
                "John",
                "João",
                "タロウ",
                "やまだ",
                "山田",
                "先生",
                "мыхаыл",
                "Θεοκλεια",
                "आकाङ्क्षा",
                "علاء الدين",
                "אַבְרָהָם",
                "മലയാളം",
                "상",
                "D'Addario",
                "John-Doe",
                "P.A.M.",
                "' --",
                "<xss>",
                "\""
            };
            foreach (var nameParam in names)
            {
                Console.Write(nameParam+" ");
                var name = nameParam.Trim();
                if (!Regex.IsMatch(name, @"^[\p{L}\p{M}' \.\-]+$"))
                {
                    Console.WriteLine("fail");
                    continue;
                }
                name = name.Replace("'", "&#39;");
                Console.WriteLine(name);
            }
        }
    }
}
18
répondu Sklivvz 2009-05-20 19:35:16

j'autoriserais tout (sauf une chaîne vide) et supposerais que l'utilisateur sait quel est son nom.

il y a 2 cas communs:

  1. vous vous souciez que le nom est exact et valident contre un vrai passeport papier ou autre document d'identité, ou contre une carte de crédit.
  2. vous ne vous souciez pas beaucoup et l'Utilisateur sera en mesure de s'inscrire comme "Fred Smith" (ou "Jane Doe") de toute façon.

dans le cas (1) , vous pouvez autoriser tous les caractères parce que tu vérifies contre un document papier.

dans le cas (2), Vous pouvez aussi bien autoriser tous les caractères parce que "123 456" n'est vraiment pas pire un pseudonyme que "Abc Def".

14
répondu user9876 2009-05-20 16:13:13

je pense que vous feriez mieux de hors les caractères que vous ne voulez pas d'un regex. Essayer d'obtenir chaque tréma, e accentué, trait d'union, etc. sera assez fou. Excluez juste les chiffres (mais alors qu'en est-il D'un gars nommé "George Forman the 4th") et les symboles que vous savez que vous ne voulez pas comme @#$%^ ou ce que vous avez. Mais même dans ce cas, l'utilisation d'un regex ne fera que garantir que l'input correspond au regex, il ne vous dira pas que c'est un nom valide

modifier après avoir précisé que cela tente d'empêcher XSS: Un regex sur un champ de nom ne va évidemment pas arrêter XSS tout seul. Toutefois, cet article a une section sur le filtrage qui est un point de départ si vous voulez aller dans cette voie.

http://tldp.org/HOWTO/Secure-Programs-HOWTO/cross-site-malicious-content.html

s/[\<\>\"\'\%\;\(\)\&\+]//g;
10
répondu kscott 2009-05-20 16:40:36

Je ne pense pas que ce soit une bonne idée. Même si vous trouvez une expression régulière appropriée (peut-être en utilisant les propriétés des caractères Unicode), cela n'empêcherait pas les utilisateurs d'entrer des pseudo-noms comme John Doe, Max Mustermann (il y a même une personne avec ce nom), Abcde Fghijk ou Ababa Bebebe.

6
répondu Gumbo 2009-05-20 16:13:55

vous pouvez utiliser le code regex suivant pour valider 2 noms séparés par un espace avec le code regex suivant:

^[A-Za-zÀ-ú]+ [A-Za-zÀ-ú]+$

ou simplement l'utiliser:

[[[: lower:]] = [a-zà-ú]

[[: upper:]] =[a-ZÀ-Ú]

[[[: alpha:]] = [A-Za-Zà-ú]

[[: alnum:]] = [A-Za-zÀ-ú0-9]

6
répondu Paulo Carvalho 2012-04-08 00:29:28

BTW, prévoyez-vous de n'autoriser que l'alphabet Latin, ou prévoyez-vous également d'essayer de valider le Chinois, l'arabe, L'Hindi, etc.?

comme d'autres l'ont dit, ne pas même pour ce faire. Reculez et demandez-vous ce que vous essayez réellement d'accomplir. Puis essayer de l'accomplir sans faire des hypothèses sur les noms de personnes sont, ou ce qu'ils signifient.

5
répondu John Saunders 2009-05-20 16:18:10

C'est un problème très difficile à valider quelque chose comme un nom à cause de tous les cas particuliers possibles.

Coin Des Cas

épurez les entrées et laissez-les entrer tout ce qu'ils veulent pour un nom, parce que décider ce qui est un nom valide et ce qui ne l'est pas est probablement en dehors de la portée de ce que vous faites; étant donné la gamme de noms potentiels étranges et Légaux est presque infini.

S'ils veulent s'appeler Tricyclopltz^2-Glockenschpiel, c'est leur problème, pas le vôtre.

2
répondu Trampas Kirk 2009-05-20 17:35:55

un sujet très litigieux que je semble avoir trébuché ici. Toutefois, il est parfois agréable de tête cher petit-Bobby tables off à la passe et envoyer Petit Robert au bureau des directeurs avec ses semi-colons et SQL lignes de commentaire --.

ce REGEX dans VB.NET comprend des caractères alphabétiques réguliers et divers caractères européens circonflexes. Cependant pauvre vieux James Mc'Tristan-Smythe le 3rd devra entrer son pedigree en tant que le Jim le Troisième.

<asp:RegularExpressionValidator ID="RegExValid1" Runat="server"
                    ErrorMessage="ERROR: Please enter a valid surname<br/>" SetFocusOnError="true" Display="Dynamic"
                    ControlToValidate="txtSurname" ValidationGroup="MandatoryContent"
                    ValidationExpression="^[A-Za-z'\-\p{L}\p{Zs}\p{Lu}\p{Ll}\']+$">
2
répondu Timi 2011-05-05 10:16:38

un peu Cela aide:

^[a-zA-Z]'?([a-zA-Z]|\.| |-)+$

1
répondu MT. 2012-06-28 00:23:41

celui-ci devrait fonctionner ^([A-Z]{1}+[a-z\-\.\']*+[\s]?)* Ajouter des caractères spéciaux si vous en avez besoin.

0
répondu TodStoychev 2016-03-10 07:45:58

Mesures:

  1. d'abord enlever tous les accents
  2. appliquer l'expression régulière

pour enlever les accents:

private static string RemoveAccents(string s)
{
    s = s.Normalize(NormalizationForm.FormD);
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < s.Length; i++)
    {
        if (CharUnicodeInfo.GetUnicodeCategory(s[i]) != UnicodeCategory.NonSpacingMark) sb.Append(s[i]);
    }
    return sb.ToString();
}
0
répondu Martin Staufcik 2016-08-20 12:15:45