Quelle expression régulière correspondra aux numéros de téléphone internationaux valides?


113

Je dois déterminer si un numéro de téléphone est valide avant d'essayer de le composer. L'appel téléphonique peut aller n'importe où dans le monde.

Quelle expression régulière correspondra aux numéros de téléphone internationaux valides?


Comment une expression régulière gère-t-elle les erreurs telles que les numéros hors service? Essayez simplement d'appeler et de gérer le nombre invalide comme vous le feriez pour d'autres erreurs.

3
Bien que vous ayez raison de dire que l'expression régulière ne peut pas le déterminer, chaque tentative sortante consomme du temps et des ressources. Faire une vérification rapide du bon sens du numéro garantit qu'un appel manifestement faux ne bloque pas un canal précieux.
Abtin Forouzandeh

1
LOL @ paxdiablo .... Je suppose que 1-800-CALL-HELP passera votre test RegExp ... lol
Buhake Sindi

1
Quelque chose qui n'est pas clair dans cette question est de savoir si les numéros doivent être valides s'ils sont appelés des États-Unis ou de n'importe quel pays du monde, car la plupart des solutions ci-dessous ne valident pas certains numéros valides (tels que 0030210 12312312 - un Numéro grec appelé depuis n'importe quel pays de l'UE)
Xeroxoid

1
@JonHanna Je suis d'accord sur un point, mais d'un autre côté, du point de vue UX, ne pensez-vous pas que si un utilisateur entre un 00XX ... X nombre, le test devrait réussir? Il y a des cas où les utilisateurs (c'est-à-dire les personnes âgées) ne savent même pas ce qu'est le + et comment le saisir sur un clavier numérique / téléphonique. Aussi je pourrais encore soutenir que 00XXX est un numéro international valide (c'est-à-dire dans le contexte d'un utilisateur) où au lieu du +, le code de sortie a été utilisé.
Xeroxoid

Réponses:


96
\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{1,14}$

Est le format correct pour faire correspondre un numéro de téléphone international générique. J'ai remplacé le code d'accès international 011 centré sur la ligne terrestre américaine par l'identifiant standard du code d'accès international «+», ce qui le rend obligatoire. J'ai également changé le minimum du numéro national à au moins un chiffre.

Notez que si vous entrez des numéros dans ce format dans le carnet d'adresses de votre téléphone mobile, vous pouvez appeler avec succès n'importe quel numéro de votre carnet d'adresses, peu importe où vous voyagez. Pour les lignes fixes, remplacez le signe plus par le code d'accès international du pays à partir duquel vous composez.

Notez que cela NE prend PAS en compte les règles du plan de numérotation national - en particulier, cela autorise les zéros et les uns dans les emplacements que les plans de numérotation nationaux peuvent ne pas autoriser et autorise également des longueurs de numéro supérieures au plan de numérotation national pour certains pays (par exemple, les États-Unis).


5
Cela me semble raisonnable. Je vais utiliser celui-ci
Sevenearths

17
Ceci n'est pas valable. Les numéros de téléphone européens peuvent commencer par un double 0 sans un + au début. Ainsi, un numéro de téléphone tel que: +44 8984 1234 (UK) est également parfaitement valide s'il est écrit 0044 8984 1234 que cette expression régulière (et sur d'autres réponses également) ne prend pas en charge.
Xeroxoid

4
Combiné avec les améliorations de @ fezfox (?) Et la longueur optimisée:^\+((?:9[679]|8[035789]|6[789]|5[90]|42|3[578]|2[1-689])|9[0-58]|8[1246]|6[0-6]|5[1-8]|4[013-9]|3[0-469]|2[70]|7|1)(?:\W*\d){0,13}\d$
SamWhan

1
+1. Du point de vue UX, oui, il pourrait être judicieux d'autoriser 00devant. Du point de vue du développement et de la maintenance, je dirais que c'est parfaitement bien d'appliquer tous les numéros pour commencer +ou même de les remplacer 00par un à +chaque fois que vous l'obtenez - d'autant plus que la plupart des gens connaissent le +format (que la plupart des champs de saisie téléphoniques internationaux exiger de toute façon). De plus, c'est une solution à une seule ligne et beaucoup plus lisible. Cette approche garantirait également que tous les numéros de téléphone sont dans le même format et rend votre validation beaucoup moins sujette aux erreurs, ce qui rend l'ensemble plus facile à gérer.
milosmns

1
Et aussi, dans les «vieux» jours du SMS pré-EDGE (GSM ordinaire), l'utilisation 00n'envoyait pas le message correctement, alors que commencer par a +fonctionnerait toujours à l'international. Nous pouvons devenir fous et rendre les choses super complexes, mais parfois c'est possible / cela vaut la peine de laisser tomber quelques contraintes pour nous rendre la vie plus facile :)
milosmns

66

Tous les codes de pays sont définis par l'UIT. L'expression régulière suivante est basée sur l'UIT-T E.164 et l' Annexe du Bulletin d'exploitation de l'UIT No 930 - 15.IV.2009 . Il contient tous les codes de pays actuels et les codes réservés pour une utilisation future. Bien que cela puisse être un peu raccourci, j'ai décidé d'inclure chaque code indépendamment.

Ceci est pour les appels provenant des États-Unis. Pour les autres pays, remplacez le code d'accès international (le 011 au début de l'expression régulière) par tout ce qui est approprié pour le plan de numérotation de ce pays .

Notez également que l'UIT E.164 définit la longueur maximale d'un numéro de téléphone international complet à 15 chiffres. Cela signifie qu'un code de pays à trois chiffres donne jusqu'à 12 chiffres supplémentaires, et un code de pays à 1 chiffre peut contenir jusqu'à 14 chiffres supplémentaires. D'où le

[0-9]{0,14}$

a la fin de l'expression régulière.

Plus important encore, cette expression régulière ne signifie pas que le numéro est valide - chaque pays définit son propre plan de numérotation interne. Cela garantit seulement que le code du pays est valide.

283 | 282 | 281 | 280 | 269 | 268 | 267 | 266 | 265 | 264 | 263 | 262 | 261 | 260 | 259 | 258 | 257 | 256 | 255 | 254 | 253 | 252 | 251 | 250 | 249 | 248 | 247 | 246 | 245 | 244 | 243 | 242 | 241 | 240 | 239 | 238 | 237 | 236 | 235 | 234 | 233 | 232 | 231 | 230 | 229 | 228 | 227 | 226 | 225 | 224 | 223 | 222 | 221 | 220 | 219 | 218 | 217 | 216 | 215 | 214 | 213 | 212 | 211 | 210 | 98 | 95 | 94 | 93 | 92 | 91 | 90 | 86 | 84 | 82 | 81 | 66 | 65 | 64 | 63 | 62 | 61 | 60 | 58 | 57 | 56 | 55 | 54 | 53 | 52 | 51 | 49 | 48 | 47 | 46 | 45 | 44 | 43 | 41 | 40 | 39 | 36 | 34 | 33 | 32 | 31 | 30 | 27 | 20 | 7 | 1) [0-9] {0, 14} $


12
Presque avait raison ... "011" ne fait pas partie d'un code international. C'est exactement ce que les Américains doivent composer pour passer un appel international. Ce préfixe changera en fonction de l'endroit d'où vous composez ... Donc ce préfixe ne fait PAS partie du numéro.
Gabriel Magana

3
@gmagana - Je le mentionne dans ma réponse (paragraphe 2)
Abtin Forouzandeh

1
Ce que je veux dire, c'est que cela ne fait pas partie du numéro de téléphone. Cela revient à dire que le préfixe d'appel interurbain national américain «1» fait partie du numéro de téléphone.
Gabriel Magana

1
@gmagana - bien que vous ayez raison de dire que cela ne fait pas partie du numéro de téléphone, il est techniquement nécessaire de passer l'appel.
Abtin Forouzandeh

2
@Roger Pate: J'ai passé un peu de temps à comprendre cela et j'espère que cela sera utile aux autres. J'espérais aussi que quelqu'un d'autre pourrait avoir une meilleure solution (c'est pourquoi je n'ai pas marqué ma propre réponse comme acceptée).
Abtin Forouzandeh

32

C'est une optimisation supplémentaire.

\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)
\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*(\d{1,2})$

(i) permet des préfixes internationaux valides
(ii) suivis de 9 ou 10 chiffres, avec n'importe quel type ou placement de délimiteurs (sauf entre les deux derniers chiffres)

Cela correspondra:
+ 1-234-567-8901
+ 61-234-567-89-01
+ 46-234 5678901
+1 (234) 56
89901 +1 (234) 56-89 901
+46.234.567.8901
+1 / 234/567/8901


Je sais que c'est une vieille réponse, mais y a-t-il une option pour rendre le 1 facultatif pour les numéros américains?
Adam Fratino

Ce que vous voulez faire, c'est (i) rendre le "+" facultatif et (ii) le code international facultatif. Alors placez "?" après le + et après la première parenthèse fermée.
fezfox

@ManosPasgiannis bien oui, comme spécifié "suivi de 9 ou 10 chiffres". Il apparaîtrait à Chypre que vous utilisez 8, donc ajustez simplement la dernière séquence en supprimant une fois l'instance de \ d \ W * et créez la dernière expression (\ d {1,3})
fezfox

22

Vous pouvez utiliser la bibliothèque libphonenumber de Google.

PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
String decodedNumber = null;
PhoneNumber number;
    try {
        number = phoneNumberUtil.parse(encodedHeader, null);
        decodedNumber = phoneNumberUtil.format(number, PhoneNumberFormat.E164);
    } catch (NumberParseException e) {
        e.printStackTrace();
    }

2
Cela pourrait être une bonne solution mais juste pour vérifier les numéros de téléphone, avant d'utiliser cette bibliothèque, vous devez importer une énorme quantité de js ... car libphonenumber.js a besoin d'une bibliothèque de fermeture ... ce n'est pas une solution légère: /
J. BizMai

11

Cela fonctionnera pour les numéros internationaux;

C #:

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

JS:

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

11

J'utilise celui-ci:

/([0-9\s\-]{7,})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/

Avantages: reconnaît les débuts + ou 011, le laisse être aussi long que nécessaire et gère de nombreuses conventions d'extension. (#, x, ext, extension)


Celui-ci est assez proche de la plupart des formats de numéros de téléphone internationaux.
feeela

9

Voici une version "optimisée" de votre regex:

^011(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{0,14}$

Vous pouvez remplacer le \ds par [0-9]si votre syntaxe regex ne prend pas en charge \d.



6

Expression régulière modifiée de @ Eric - ajout d'une liste de tous les codes de pays (obtenu de xxxdepy @ Github . J'espère que vous le trouverez utile:

/(\+|00)(297|93|244|1264|358|355|376|971|54|374|1684|1268|61|43|994|257|32|229|226|880|359|973|1242|387|590|375|501|1441|591|55|1246|673|975|267|236|1|61|41|56|86|225|237|243|242|682|57|269|238|506|53|5999|61|1345|357|420|49|253|1767|45|1809|1829|1849|213|593|20|291|212|34|372|251|358|679|500|33|298|691|241|44|995|44|233|350|224|590|220|245|240|30|1473|299|502|594|1671|592|852|504|385|509|36|62|44|91|246|353|98|964|354|972|39|1876|44|962|81|76|77|254|996|855|686|1869|82|383|965|856|961|231|218|1758|423|94|266|370|352|371|853|590|212|377|373|261|960|52|692|389|223|356|95|382|976|1670|258|222|1664|596|230|265|60|262|264|687|227|672|234|505|683|31|47|977|674|64|968|92|507|64|51|63|680|675|48|1787|1939|850|351|595|970|689|974|262|40|7|250|966|249|221|65|500|4779|677|232|503|378|252|508|381|211|239|597|421|386|46|268|1721|248|963|1649|235|228|66|992|690|993|670|676|1868|216|90|688|886|255|256|380|598|1|998|3906698|379|1784|58|1284|1340|84|678|681|685|967|27|260|263)(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{4,20}$/

Fonctionne comme un charme. Pour les numéros de téléphone néerlandais également. Merci!
Mauvm

2

Il y a évidemment une multitude de façons de le faire, comme en témoignent toutes les différentes réponses données jusqu'à présent, mais je vais jeter ma valeur de 0,02 $ ici et fournir le regex ci-dessous, ce qui est un peu plus laconique que presque tout ce qui précède , mais plus approfondi que la plupart des autres. Il a également le bon effet secondaire de laisser le code du pays en 1 $ et le numéro local en 2 $.

^ \ + (? = \ d {5,15} $) (1 | 2 [078] | 3 [0-469] | 4 [013-9] | 5 [1-8] | 6 [0-6] | 7 | 8 [1-469] | 9 [0-58] | [2-9] ..) (\ d +) $


2

Aucune critique concernant ces excellentes réponses, je veux juste présenter la solution simple que j'utilise pour nos créateurs de contenu administrateur:

^(\+|00)[1-9][0-9 \-\(\)\.]{7,}$

Forcer le début avec un plus ou deux zéros et utiliser au moins un peu de chiffres, un espace blanc, des accolades, un signe moins et un point est facultatif et aucun autre caractère. Vous pouvez supprimer en toute sécurité tous les non-nombres et l'utiliser dans une entrée tel :. Les nombres auront une forme de représentation commune et je n'ai pas à me soucier d'être trop restrictif.


1

Une version simple pour les numéros européens, qui correspond à des numéros comme 0034617393211 mais aussi à des numéros longs comme 004401484172842.

^0{2}[0-9]{11,}

J'espère que ça aide :·)


1
public static boolean validateInternationalPhoneNumberFormat(String phone) {
    StringBuilder sb = new StringBuilder(200);

    // Country code
    sb.append("^(\\+{1}[\\d]{1,3})?");

    // Area code, with or without parentheses
    sb.append("([\\s])?(([\\(]{1}[\\d]{2,3}[\\)]{1}[\\s]?)|([\\d]{2,3}[\\s]?))?");

    // Phone number separator can be "-", "." or " "

    // Minimum of 5 digits (for fixed line phones in Solomon Islands)
    sb.append("\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?\\d[\\-\\.\\s]?");

    // 4 more optional digits
    sb.append("\\d?[\\-\\.\\s]?\\d?[\\-\\.\\s]?\\d?[\\-\\.\\s]?\\d?$");

    return Pattern.compile(sb.toString()).matcher(phone).find();
}

1
Bien que cet extrait de code puisse répondre à la question, il ne fournit aucun contexte pour expliquer comment ou pourquoi. Pensez à ajouter une phrase ou deux pour expliquer votre réponse.
brandonscript

1

Voici une expression régulière pour les scénarios de numéro de téléphone les plus courants suivants. Bien que cela soit adapté du point de vue américain pour les indicatifs régionaux, cela fonctionne pour les scénarios internationaux.

  1. Le nombre réel ne doit comporter que 10 chiffres.
  2. Pour les numéros américains, l'indicatif régional peut être entouré de parenthèses ().
  3. Le code du pays peut comporter de 1 à 3 chiffres. Peut éventuellement être précédé d'un signe +.
  4. Il peut y avoir des tirets, des espaces, des points ou aucun espace entre l'indicatif du pays, l'indicatif régional et le reste du nombre.
  5. Un numéro de téléphone valide ne peut pas être composé uniquement de zéros.

    ^(?!\b(0)\1+\b)(\+?\d{1,3}[. -]?)?\(?\d{3}\)?([. -]?)\d{3}\3\d{4}$

Explication:

    ^ - start of expression  
    (?!\b(0)\1+\b) - (?!)Negative Look ahead. \b - word boundary around a '0' character. \1 backtrack to previous capturing group (zero). Basically don't match all zeros.  
    (\+?\d{1,3}[. -]?)? - '\+?' plus sign before country code is optional.\d{1,3} - country code can be 1 to 3 digits long. '[. -]?' - spaces,dots and dashes are optional. The last question mark is to make country code optional.  
    \(?\d{3}\)? - '\)?' is to make parentheses optional. \d{3} - match 3 digit area code.  
    ([. -]?) - optional space, dash or dot
    $ - end of expression

Plus d'exemples et d'explications - https://regex101.com/r/hTH8Ct/2/


1

J'ai utilisé ceci ci-dessous:

^(\+|00)[0-9]{1,3}[0-9]{4,14}(?:x.+)?$

Le format + CCC.NNNNNNNNNNxEEEE ou 00CCC.NNNNNNNNNNxEEEE

Le numéro de téléphone doit commencer par «+» ou «00» pour un appel international. où C est le code du pays à 1 à 3 chiffres,

N comprend jusqu'à 14 chiffres,

et E est l'extension (facultative).

Le signe plus au début et le point suivant le code du pays sont obligatoires. Le caractère littéral «x» n'est requis que si une extension est fournie.



0

Le plan de numérotage international est basé sur le plan de numérotage UIT E.164 . Je suppose que c'est le point de départ de votre expression régulière.

Je mettrai à jour ceci si je me déplace pour créer une expression régulière basée sur la numérotation ITU E.164.


0

Cette expression Regex fonctionne pour les numéros de téléphone de l'Inde, du Canada, de l'Europe, de la Nouvelle-Zélande, de l'Australie et des États-Unis, ainsi que leurs codes de pays:

"^(\+(([0-9]){1,2})[-.])?((((([0-9]){2,3})[-.]){1,2}([0-9]{4,10}))|([0-9]{10}))$"


0

Cela fonctionne pour moi, sans le préfixe 00, 001, 0011, etc.

/^\+*(\d{3})*[0-9,\-]{8,}/



0

J'ai créé l'expression régulière pour les numéros de téléphone européens, et elle est spécifique au préfixe de numérotation par rapport à la longueur du numéro.

const PhoneEuropeRegExp = () => {
    // eu phones map https://en.wikipedia.org/wiki/Telephone_numbers_in_Europe
    const phonesMap = {
        "43": [4, 13],
        "32": [8, 10],
        "359": [7, 9],
        "385": [8, 9],
        "357": 8,
        "420": 9,
        "45": 8,
        "372": 7,
        "358": [5, 12],
        "33": 9,
        "350": 8,
        "49": [3, 12],
        "30": 10,
        "36": [8, 9],
        "354": [7, 9],
        "353": [7, 9],
        "39": [6, 12],
        "371": 8,
        "423": [7, 12],
        "370": 8,
        "352": 8,
        "356": 8,
        "31": 9,
        "47": [4, 12],
        "48": 9,
        "351": 9,
        "40": 9,
        "421": 9,
        "386": 8,
        "34": 9,
        "46": [6, 9],
    };
    const regExpBuilt = Object.keys(phonesMap)
        .reduce(function(prev, key) {
            const val = phonesMap[key];
            if (Array.isArray(val)) {
                prev.push("(\\+" + key + `[0-9]\{${val[0]},${val[1]}\})`);
            } else {
                prev.push("(\\+" + key + `[0-9]\{${val}\})`);
            }
            return prev;
        }, [])
        .join("|");
    return new RegExp(`^(${regExpBuilt})$`);
};

alert(PhoneEuropeRegExp().test("+420123456789"))

-4

Essayez ceci, je ne sais pas s'il y a un numéro de téléphone plus long que 12:

^(00|\+){1}\d{12}$

1
Cela correspond aux numéros qui ont exactement 12 chiffres, y compris le code du pays. C'est faux car cela ne tient pas compte de la variabilité de la longueur dans le monde. De plus, la longueur maximale est en fait de 15 chiffres .
tmt le

1
@tmt Et ^(00|\+){1}\d{12,15}$alors?
testée
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.