web-dev-qa-db-fra.com

Une regex complète pour la validation du numéro de téléphone

J'essaie de mettre au point une regex complète pour valider les numéros de téléphone. Idéalement, il devrait gérer les formats internationaux, mais il doit gérer les formats américains, notamment:

  • 1-234-567-8901
  • 1-234-567-8901, x 1234
  • 1-234-567-8901 ext1234
  • 1 (234) 567-8901
  • 1.234.567.8901
  • 1/234/567/8901
  • 12345678901

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

884
Nicholas Trandem

Meilleure option ... il suffit de supprimer tous les caractères non numériques de la saisie (à l'exception des signes 'x' et des signes '+'), en prenant garde en raison de la tendance britannique à écrire des nombres sous la forme non standard +44 (0) ... lorsqu'on lui a demandé d'utiliser l'international préfixe (dans ce cas précis, vous devriez jeter le (0) au complet).

Ensuite, vous vous retrouvez avec des valeurs telles que:

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

Ensuite, lorsque vous affichez, reformatez à votre guise le contenu. par exemple.

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

Il se trouve qu'il existe une sorte de spécification pour cela, du moins pour l'Amérique du Nord, appelée NANP .

Vous devez spécifier exactement ce que vous voulez. Que sont les délimiteurs légaux? Des espaces, des tirets et des points? 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) vont-elles être traité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 de 7 ou 10 chiffres, avec 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+))?$
294
Justin R.
.*

Si l'utilisateur veut vous donner son numéro de téléphone, faites-lui confiance pour bien faire les choses. S'il ne veut pas vous le donner, le forcer à entrer un numéro valide l'enverra soit sur le site d'un concurrent, soit lui fera entrer une chaîne aléatoire qui correspond à votre expression rationnelle. Je pourrais même être tenté de rechercher le nombre de lignes sexuelles à taux majoré et de le saisir à la place.

Je considérerais également les é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"
289
Dave Kirby

Je suggérerais également de consulter la bibliothèque Google " libphonenumber ". Je sais que ce n'est pas regex mais il fait exactement ce que tu veux.

Par exemple, il reconnaîtra que:

_15555555555
_

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

Principales fonctionnalités:

  • Analyser/formater/valider des numéros de téléphone pour tous les pays/régions du monde.
  • getNumberType - récupère le type du nombre en fonction du nombre lui-même; capable de distinguer les lignes fixes, mobiles, sans frais, à taux majoré, à coûts partagés, VoIP et numéros personnels (dans la mesure du possible).
  • isNumberMatch - obtient un niveau de confiance permettant de déterminer 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 - devine 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 d'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 en 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–2042_ est un numéro américain valide
    • _(999) 974–2042_ est un numéro américain non valide
  • Australie
    • _0404 999 999_ est un numéro australien valide
    • _(02) 9999 9999_ est également un numéro australien valide
    • _(09) 9999 9999_ n'est pas un numéro australien valide

Une expression régulière convient bien pour vérifier le format d'un numéro de téléphone, mais elle ne pourra pas vraiment vérifier la validité d'un numéro de téléphone.

Je suggérerais de ne pas utiliser une expression régulière simple pour tester votre numéro de téléphone et d'utiliser une bibliothèque telle que celle de 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 une démonstration 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 (quel qu'il soit), mais vous obtenez également un formatage de numéro de téléphone cohérent dans votre pays.

En prime, libphonenumber dispose d'un certain nombre de jeux de données pour vérifier la validité des numéros de téléphone. Vérifiez donc un numéro tel que _+61299999999_ (version internationale de (02) 9999 9999 ) renvoie sous forme de nombre valide avec formatage:

_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é, ainsi que 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 ) indique 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 contient du code pour Java et Javascript, mais des personnes ont également implémenté des bibliothèques pour d'autres langues utilisant le jeu de données de numéro de téléphone Google i18n:

À moins que vous ne soyez certain d'accepter toujours des numéros d'un même endroit et qu'ils soient toujours dans un seul format, je suggérerais 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.

159
Halfwarr

/^(?:(?:\(?(?: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 enregistre:

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

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

73
Ismael Miguel

Bien que la solution pour éliminer tous les espaces blancs soit nette, cela ne résout pas vraiment le problème posé, à savoir la recherche d'une expression régulière. Prenons, 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 la regex. Comme vous auriez besoin de toute façon d'une expression régulière, vous pourriez également demander à cette expression 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 faites correspondre, $ 1 contient l'indicatif régional, $ 2 et $ 3 contiennent le numéro de téléphone et $ 5, l'extension. Mon script de test télécharge un fichier sur Internet et imprime tous les numéros de téléphone qu'il contient.

#!/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";
        }
}

Edit:

Vous pouvez changer\W * en\s *\W?\S * dans la regex pour le resserrer un peu. Je ne pensais pas à l'expression régulière en termes de validation d'une entrée d'utilisateur sur un formulaire lorsque je l'ai écrit, mais cette modification rend possible l'utilisation de 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*))?';
63
indiv

J'ai répondu à cette question sur une autre SO question avant de décider d'inclure également ma réponse en tant que réponse à ce fil, car personne ne demandait comment exiger/ne pas exiger des éléments, se contentant de distribuer des expressions rationnelles: La regex ne fonctionne pas correctement, elle associe des choses inattendues

À partir de mon post sur ce site, j'ai créé un guide rapide pour aider toute personne à créer son propre regex pour le format de numéro de téléphone souhaité, ce que je tiens à rappeler (comme je l'ai fait sur l'autre site): 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, mais uniquement ce que vous décidez d'accepter comme format de votre choix. À utiliser à vos risques et périls.

Aide-mémoire rapide

  • Commencez l'expression: /^
  • Si vous souhaitez demander un espace, utilisez: [\s] ou \s
  • Si vous souhaitez exiger des parenthèses, utilisez: [(] et [)]. Utiliser \( et \) est laid et peut rendre les choses confuses.
  • Si vous voulez que quelque chose soit facultatif, mettez un ? après
  • Si vous voulez un trait d'union, tapez simplement - ou [-]. Si vous ne le mettez pas d'abord ou dernier dans une série d'autres caractères, vous devrez peut-être l'échapper: \-
  • Si vous souhaitez accepter différents choix dans un emplacement, mettez des options entre crochets: [-.\s] nécessitera un trait d'union, un point ou un espace. Un point d'interrogation après le dernier crochet rendra toutes ces options facultatives pour cet emplacement.
  • \d{3}: Requiert un nombre à 3 chiffres: 000-999. Raccourci pour [0-9][0-9][0-9].
  • [2-9]: Nécessite un chiffre entre 2 et 9 pour cet emplacement.
  • (\+|1\s)?: Acceptez un "plus" ou un 1 et un espace (caractère de pipe, |, est "ou") et rendez-le facultatif. Le signe "plus" doit être échappé.
  • Si vous souhaitez que des numéros spécifiques correspondent à un emplacement, entrez-les: [246] nécessitera 2, 4 ou 6. [77|78] nécessitera 77 ou 78.
  • $/: Termine l'expression
41
vapcguy

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

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

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

28
Artjom Kurapov

Notez que l'effacement des caractères _()_ ne fonctionne pas pour un style d'écriture de numéros britanniques commun: +44 (0) 1234 567890, ce qui signifie que vous devez composer le numéro international:
_+441234567890_
ou au Royaume-Uni, composez le _01234567890_

22
Ben Clifford

Si vous voulez juste vérifier que vous n’avez pas d’ordures aléatoires dans le champ (c’est-à-dire des spammeurs de formulaire), cette expression rationnelle devrait faire l'affaire:

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

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

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

Si vous souhaitez conserver des règles par chiffre (comme dans les indicatifs régionaux américains et les préfixes (codes d’échange) doivent se situer dans la plage allant de 200 à 999), bonne chance à vous. Il n’est pas amusant de maintenir un ensemble de règles complexes qui pourraient devenir obsolètes à n’importe quel moment dans l’avenir de n’importe quel pays du monde.

Et bien que supprimer tous/la plupart des caractères non numériques puisse fonctionner correctement côté serveur (surtout si vous envisagez de transmettre ces valeurs à un numéroteur), vous pouvez ne pas vouloir masquer les entrées de l'utilisateur lors de la validation, en particulier si vous le souhaitez. faire des corrections dans un autre domaine.

21
Steve

Avez-vous jeté un œil à RegExLib ?

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

15
Rob Wells

J'ai trouvé que cela fonctionne 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 nombres:

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

12
Herobrine2Nether

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'afficher. Après l'avoir validé pourrait être un nombre cependant.

12
ReactiveRaven

Si vous parlez de validation de formulaire, l'expression rationnelle destinée à valider le sens correct ainsi que les données correctes sera extrêmement complexe en raison de la diversité des normes de pays et de fournisseurs. Il sera également difficile de se tenir au courant.

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 nombres valide, mais ne validant pas le fait que la ligne de jonction, l'échange, etc. correspond 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 la façon dont les gens spécifient et se souviennent de leur nombre:

^((((\(\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. Les comptes internationaux pour 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 est limitée à l’Amérique du Nord, à l’Europe et à une petite partie de l’Asie.

11
ron0

Il s'agit d'un modèle d'expression régulière simple pour les numéros de téléphone portable 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 à TOUT code de pays à deux chiffres, tandis que le second correspondra exclusivement au code de pays des Philippines.

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

10
GaiusSensei

Mon instinct est renforcé par le nombre 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 gros validateur poilu qui autoriserait tous les différents formats légitimes, il autoriserait pratiquement tout ce qui pourrait ressembler à un numéro de téléphone.

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

10
mindplay.dk

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

Les expressions régulières suivantes intercepteront les combinaisons de chiffres et de caractères largement utilisées dans divers formats de numéros de téléphone:

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

Positif:
+ 42 555.123.4567
+ 1 800) -123-4567
+ 7 555 1234567
+ 7 (926) 1234567
(926) 1234567
+ 79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 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
8 800 600-Apple

Source originale: --- (http://www.regexr.com/38pvb

9
Stuart Kershaw

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

Vous voudrez 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 commun aux États-Unis - en laissant de côté le premier 1. La plupart des téléphones cellulaires aux États-Unis n'en ont pas besoin, et ils vont commencer à dérouter la jeune génération à moins qu'elle ait composé le numéro international.

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

-Adam

9
Adam Davis

Voici mon meilleur essai jusqu'à présent. Il gère les formats ci-dessus, mais je suis certain 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}))?$
8
Nicholas Trandem

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 textes et extraire des numéros de téléphone dans n’importe quel format (y compris les caractères internationaux 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, quel que soit leur format, en liens tel:.

Jusqu'à présent, cela fonctionne avec tout ce qu'ils ont jeté, mais si des erreurs se produisent, 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;
}
8
Drew Thomas

Je crois que le Number :: Phone :: US et Regexp :: Common (en particulier la source de Regexp :: Common :: URI :: RFC2806 =) Les modules Perl pourraient aider.

La question devrait probablement être spécifié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 ne s'applique à aucune valeur de x. C’est pour que la compagnie de téléphone puisse calculer le moment où vous avez composé le numéro. Il existe plusieurs variantes sur ce problème. Mais votre regex ne vérifie pas la portion d'indicatif régional, donc cela ne semble pas être un problème.

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

Si vous essayez de valider la saisie de l'utilisateur, pourquoi ne pas normaliser le résultat et en finir? Si l'utilisateur entre un nombre que vous ne pouvez pas reconnaître comme un nombre valide, sauvegardez-le comme saisie ou supprimez les caractères indisponibles. Le module Number :: Phone :: Normalize Perl pourrait être une source d’inspiration.

6
Jon Ericson

Je travaille pour une entreprise d’études de marché et nous devons filtrer ces types d’intrants à tout moment. Tu compliques trop. Il suffit de supprimer les caractères non alphanumériques et de voir s’il existe 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 indiqueront s'il s'agit de lignes fixes ou mobiles, déconnectés, etc. Cela coûte de l'argent.

4
Joe Phillips

Remplacez les caractères de formatage, puis vérifiez la validité du téléphone restant. 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 );

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

4
rooskie

Vous feriez probablement mieux d'utiliser une entrée masquée pour cela. De cette façon, les utilisateurs peuvent SEULEMENT saisir des chiffres et vous pouvez formater comme bon vous semble. Je ne suis pas sûr que ce soit pour une application Web, mais si c'est le cas, il existe un plugin très clic jQuery qui offre certaines options pour le faire.

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

Ils vont même jusqu'à masquer les entrées de numéros de téléphone dans leur tutoriel.

3
Abe Miessler

Je me débattais avec le même problème, essayant de faire en sorte que ma candidature soit une preuve pour l'avenir, mais ces gars-là m'ont permis d'aller dans la bonne direction. 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 numéros a été entrée avec ou sans extension.

Dans le pire des cas, si l'utilisateur devait extraire un numéro non formaté du fichier XML, il lui suffirait de taper les numéros dans le pavé numérique du téléphone 012345678x5, sans véritable raison de le garder en beauté. Ce genre de RegEx produirait quelque chose comme ça pour moi:

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

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

Il correspond à un numéro NANP nord-américain à 10 chiffres avec extension facultative. Les espaces, les tirets et les points sont des délimiteurs acceptés.

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

J'ai trouvé cela 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.';
}
?>
3
Chris

Mon penchant est d’accorder le fait de ne pas prendre de chiffres et d’accepter simplement ce qui est meilleur. Peut-être pour assurer au moins deux chiffres, bien que cela interdise par exemple un numéro de téléphone alphabétique "ASK-JAKE".

Quelques expressions simples en Perl pourraient être:

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

Utilisez le premier pour conserver les groupes de chiffres ensemble, ce qui peut donner des indices de formatage. Utilisez le second pour lancer trivialement tous les autres chiffres.

Vous inquiétez-vous du fait qu'il peut être nécessaire de faire une pause puis de saisir d'autres clés? Ou quelque chose comme 555-1212 (attendez le bip) 123?

2
piCookie
    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
Ian

Pour toute personne intéressée à faire quelque chose de similaire avec les numéros de téléphone mobile irlandais, voici une manière simple de le réaliser:

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.

MODIFIER:

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 .

2
Bob-ob

Comme il n'y a pas d'étiquette de langue dans cet article, je vais vous donner une solution regex utilisée dans python.

L'expression elle-même:

1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+

Lorsqu'il est utilisé dans python:

import re

phonelist ="1-234-567-8901,1-234-567-8901 1234,1-234-567-8901 1234,1 (234) 567-8901,1.234.567.8901,1/234/567/8901,12345678901"

phonenumber = '\n'.join([phone for phone in re.findall(r'1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+' ,phonelist)])
print(phonenumber)

Sortie:

1-234-567-8901
1-234-567-8901 1234
1-234-567-8901 1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
1
SIM

Je ne recommanderais pas d'utiliser une regex pour cela.

Comme pour la réponse principale, supprimez toute la laideur du numéro de téléphone, de sorte à vous laisser avec une chaîne de caractères numériques, avec un 'x', si des extensions sont fournies.

En Python:

Remarque: BAD_AREA_CODES provient d'un fichier texte que vous pouvez récupérer sur le Web.

BAD_AREA_CODES = open('badareacodes.txt', 'r').read().split('\n')

def is_valid_phone(phone_number, country_code='US'):
    """for now, only US codes are handled"""
    if country_code:
        country_code = country_code.upper()

    #drop everything except 0-9 and 'x'
    phone_number = filter(lambda n: n.isdigit() or n == 'x', phone_number)

    ext = None
    check_ext = phone_number.split('x')
    if len(check_ext) > 1:
        #there's an extension. Check for errors.
        if len(check_ext) > 2:
            return False
        phone_number, ext = check_ext

    #we only accept 10 digit phone numbers.
    if len(phone_number) == 11 and phone_number[0] == '1':
        #international code
        phone_number = phone_number[1:]
    if len(phone_number) != 10:
        return False

    #area_code: XXXxxxxxxx 
    #head:      xxxXXXxxxx
    #tail:      xxxxxxXXXX
    area_code = phone_number[ :3]
    head      = phone_number[3:6]
    tail      = phone_number[6: ]

    if area_code in BAD_AREA_CODES:
        return False
    if head[0] == '1':
        return False
    if head[1:] == '11':
        return False

    #any other ideas?
    return True

Cela couvre un peu. Ce n'est pas une regex, mais cela mappe assez facilement vers d'autres langues.

1
Droogans

Est-il possible d'avoir pour l'affichage 4 champs distincts (indicatif régional, préfixe à 3 chiffres, partie à 4 chiffres, extension) afin qu'ils puissent saisir chaque partie de l'adresse séparément et que vous puissiez vérifier chaque élément individuellement? De cette façon, vous pouvez non seulement simplifier la vérification, mais également stocker vos numéros de téléphone dans un format plus cohérent dans la base de données.

1
Kibbee

Trouvez String regex = "^\\+(?:[0-9] ?){6,14}[0-9]$";

utile pour les numéros internationaux.

1
Sai prateek

Il est presque impossible de gérer toutes sortes de numéros de téléphone internationaux avec de simples regex.

Vous feriez mieux d'utiliser un service tel que numverify.com, ils offrent une API JSON gratuite pour les téléphones internationaux. la validation du numéro, vous obtiendrez également des informations utiles sur le pays, la localisation, le transporteur et le type de ligne à chaque demande.

1
Frank

Exemple de travail pour la Turquie, il suffit de changer le

d{9}

selon vos besoins et commencez à l'utiliser.

function validateMobile($phone)
{
    $pattern = "/^(05)\d{9}$/";
    if (!preg_match($pattern, $phone))
    {
        return false;
    }
    return true;
}

$phone = "0532486061";

if(!validateMobile($phone))
{
    echo 'Incorrect Mobile Number!';
}

$phone = "05324860614";
if(validateMobile($phone))
{
    echo 'Correct Mobile Number!';
}
1
Sinan Eldem

Essayez ceci (c'est pour la validation du numéro de portable indien):

if (!phoneNumber.matches("^[6-9]\\d{9}$")) {
  return false;
} else {
  return true;
}
0
Shylendra Madda

Remarque Il faut entrer un numéro de mobile américain dans n'importe quel format et éventuellement accepter un deuxième paramètre - définissez true si vous voulez que le numéro de mobile de sortie soit formaté de façon esthétique. Si le numéro fourni n'est pas un numéro de mobile, la valeur renvoyée est fausse. Si un numéro de portable IS est détecté, il renvoie le numéro assaini complet au lieu de true.

    function isValidMobile(num,format) {
        if (!format) format=false
        var m1 = /^(\W|^)[(]{0,1}\d{3}[)]{0,1}[.]{0,1}[\s-]{0,1}\d{3}[\s-]{0,1}[\s.]{0,1}\d{4}(\W|$)/
        if(!m1.test(num)) {
           return false
        }
        num = num.replace(/ /g,'').replace(/\./g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'').replace(/\[/g,'').replace(/\]/g,'').replace(/\+/g,'').replace(/\~/g,'').replace(/\{/g,'').replace(/\*/g,'').replace(/\}/g,'')
        if ((num.length < 10) || (num.length > 11) || (num.substring(0,1)=='0') || (num.substring(1,1)=='0') || ((num.length==10)&&(num.substring(0,1)=='1'))||((num.length==11)&&(num.substring(0,1)!='1'))) return false;
        num = (num.length == 11) ? num : ('1' + num);   
        if ((num.length == 11) && (num.substring(0,1) == "1")) {
            if (format===true) {
               return '(' + num.substr(1,3) + ') ' + num.substr(4,3) + '-' + num.substr(7,4)
            } else {
               return num
            }
        } else {
            return false;
        }
    }
0
Gautam Sharma