Comment valider des numéros de téléphone en utilisant regex


920

J'essaie de mettre sur pied une expression rationnelle complète pour valider les numéros de téléphone. Idéalement, il gérerait les formats internationaux, mais il devrait gérer les formats américains, notamment les suivants:

  • 1-234-567-8901
  • 1-234-567-8901 x1234
  • 1-234-567-8901 ext1234
  • 1 (234) 567-8901
  • 1.234.567.8901
  • 1/234/567/8901
  • 12345678901

Je répondrai avec ma tentative actuelle, mais j'espère que quelqu'un a quelque chose de mieux et / ou de plus élégant.


3
BTW, vous devez spécifier la langue que vous utilisez. Tous les moteurs d'expression régulière n'ont pas la même syntaxe.
AndrewJFord

9
Il semble que vous ayez omis l'option +1 au lieu de 1, bien que la réponse couvre ce cas.
Eric

153
Tous les numéros de téléphone américains ne nécessitent- 555ils pas en dehors d'eux 911?
Andrew Grimm

41
Au contraire, le préfixe 555 est réservé aux faux numéros de téléphone. Ces numéros sont garantis de ne pas se connecter à un numéro de téléphone réel, ils sont donc souvent utilisés à la télévision et au cinéma pour s'assurer qu'un téléspectateur n'essaie pas d'appeler le numéro et finit par harceler des pauvres innocents.
rushinge

49
@rushinge Si c'était vrai il y a des décennies, ce n'est plus vrai . Le préfixe 555 est toujours spécial, mais seule une petite plage de chiffres est garantie de se terminer sans connexion 555-0100 à 555-0199. Mais je suis presque sûr qu'Andrew plaisantait de toute façon.
Adam Davis

Réponses:


515

Meilleure option ... il suffit de supprimer tous les caractères non numériques à l'entrée (sauf les signes 'x' et les signes '+'), en prenant soin en raison de la tendance britannique à écrire des nombres sous la forme non standard +44 (0) ...lorsqu'on lui demande d'utiliser le préfixe international (dans ce cas spécifique, vous devez vous débarrasser (0)entièrement du).

Ensuite, vous vous retrouvez avec des valeurs comme:

 12345678901
 12345678901x1234
 345678901x1234
 12344678901
 12345678901
 12345678901
 12345678901
 +4112345678
 +441234567890

Ensuite, lorsque vous affichez, reformatez le contenu de votre cœur. par exemple

  1 (234) 567-8901
  1 (234) 567-8901 x1234

35
Le code de formatage sera une perte de temps si les chiffres peuvent provenir de l'extérieur des États-Unis.
Daniel Earwicker

26
C'est bien et tout, mais cela ne valide pas ce qui a été entré était en fait un numéro de téléphone. Par exemple, que se passe-t-il si l'utilisateur n'entre pas les 10 chiffres requis? Cela devrait être combiné avec une bonne validation des expressions rationnelles.
Hugh Jeffner

108
Considérant que la question portait sur la validation - c'est une très mauvaise réponse.
PlexQ

15
@PlexQ Je ne suis pas d'accord. Le problème d'origine tente de gérer la validation des numéros de téléphone car il essayait de gérer toutes les options de formatage possibles. Plutôt que d'essayer de résoudre tout cela, prenez l'entrée et "pré-supprimez" tous les trucs de formatage jusqu'à ce que vous ayez juste le "nombre". Cela résout 2 problèmes - tester le résultat est désormais facile et vous pouvez désormais vous assurer que les valeurs restituées pour l'affichage peuvent toutes être formatées de manière cohérente. Le premier commentaire sur cette réponse à propos des "Gants de complicateur" est une bonne lecture ... parfois la réponse à un problème est de l'aborder différemment.
scunliffe

29
Comment diable est-ce une réponse si fortement votée? Cela ne valide rien. Le pire, c'est que toutes les autres questions de validation des numéros de téléphone font référence à celle-ci ...
jlars62

303

Il s'avère qu'il y a quelque chose d'une spécification pour cela, au moins pour l'Amérique du Nord, appelée le NANP .

Vous devez spécifier exactement ce que vous voulez. Que sont les délimiteurs légaux? Espaces, tirets et périodes? Aucun délimiteur autorisé? Peut-on mélanger des délimiteurs (par exemple, + 0.111-222.3333)? Comment les extensions (par exemple, 111-222-3333 x 44444) seront-elles gérées? Qu'en est-il des numéros spéciaux, comme le 911? L'indicatif régional sera-t-il facultatif ou obligatoire?

Voici une expression régulière pour un nombre à 7 ou 10 chiffres, avec des extensions autorisées, les délimiteurs sont des espaces, des tirets ou des points:

^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$

7
le voici sans la section extension (je fais entrer mes utilisateurs ext dans un champ séparé): ^ (?: (?: \ +? 1 \ s * (?: [.-] \ s *)?)? : (\ s * ([2-9] 1 [02-9] | [2-9] [02-8] 1 | [2-9] [02-8] [02-9]) \ s *) | ([2-9] 1 [02-9] | [2-9] [02-8] 1 | [2-9] [02-8] [02-9])) \ s * (?: [ .-] \ s *)?)? ([2-9] 1 [02-9] | [2-9] [02-9] 1 | [2-9] [02-9] {2}) \ s * (?: [.-] \ s *)? ([0-9] {4}) $
aarona

18
Voici une version qui ne correspond qu'à 10 chiffres (pas à 7 chiffres comme 843-1212): /(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})/
Brian Armstrong

8
10 chiffres acceptent () autour de l'indicatif régional et ne permettent pas de précéder 1 comme indicatif de pays(?:(?:(\s*\(?([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\)?\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})
Brooke.

5
@StevenSoroka J'ai le livre de Jeffrey Friedl à côté de moi sur mon bureau depuis deux ans, car les expressions régulières sont une partie importante de mon travail. Il faut un bon moment pour vraiment comprendre les expressions régulières. Parfois, les lecteurs de ce site recherchent simplement une solution existante, plutôt que d'écrire la leur, en particulier dans les domaines avec beaucoup de cas d'angle, tels que les représentations de numéros de téléphone.
Justin R.

7
@ fatcat1111 Je comprends cela, mais la majorité des réponses ici sont des expressions régulières uniques "moi aussi" qui ne correspondent probablement à aucun de vos cas de coin. Ceux-ci se retrouvent ensuite sur tous les sites Web que j'essaie d'utiliser et je ne peux pas entrer mon code postal ou mon numéro de téléphone ou mon adresse e-mail parce que quelqu'un a utilisé une expression régulière à moitié cuite (par exemple: + est un caractère valide dans les adresses e-mail ). Les meilleures réponses sur cette page pointent les utilisateurs vers les bibliothèques, pas vers les expressions rationnelles gribouillées de serviettes.
Steven Soroka

298
.*

Si les utilisateurs veulent vous donner leurs numéros de téléphone, faites-leur confiance pour bien faire les choses. S'ils ne veulent pas vous le donner, les forcer à entrer un numéro valide les enverra soit sur le site d'un concurrent, soit leur fera entrer une chaîne aléatoire qui correspond à votre expression régulière. Je pourrais même être tenté de rechercher le numéro d'une hotline horoscope à tarif premium et de le saisir à la place.

Je considérerais également l'un des éléments suivants comme des entrées valides sur un site Web:

"123 456 7890 until 6pm, then 098 765 4321"  
"123 456 7890 or try my mobile on 098 765 4321"  
"ex-directory - mind your own business"

202
Je suis d'accord avec le sentiment ici, mais parfois il est agréable d'effectuer une validation lorsque le numéro de téléphone va être utilisé pour quelque chose d'important dans l'intérêt de l'utilisateur . Le meilleur exemple ici est l'autorisation de carte de crédit pour un achat. Si le numéro de téléphone est incorrect, l'authentification peut échouer.
Pointy

53
Si l'utilisateur ne veut pas entrer son numéro de téléphone, vous pouvez simplement autoriser le champ à être facultatif, mais est-ce trop demander à l'utilisateur d'entrer un numéro de téléphone valide s'il veut en entrer un?
Joel McBeth

11
Un autre rôle de la validation est simplement de rappeler aux gens d'ajouter des codes régionaux, etc. qu'ils ne se souviendraient pas autrement d'ajouter, mais qui ne peuvent pas être devinés après coup.
Ben McIntyre

29
@Pointy Mais la validation regex ne vous aidera pas. La seule et unique façon de valider réellement si le numéro de téléphone est correct est de lui envoyer un message (en cas de mobile) ET de s'assurer que l'utilisateur confirme en utilisant une sorte de code de vérification. C'est ce que vous faites lorsque l'exactitude des nombres est importante. Tout le reste est juste pour la commodité de l'utilisateur pour se protéger contre certaines (mais pas toutes) les fautes de frappe et ne valide rien.
Alex B

14
Cool. Mon numéro de téléphone est 1 'OU 1 = 1 - PWNED . Voir xkcd.com/327 et owasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005)
Aaron Newton

171

Je suggère également de consulter la bibliothèque Google " libphonenumber ". Je sais que ce n'est pas regex mais ça fait exactement ce que vous voulez.

Par exemple, il reconnaîtra que:

15555555555

est un nombre possible mais pas un nombre valide. Il prend également en charge les pays en dehors des États-Unis.

Points forts de la fonctionnalité:

  • Analyse / formatage / validation des numéros de téléphone pour tous les pays / régions du monde.
  • getNumberType- obtient le type du numéro en fonction du numéro lui-même; capable de distinguer les numéros fixes, mobiles, sans frais, surtaxés, à frais partagés, VoIP et personnels (lorsque cela est possible).
  • isNumberMatch - obtient un niveau de confiance pour savoir si deux nombres peuvent être identiques.
  • getExampleNumber/ getExampleNumberByType- fournit des exemples de numéros valides pour tous les pays / régions, avec la possibilité de spécifier le type d'exemple de numéro de téléphone requis.
  • isPossibleNumber - deviner rapidement si un numéro est un numéro de téléphone possible en utilisant uniquement les informations de longueur, beaucoup plus rapidement qu'une validation complète.
  • isValidNumber - validation complète d'un numéro de téléphone pour une région à l'aide des informations de longueur et de préfixe.
  • AsYouTypeFormatter - formate les numéros de téléphone à la volée lorsque les utilisateurs entrent chaque chiffre.
  • findNumbers - trouve des nombres dans la saisie de texte.
  • PhoneNumberOfflineGeocoder - fournit des informations géographiques liées à un numéro de téléphone.

Exemples

Le plus gros problème avec la validation du numéro de téléphone est qu'il est très dépendant de la culture.

  • Amérique
    • (408) 974–2042est un numéro américain valide
    • (999) 974–2042n'est pas un numéro américain valide
  • Australie
    • 0404 999 999est un numéro australien valide
    • (02) 9999 9999est également un numéro australien valide
    • (09) 9999 9999n'est pas un numéro australien valide

Une expression régulière est très bien pour vérifier le format d'un numéro de téléphone, mais ça ne va pas vraiment pouvoir vérifier la validité d'un numéro de téléphone.

Je suggère de sauter une expression régulière simple pour tester votre numéro de téléphone et d'utiliser une bibliothèque telle que Google libphonenumber(lien vers le projet GitHub) .

Présentation de libphonenumber!

En utilisant l'un de vos exemples les plus complexes 1-234-567-8901 x1234, vous obtenez les données suivantes de libphonenumber(lien vers la démo en ligne) :

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results:

E164 format                    +12345678901
Original format                (234) 567-8901 ext. 123
National format                (234) 567-8901 ext. 123
International format           +1 234-567-8901 ext. 123
Out-of-country format from US  1 (234) 567-8901 ext. 123
Out-of-country format from CH  00 1 234-567-8901 ext. 123

Ainsi, non seulement vous apprenez si le numéro de téléphone est valide (ce qu'il est), mais vous obtenez également une mise en forme cohérente des numéros de téléphone dans votre région.

En prime, libphonenumberdispose d'un certain nombre d'ensembles de données pour vérifier la validité des numéros de téléphone, ainsi, la vérification d'un nombre tel que +61299999999(la version internationale de (02) 9999 9999) renvoie comme un numéro valide avec mise en forme:

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results

E164 format                    +61299999999
Original format                61 2 9999 9999
National format                (02) 9999 9999
International format           +61 2 9999 9999
Out-of-country format from US  011 61 2 9999 9999
Out-of-country format from CH  00 61 2 9999 9999

libphonenumber vous offre également de nombreux avantages supplémentaires, tels que la capture de l'emplacement où le numéro de téléphone est détecté comme étant, et également l'obtention des informations de fuseau horaire à partir du numéro de téléphone:

PhoneNumberOfflineGeocoder Results
Location        Australia

PhoneNumberToTimeZonesMapper Results
Time zone(s)    [Australia/Sydney]

Mais le numéro de téléphone australien invalide ( (09) 9999 9999) renvoie qu'il ne s'agit pas d'un numéro de téléphone valide.

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     false

La version de Google a du code pour Java et Javascript, mais les gens ont également implémenté des bibliothèques pour d'autres langues qui utilisent l'ensemble de données de numéro de téléphone Google i18n:

À moins que vous ne soyez certain que vous allez toujours accepter des numéros provenant d'un seul lieu, et qu'ils seront toujours dans un seul format, je vous suggère fortement de ne pas écrire votre propre code pour cela, et d'utiliser libphonenumber pour valider et afficher les numéros de téléphone.


Notant qu'il existe désormais également un port Go sur: github.com/ttacon/libphonenumber
michaelhanson

Lorsque vous vérifiez s'il s'agit d'un numéro possible, n'avez-vous pas besoin de spécifier un code de pays? J'utilise la version PHP et si j'entre un nombre britannique comme (remplacez les 0 par des nombres réels) 07700000000j'obtiens une Missing or invalid default region.erreur. Mais si je spécifie le code du pays, il passera.
BugHunterUK

Pour info: cette bibliothèque ne prend pas en charge certains pays, phpinterviewquestions.co.in/blog/ionic/…
sijo vijayan

1
@BugHunterUK (et quiconque rencontre cette question et se pose la même question) lors de l'analyse d'un numéro, vous pouvez spécifier la région attendue et la bibliothèque recherchera des numéros non internationaux dans cette région. Si vous ne le spécifiez pas, il rejettera tout ce qui n'est pas dans un format international valide.
IMSoP

Considérez github.com/nyaruka/phonenumbers car il est devenu le package Go "officiel" recommandé par Google plutôt que libphonenumber.
DeeZone

78

/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i

Cela correspond:

 - (+351) 282 43 50 50
 - 90191919908
 - 555-8909
 - 001 6867684
 - 001 6867684x1
 - 1 (234) 567-8901
 - 1-234-567-8901 x1234
 - 1-234-567-8901 ext1234
 - 1-234 567.89/01 ext.1234
 - 1(234)5678901x1234
 - (123)8575973
 - (0055)(123)8575973

Sur $ n, il économise:

  1. Indicateur de pays
  2. Numéro de téléphone
  3. Extension

Vous pouvez le tester sur https://www.regexpal.com/?fam=99127


Ce fut l'expression rationnelle la plus complète que j'ai vue. Il est facile de se déplacer jusqu'à ce que vous supprimiez ^et $sinon je suis en mesure de le contourner en utilisant [111] [111] [1111]ou 111--111--1111autre. (désolé, supprimé mon dernier commentaire)
bafromca

Pouvez-vous reformuler s'il vous plaît? Je ne peux pas comprendre ceci: "Il est facile de s'en sortir jusqu'à ce que vous supprimiez ^ et $ ou bien je suis capable de le contourner en utilisant [111] [111] [1111]". Cela signifie-t-il qu'il valide «[111] [111] [1111]» lorsque vous prenez le ^et le $?
Ismael Miguel

J'ai contourné votre expression régulière en utilisant [111] [111] [1111]et 111--111--1111jusqu'à ce que je la retire ^et $de l'expression régulière.
bafromca

11
^^^ Ceci est un excellent exemple des raisons pour lesquelles les fils de commentaires ne doivent PAS aller sur le chat. Je suis très intéressé par la façon dont cette conversation s'est avérée et j'ai besoin de savoir si ce ReGex est suffisamment solide pour être utilisé dans mon application. Malheureusement, la conversation de chat a maintenant disparu.
Matt Cashatt

1
Pour être honnête, je ne suis pas allé discuter. Après avoir demandé plusieurs fois des explications, je suis resté sans info. Vous pouvez toujours l'essayer vous-même avec toutes sortes de numéros que vous trouvez en ligne, dans plusieurs formats. Une chose que j'ai essayé avec celui-ci est d'utiliser plusieurs numéros de téléphone, mais cela ne fonctionne pas si bien s'ils ont des espaces autour. Et je dois trouver une solution pour compter le nombre de chiffres et appliquer un montant spécifique.
Ismael Miguel

63

Bien que la réponse pour supprimer tous les espaces blancs soit nette, cela ne résout pas vraiment le problème posé, qui est de trouver une expression régulière. Prenez, par exemple, mon script de test qui télécharge une page Web et extrait tous les numéros de téléphone à l'aide de l'expression régulière. Comme vous auriez besoin d'une expression régulière de toute façon, vous pourriez tout aussi bien demander à l'expression régulière de faire tout le travail. Je suis venu avec ceci:

1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?

Voici un script perl pour le tester. Lorsque vous correspondez, $ 1 contient l'indicatif régional, $ 2 et $ 3 contiennent le numéro de téléphone et $ 5 contient l'extension. Mon script de test télécharge un fichier sur Internet et y imprime tous les numéros de téléphone.

#!/usr/bin/perl

my $us_phone_regex =
        '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?';


my @tests =
(
"1-234-567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1 (234) 567-8901",
"1.234.567.8901",
"1/234/567/8901",
"12345678901",
"not a phone number"
);

foreach my $num (@tests)
{
        if( $num =~ m/$us_phone_regex/ )
        {
                print "match [$1-$2-$3]\n" if not defined $4;
                print "match [$1-$2-$3 $5]\n" if defined $4;
        }
        else
        {
                print "no match [$num]\n";
        }
}

#
# Extract all phone numbers from an arbitrary file.
#
my $external_filename =
        'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt';
my @external_file = `curl $external_filename`;
foreach my $line (@external_file)
{
        if( $line =~ m/$us_phone_regex/ )
        {
                print "match $1 $2 $3\n";
        }
}

Éditer:

Vous pouvez changer \ W * en \ s * \ W? \ S * dans l'expression régulière pour le resserrer un peu. Je ne pensais pas à l'expression rationnelle en termes, disons, de validation de l'entrée utilisateur sur un formulaire lorsque je l'ai écrit, mais cette modification permet d'utiliser l'expression régulière à cette fin.

'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';

2
Pour info, l'expression rationnelle correspond également: (4570457-6789ce serait une faute de frappe assez courante. Les groupes de match sont également biaisés
SooDesuNe

@SooDesuNe Prepending (^|[^\d\n])(avec indicateur multiligne activé ) évite le problème général, en s'assurant qu'il n'est pas immédiatement précédé par quelque chose de numérique.
btown

Notez que c'est centré sur l'Amérique du Nord - il manque "44 7911 123456"
Ben Wheeler

43

J'ai répondu à cette question sur une autre question SO avant de décider d'inclure également ma réponse en tant que réponse sur ce fil, car personne ne se demandait comment exiger / ne pas exiger des éléments, distribuant simplement des expressions rationnelles: Regex fonctionnant mal, correspondant à des choses inattendues

À partir de mon message sur ce site, j'ai créé un guide rapide pour aider quiconque à créer son propre regex pour le format de numéro de téléphone souhaité, que je mettrai en garde (comme je l'ai fait sur l'autre site) que si vous êtes trop restrictif, vous n'obtiendrez peut-être pas les résultats souhaités et il n'y a pas de solution unique pour accepter tous les numéros de téléphone possibles dans le monde - uniquement ce que vous décidez d'accepter comme format de choix. À utiliser à vos risques et périls.

Aide-mémoire rapide

  • Démarrez l'expression: /^
  • Si vous souhaitez avoir besoin d'un espace, utilisez: [\s]ou\s
  • Si vous souhaitez exiger des parenthèses, utilisez: [(]et [)]. Utilisation de \(et\) est moche et peut rendre les choses déroutantes.
  • Si vous voulez que quelque chose soit facultatif, mettez un ?après
  • Si vous voulez un tiret, tapez simplement -ou [-]. Si vous ne le mettez pas en premier ou en dernier dans une série d'autres personnages, vous devrez peut-être y échapper: \-
  • Si vous souhaitez accepter différents choix dans un emplacement, placez des crochets autour des options: il [-.\s]faudra un trait d'union, un point ou un espace. Un point d'interrogation après la dernière parenthèse rendra tous ceux facultatifs pour cet emplacement.
  • \d{3}: Nécessite un numéro à 3 chiffres: 000-999. Sténographie pour [0-9][0-9][0-9].
  • [2-9] : Nécessite un chiffre de 2 à 9 pour cet emplacement.
  • (\+|1\s)?: Acceptez un «plus» ou un 1 et un espace (caractère de tuyau,, |est «ou») et rendez-le facultatif. Le signe "plus" doit être échappé.
  • Si vous voulez que des numéros spécifiques correspondent à un créneau, saisissez-les: il [246]faudra 2, 4 ou 6. [77|78], 77 ou 78.
  • $/ : Mettre fin à l'expression

1
C'est très utile, mais je doute et je cherche une expression {min, max}. Pouvez-vous m'aider?
Ataboy Josef

Si c'est un seul chiffre dont nous parlons (et vous pouvez le faire correspondre en fonction de cela), voyez le [2-9]bloc que je mets là. Cela signifie que votre min est 2 et votre max est 9. Ajustez en conséquence.
vapcguy

30

J'ai écrit le plus simple (même si je n'avais pas besoin de point dedans).

^ ([0-9 \ (\) \ / \ + \ -] *) $

Comme mentionné ci-dessous, il vérifie uniquement les caractères, pas sa structure / ordre


38
cela valide des tonnes de numéros techniquement invalides. comme, "- + () () ()) ())))". Apprenez à lire les expressions régulières pour comprendre ce que vous faites.
Steven Soroka

3
@StevenSoroka techniquement, cela peut autoriser de nombreux cas non valides, mais lorsque nous pensons simplement aider l'utilisateur à éviter les erreurs courantes avec la solution la plus simple possible, c'est la voie à suivre :)
happyhardik

2
cela correspond également à un espace blanc, ligne vide
Wasim A.

1
@HappyHardik. En effet. Simple et puissant, pour une validation de base, l'utilisateur peut taper plus d'un point, un tiret, un crochet ou plus.
dijipiji

Je viens de l'utiliser et c'est faux à bien des égards. Par exemple, un numéro de téléphone au Royaume-Uni peut commencer par +44, ou un numéro de téléphone peut avoir (0) à l'intérieur. Mais ce n'est pas valable selon votre expression régulière. Je recommanderais la réponse de @Ismael Miguel. Cela fonctionne très bien et je vous recommanderais de réviser votre réponse.
Stelios Voskos

22

Si vous voulez simplement vérifier que vous n'avez pas de déchets aléatoires dans le champ (c'est-à-dire de spammeurs de formulaires), cette expression régulière devrait bien fonctionner:

^[0-9+\(\)#\.\s\/ext-]+$

Notez qu'il n'a pas de règles spéciales pour le nombre de chiffres ou quels nombres sont valides dans ces chiffres, il vérifie simplement que seuls les chiffres, les parenthèses, les tirets, plus, l'espace, la livre, l'astérisque, le point, la virgule ou les lettres e, x, tsont présents.

Il doit être compatible avec les numéros internationaux et les formats de localisation. Prévoyez-vous un besoin d'autoriser les supports carrés, bouclés ou angulaires pour certaines régions? (actuellement, ils ne sont pas inclus).

Si vous souhaitez conserver les règles par chiffre (comme dans les codes de zone et les préfixes des États-Unis (les codes d'échange) doivent être compris entre 200 et 999), bonne chance à vous. Le maintien d'un ensemble de règles complexes qui pourrait être obsolète à tout moment dans l'avenir par n'importe quel pays du monde ne semble pas amusant.

Et bien que supprimer tous / la plupart des caractères non numériques puisse bien fonctionner côté serveur (surtout si vous prévoyez de transmettre ces valeurs à un numéroteur), vous ne voudrez peut-être pas supprimer l'entrée de l'utilisateur lors de la validation, en particulier si vous le souhaitez. faire des corrections dans un autre domaine.


22

Notez que la suppression des ()caractères ne fonctionne pas pour un style d'écriture des numéros britanniques qui est courant: +44 (0) 1234 567890ce qui signifie composer le numéro international:
+441234567890
ou dans le cadran britannique01234567890


15

Avez-vous jeté un œil à RegExLib ?

La saisie du numéro de téléphone américain a ramené toute une liste de possibilités.


3
Cela semble être un excellent moyen d'intégrer des bogues obscurs dans votre code.
Tom Lord

12

Ma tentative de regex sans restriction:

/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/

Accepte:

+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww

Rejette:

mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911

C'est à vous de le désinfecter pour l'affichage. Après validation, cela pourrait être un nombre.


12

J'ai trouvé que cela fonctionnait assez bien:

^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$

Cela fonctionne pour ces formats de nombre:

1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
1-234-567-8901 ext. 1234
(+351) 282 433 5050

Assurez-vous d'utiliser des indicateurs globaux ET multilignes pour vous en assurer.

Lien: http://www.regexr.com/3bp4b


11

Si vous parlez de validation de formulaire, l'expression rationnelle pour valider la signification correcte ainsi que les données correctes sera extrêmement complexe en raison de la diversité des pays et des normes des fournisseurs. Il sera également difficile de se tenir à jour.

J'interprète la question comme recherchant un modèle largement valide, qui peut ne pas être cohérent en interne - par exemple, avoir un ensemble de chiffres valide, mais ne validant pas que la ligne principale, l'échange, etc. au modèle valide pour le préfixe de code de pays .

L'Amérique du Nord est simple, et pour l'international, je préfère utiliser un modèle «idiomatique» qui couvre les façons dont les gens spécifient et se souviennent de leurs chiffres:

^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

Le modèle nord-américain garantit que si une parenthèse est incluse, les deux le sont. L'international représente un «+» initial et un code de pays facultatifs. Après cela, vous êtes dans l'idiome. Les correspondances valides seraient:

  • (xxx)xxx-xxxx
  • (xxx)-xxx-xxxx
  • (xxx)xxx-xxxx x123
  • 12 1234 123 1 x1111
  • 12 12 12 12 12
  • 12 1 1234 123456 x12345
  • +12 1234 1234
  • +12 12 12 1234
  • +12 1234 5678
  • +12 12345678

Cela peut être biaisé car mon expérience se limite à l'Amérique du Nord, à l'Europe et à un petit peu d'Asie.


J'ai essayé d'implémenter ce qui précède dans mon script de validation javascript mais je reçois toujours une invalid quantifiererreur. Des idées sur ce que je fais mal?
Jannis

J'ajouterais le cas trivial où le téléphone est spécifié sans symboles mais peut-être les espaces et le code du pays, en Europe est typique pour les numéros locaux et mobiles: 676412342, 676 46 32 12, 676 463 212
rupps

11

Voici un modèle merveilleux qui correspond le mieux à la validation que j'avais besoin de réaliser. Je ne suis pas l'auteur original, mais je pense que cela vaut la peine d'être partagé car j'ai trouvé ce problème très complexe et sans réponse concise ou largement utile.

La regex suivante capturera des combinaisons de chiffres et de caractères largement utilisées dans une variété de formats de numéros de téléphone mondiaux:

/^\s*(?:\+?(\d{1,3}))?([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/gm

Positif:
+42 555.123.4567
+ 1- (800) -123-4567
+ 7555 1234567
+7 (926) 1234567
(926) 1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567469
123 45 67
89261234567
8 (926) 1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292

Négatif:
926 3 4
8800600-APPLE

Source d'origine: http://www.regexr.com/38pvb


Cela a un support limité pour les extensions. Il correspond à "616-555-1234 x567" mais pas à "616-555-1234 ext. 567".
Jon Schneider

2
Faux positif pour par exemple "------- ((((((55555555" ou "99999999999999999999999"
mikep

Il ne valide pas le numéro de MacDonalds de Nitherland +31 76 596 4192 (je
testais

10

Mon intuition est renforcée par la quantité de réponses à ce sujet - qu'il existe un nombre pratiquement infini de solutions à ce problème, dont aucune ne sera élégante.

Honnêtement, je vous recommande de ne pas essayer de valider les numéros de téléphone. Même si vous pouviez écrire un grand validateur velu qui autoriserait tous les différents formats légitimes, cela finirait par permettre à peu près n'importe quoi, même à distance, ressemblant à un numéro de téléphone en premier lieu.

À mon avis, la solution la plus élégante est de valider une longueur minimale, rien de plus.


Après avoir essayé un certain nombre d'entre eux et avoir parcouru les données existantes et les commentaires des utilisateurs, j'aurais tendance à être d'accord ...
Christopher King

Parfois, vous devez cependant effectuer une validation. Si j'envoie des codes de confirmation, je ne peux pas simplement envoyer un code à une poubelle aléatoire qu'un spammeur a entrée dans le champ. Je veux m'assurer que le numéro est probablement un numéro de téléphone avant de gaspiller des ressources à l'envoyer.
Luc

10

Il s'agit d'un modèle d'expression régulière simple pour les numéros de téléphone mobile philippins:

((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

ou

((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

correspondra à ceux-ci:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

Le premier correspondra à N'IMPORTE QUEL code de pays à deux chiffres, tandis que le second correspondra exclusivement au code de pays des Philippines.

Testez-le ici: http://refiddle.com/1ox


Merci. Que diriez-vous des numéros fixes avec l'indicatif régional tel que 028231234? Je me demande si les indicatifs régionaux ne sont que des nombres à 2 ou 3 chiffres et sont-ils toujours précédés de 0?
stormwild

9

Voici mon meilleur essai jusqu'à présent. Il gère les formats ci-dessus mais je suis sûr qu'il me manque d'autres formats possibles.

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$

9

Vous aurez du mal à traiter les numéros internationaux avec une expression rationnelle simple / simple, consultez cet article sur les difficultés des numéros de téléphone internationaux (et même nord-américains).

Vous souhaiterez analyser les premiers chiffres pour déterminer le code de pays, puis agir différemment en fonction du pays.

Au-delà de cela - la liste que vous avez donnée n'inclut pas un autre format américain commun - laissant de côté le premier 1. La plupart des téléphones cellulaires aux États-Unis n'en ont pas besoin, et cela commencera à dérouter la jeune génération à moins qu'ils aient composé le numéro international.

Vous avez correctement identifié qu'il s'agit d'un problème délicat ...

-Adam


Pas une solution proposée. C'EST POSSIBLE. Ce n'est pas parce que c'est délicat ou complexe que vous devez simplement lever les bras.
Eric Hodonsky

7

Après avoir lu ces réponses, il semble qu'il n'y avait pas d'expression régulière simple qui puisse analyser un tas de texte et extraire des numéros de téléphone dans n'importe quel format (y compris international avec et sans le signe plus).

Voici ce que j'ai utilisé récemment pour un projet client, où nous avons dû convertir tous les numéros de téléphone dans n'importe quel format en liens tel :.

Jusqu'à présent, cela fonctionne avec tout ce qu'ils ont lancé, mais si des erreurs surviennent, je mettrai à jour cette réponse.

Regex:

/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/

Fonction PHP pour remplacer tous les numéros de téléphone par des liens tel: (au cas où quelqu'un serait curieux):

function phoneToTel($number) {
    $return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
    return $return;
}

Cette expression régulière correspondait +1 1234562222222222222222222222.
Varda Elentári

pourquoi ne pas simplement revenir?
thexande

Faux positif pour "999999999999999999999999999999999999999"
Ben Wheeler

6

Je pense que les modules Perl Number :: Phone :: US et Regexp :: Common (en particulier la source de Regexp :: Common :: URI :: RFC2806 ) pourraient aider.

La question devrait probablement être précisée un peu plus en détail pour expliquer le but de la validation des nombres. Par exemple, 911 est un nombre valide aux États-Unis, mais 911x n'est pour aucune valeur de x. C'est pour que la compagnie de téléphone puisse calculer quand vous avez fini de composer. Il existe plusieurs variantes à ce sujet. Mais votre expression régulière ne vérifie pas la partie de l'indicatif régional, donc cela ne semble pas être un problème.

Comme la validation des adresses e-mail, même si vous avez un résultat valide, vous ne pouvez pas savoir s'il est attribué à quelqu'un avant de l'essayer.

Si vous essayez de valider l'entrée utilisateur, pourquoi ne pas normaliser le résultat et en finir avec lui? Si l'utilisateur saisit un numéro que vous ne pouvez pas reconnaître comme un numéro valide, enregistrez-le comme entré ou supprimez les caractères non disponibles. Le module Number :: Phone :: Normalize Perl pourrait être une source d'inspiration.


Je vais me lancer ici et dire que permettre le 911 comme numéro de téléphone est probablement une mauvaise idée dans presque toutes les applications de cette expression régulière. Bonne prise cependant.
Nicholas Flynt

4

Je travaille pour une société d'études de marché et nous devons filtrer ces types d'entrée tout le temps. Vous le compliquez trop. Supprimez simplement les caractères non alphanumériques et voyez s'il y a une extension.

Pour une analyse plus approfondie, vous pouvez vous abonner à l'un des nombreux fournisseurs qui vous donneront accès à une base de données de numéros valides et vous diront s'il s'agit de lignes fixes ou mobiles, déconnectées, etc. Cela coûte de l'argent.


Validation? 123% $) *% () $ * () # 456 * () * $ # (* (# $ @ 8908 correspondrait à votre solution proposée.
PlexQ

1
@PlexQ 555-123-1234, 07777777777, 90210, 01/01/1901 - les utilisateurs sont inventifs pour éperonner les ordures par le biais de la validation. Mieux vaut ne pas ticter ceux qui ont vraiment des données étranges en utilisant une validation trop restrictive et en leur disant qu'ils ont tort.
ReactiveRaven

4

Remplacez le formatage des caractères, puis vérifiez la validité du téléphone pour les autres. En PHP,

 $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
 preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

Briser une expression rationnelle complexe comme celle-ci peut être tout aussi efficace, mais beaucoup plus simple.


3

J'ai trouvé que c'était quelque chose d'intéressant. Je ne l'ai pas testé mais il semble que cela fonctionnerait

<?php
/*
string validate_telephone_number (string $number, array $formats)
*/

function validate_telephone_number($number, $formats)
{
$format = trim(ereg_replace("[0-9]", "#", $number));

return (in_array($format, $formats)) ? true : false;
}

/* Usage Examples */

// List of possible formats: You can add new formats or modify the existing ones

$formats = array('###-###-####', '####-###-###',
                 '(###) ###-###', '####-####-####',
                 '##-###-####-####', '####-####', '###-###-###',
                 '#####-###-###', '##########');

$number = '08008-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '123-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1800-1234-5678';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '(800) 555-123';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1234567890';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}
?>

4
Votre message semble indiquer que vous n'avez pas écrit ce code. Pourriez-vous citer une source, s'il vous plaît?
Alastair Irvine


3

Vous feriez probablement mieux d'utiliser une entrée masquée pour cela. De cette façon, les utilisateurs peuvent SEULEMENT entrer des nombres et vous pouvez formater comme bon vous semble. Je ne sais pas si c'est pour une application Web, mais si c'est le cas, il y a un plugin jQuery très cliqué qui offre quelques options pour le faire.

http://digitalbush.com/projects/masked-input-plugin/

Ils expliquent même comment masquer les entrées de numéro de téléphone dans leur didacticiel.


3

En voici une qui fonctionne bien en JavaScript. C'est dans une chaîne parce que c'est ce que le widget Dojo attendait.

Il correspond à un numéro NANP d'Amérique du Nord à 10 chiffres avec une extension facultative. Les espaces, tirets et points sont des délimiteurs acceptés.

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"

3

Je luttais avec le même problème, essayant de rendre ma demande pérenne, mais ces gars-là m'ont fait avancer dans la bonne direction. En fait, je ne vérifie pas le numéro lui-même pour voir s'il fonctionne ou non, j'essaie simplement de m'assurer qu'une série de chiffres a été saisie et peut avoir ou non une extension.

Dans le pire des cas, si l'utilisateur devait extraire un numéro non formaté du fichier XML, il ne ferait que taper les numéros dans le pavé numérique du téléphone 012345678x5, aucune raison réelle de le garder joli. Ce genre de RegEx sortirait quelque chose comme ça pour moi:

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890

2

Mon inclination est de convenir que supprimer les non-chiffres et accepter simplement ce qu'il y a de mieux. Peut-être pour s'assurer qu'au moins deux chiffres sont présents, bien que cela interdise quelque chose comme un numéro de téléphone alphabétique "ASK-JAKE" par exemple.

Quelques expressions perl simples peuvent être:

@f = /(\d+)/g;
tr/0-9//dc;

Utilisez le premier pour garder les groupes de chiffres ensemble, ce qui peut donner des indices de mise en forme. Utilisez le second pour lancer trivialement tous les non-chiffres.

Est-ce un souci qu'il puisse y avoir une pause et ensuite plus de touches saisies? Ou quelque chose comme 555-1212 (attendez le bip) 123?


2
    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

Doit se terminer par un chiffre, peut commencer par (ou + ou un chiffre, et peut contenir + - (ou)


2

Pour toute personne intéressée à faire quelque chose de similaire avec les numéros de téléphone mobile irlandais, voici une façon simple de le faire:

http://ilovenicii.com/?p=87

PHP


<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";

if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";

Il existe également une solution JQuery sur ce lien.

ÉDITER:

Solution jQuery:

    $(function(){
    //original field values
    var field_values = {
            //id        :  value
            'url'       : 'url',
            'yourname'  : 'yourname',
            'email'     : 'email',
            'phone'     : 'phone'
    };

        var url =$("input#url").val();
        var yourname =$("input#yourname").val();
        var email =$("input#email").val();
        var phone =$("input#phone").val();


    //inputfocus
    $('input#url').inputfocus({ value: field_values['url'] });
    $('input#yourname').inputfocus({ value: field_values['yourname'] });
    $('input#email').inputfocus({ value: field_values['email'] }); 
    $('input#phone').inputfocus({ value: field_values['phone'] });



    //reset progress bar
    $('#progress').css('width','0');
    $('#progress_text').html('0% Complete');

    //first_step
    $('form').submit(function(){ return false; });
    $('#submit_first').click(function(){
        //remove classes
        $('#first_step input').removeClass('error').removeClass('valid');

        //ckeck if inputs aren't empty
        var fields = $('#first_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<12 || value==field_values[$(this).attr('id')] ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }
        });        

        if(!error) {
            if( $('#password').val() != $('#cpassword').val() ) {
                    $('#first_step input[type=password]').each(function(){
                        $(this).removeClass('valid').addClass('error');
                        $(this).effect("shake", { times:3 }, 50);
                    });

                    return false;
            } else {   
                //update progress bar
                $('#progress_text').html('33% Complete');
                $('#progress').css('width','113px');

                //slide steps
                $('#first_step').slideUp();
                $('#second_step').slideDown();     
            }               
        } else return false;
    });

    //second section
    $('#submit_second').click(function(){
        //remove classes
        $('#second_step input').removeClass('error').removeClass('valid');

        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;  
        var fields = $('#second_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }


        function validatePhone(phone) {
        var a = document.getElementById(phone).value;
        var filter = /^[0-9-+]+$/;
            if (filter.test(a)) {
                return true;
            }
            else {
                return false;
            }
        }

        $('#phone').blur(function(e) {
            if (validatePhone('txtPhone')) {
                $('#spnPhoneStatus').html('Valid');
                $('#spnPhoneStatus').css('color', 'green');
            }
            else {
                $('#spnPhoneStatus').html('Invalid');
            $('#spnPhoneStatus').css('color', 'red');
            }
        });

     });

        if(!error) {
                //update progress bar
                $('#progress_text').html('66% Complete');
                $('#progress').css('width','226px');

                //slide steps
                $('#second_step').slideUp();
                $('#fourth_step').slideDown();     
        } else return false;

    });


    $('#submit_second').click(function(){
        //update progress bar
        $('#progress_text').html('100% Complete');
        $('#progress').css('width','339px');

        //prepare the fourth step
        var fields = new Array(
            $('#url').val(),
            $('#yourname').val(),
            $('#email').val(),
            $('#phone').val()

        );
        var tr = $('#fourth_step tr');
        tr.each(function(){
            //alert( fields[$(this).index()] )
            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
        });

        //slide steps
        $('#third_step').slideUp();
        $('#fourth_step').slideDown();            
    });


    $('#submit_fourth').click(function(){

        url =$("input#url").val();
        yourname =$("input#yourname").val();
        email =$("input#email").val();
        phone =$("input#phone").val();

        //send information to server
        var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone;  



        alert (dataString);//return false;  
            $.ajax({  
                type: "POST",  
                url: "http://clients.socialnetworkingsolutions.com/infobox/contact/",  
                data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone,
                cache: false,
                success: function(data) {  
                    console.log("form submitted");
                    alert("success");
                }
                });  
        return false;

   });


    //back button
    $('.back').click(function(){
        var container = $(this).parent('div'),
        previous  = container.prev();

        switch(previous.attr('id')) {
            case 'first_step' : $('#progress_text').html('0% Complete');
                  $('#progress').css('width','0px');
                       break;
            case 'second_step': $('#progress_text').html('33% Complete');
                  $('#progress').css('width','113px');
                       break;

            case 'third_step' : $('#progress_text').html('66% Complete');
                  $('#progress').css('width','226px');
                       break;

        default: break;
    }

    $(container).slideUp();
    $(previous).slideDown();
});


});

Source .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.