¿Qué expresión regular coincidirá con los números de teléfono internacionales válidos?

113

Necesito determinar si un número de teléfono es válido antes de intentar marcarlo. La llamada telefónica puede ir a cualquier parte del mundo.

¿Qué expresión regular coincidirá con los números de teléfono internacionales válidos?

Abtin Forouzandeh
fuente
¿Cómo maneja cualquier expresión regular errores como números fuera de servicio? Simplemente intente llamar y maneje un número inválido como lo haría con otros errores.
3
Si bien tiene razón en que la expresión regular no puede determinar esto, cada intento de salida consume tiempo y recursos. Hacer una verificación rápida de cordura en el número asegura que una llamada obviamente falsa no bloquee un canal valioso.
Abtin Forouzandeh
1
LOL @ paxdiablo .... Supongo que 1-800-CALL-HELP pasará su prueba de RegExp ... lol
Buhake Sindi
1
Algo que no está claro en esta pregunta es si los números tienen que ser válidos si se llaman desde los EE. UU. O desde cualquier país del mundo, porque la mayoría de las soluciones a continuación no validan algunos números válidos (como 0030 210 12312312 - un código válido Número griego llamado desde cualquier país de la UE)
Xeroxoide
1
@JonHanna Estoy de acuerdo en un punto, pero por otro lado, desde la perspectiva de UX, ¿no crees que si un usuario ingresa un número 00XX ... X, la prueba debería pasar? Hay casos en los que los usuarios (es decir, las personas mayores) ni siquiera saben qué es el + y cómo escribirlo en un teclado numérico / telefónico. Además, todavía podría argumentar que 00XXX es un número internacional válido (es decir, en el contexto de un usuario) donde en lugar del +, se usó el código de salida.
Xeroxoide

Respuestas:

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}$

Es el formato correcto para hacer coincidir un número de teléfono internacional genérico. Reemplacé el código de acceso internacional centrado en la línea terrestre de EE. UU. 011 con el identificador de código de acceso internacional estándar de '+', haciéndolo obligatorio. También cambié el mínimo para el número nacional a al menos un dígito.

Tenga en cuenta que si ingresa números en este formato en la libreta de direcciones de su teléfono móvil, puede llamar con éxito a cualquier número de su libreta de direcciones sin importar a dónde viaje. Para líneas fijas, reemplace el signo más con el código de acceso internacional del país desde el que está marcando.

Tenga en cuenta que esto NO tiene en cuenta las reglas del plan de números nacionales; específicamente, permite ceros y unos en ubicaciones que los planes de números nacionales pueden no permitir y también permite longitudes de números mayores que el plan de números nacional para algunos países (por ejemplo, EE. UU.).

Eric
fuente
5
Me parece sensato. Voy a usar este
Sevenearths
17
Esto no es valido. Los números de teléfono europeos pueden comenzar con un doble 0 sin un + al principio. Por lo tanto, un número de teléfono como: +44 8984 1234 (Reino Unido) también es perfectamente válido si se escribe 0044 8984 1234 que esta expresión regular (y también en otras respuestas) no admite.
Xeroxoide
4
Combinado con las mejoras de @ fezfox (?) Y la longitud optimizada:^\+((?: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. Desde el punto de vista de UX, sí, podría tener sentido permitir el 00frente. Desde el desarrollo y mantenimiento punto de vista, yo diría que es perfectamente posible cumplir todos los números para empezar +o incluso sustituir 00con una +cada vez que lo consigue - especialmente teniendo en cuenta que la mayoría de la gente es consciente del +formato (que campos de entrada de teléfono más internacionales requieren de todos modos). Además, es una solución de una sola línea y mucho más legible. Este enfoque también garantizaría que todos los números de teléfono estén en el mismo formato y hace que su validación sea mucho menos propensa a errores, lo que hace que todo sea más fácil de mantener.
milosmns
1
Y también, en los "viejos" días de los SMS anteriores a EDGE (GSM simple), el uso 00no enviaba el mensaje correctamente, mientras que comenzar con un +siempre funcionaba a nivel internacional. Podemos volvernos locos y hacerlo súper complejo, pero a veces es posible / vale la pena eliminar algunas restricciones para hacernos la vida más fácil :)
milosmns
66

Todos los códigos de país están definidos por la UIT. La siguiente expresión regular se basa en UIT-T E.164 y el Anexo al Boletín de Explotación de la UIT N. ° 930 - 15.IV.2009 . Contiene todos los códigos de países actuales y los códigos reservados para uso futuro. Si bien podría acortarse un poco, decidí incluir cada código de forma independiente.

Esto es para llamadas que se originan en EE. UU. Para otros países, reemplace el código de acceso internacional (el 011 al comienzo de la expresión regular) con el que sea apropiado para el plan de marcado de ese país .

Además, tenga en cuenta que ITU E.164 define la longitud máxima de un número telefónico internacional completo en 15 dígitos. Esto significa que un código de país de tres dígitos da como resultado hasta 12 dígitos adicionales, y un código de país de 1 dígito puede contener hasta 14 dígitos adicionales. Por lo tanto, la

[0-9]{0,14}$

a el final de la expresión regular.

Lo más importante es que esta expresión regular no significa que el número sea válido: cada país define su propio plan de numeración interno. Esto solo asegura que el código de país sea válido.

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} $

Abtin Forouzandeh
fuente
12
Casi lo tenía bien ... "011" no es parte de un código internacional. Es justo lo que necesitan marcar las personas en los EE. UU. Para realizar una llamada internacional. Ese prefijo cambiará dependiendo de dónde marque ... Entonces ese prefijo NO es parte del número.
Gabriel Magana
3
@gmagana - Menciono eso en mi respuesta (párrafo 2)
Abtin Forouzandeh
1
Mi punto es que no es parte del número de teléfono. Es como decir que el prefijo de marcación de larga distancia nacional de EE. UU. "1" es parte del número de teléfono.
Gabriel Magana
1
@gmagana: aunque tiene razón en que no forma parte del número de teléfono, técnicamente es necesario para realizar la llamada.
Abtin Forouzandeh
2
@Roger Pate: Pasé un poco de tiempo resolviendo esto y espero que sea útil para otros. También esperaba que alguien más pudiera tener una mejor solución (por eso no he marcado mi propia respuesta como aceptada).
Abtin Forouzandeh
32

Esta es una optimización adicional.

\+(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) permite prefijos internacionales válidos
(ii) seguidos de 9 o 10 dígitos, con cualquier tipo o ubicación de delímetros (excepto entre los dos últimos dígitos)

Esto coincidirá con:
+ 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

fezfox
fuente
Sé que esta es una respuesta antigua, pero ¿hay alguna opción para hacer que el 1 sea opcional para los números estadounidenses?
Adam Fratino
Lo que quiere hacer es (i) hacer que el "+" sea opcional y (ii) el código internacional opcional. Entonces, ¿lugar "?" después del + y después del primer corchete de cierre.
fezfox
@ManosPasgiannis bueno, sí, como se especifica "seguido de 9 o 10 dígitos". Aparecería que en chipre usa 8, así que simplemente ajuste la última secuencia eliminando una instancia de \ d \ W * y haga la última expresión (\ d {1,3})
fezfox
22

Puede utilizar la biblioteca 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();
    }
Paulo Fidalgo
fuente
2
Podría ser una buena solución, pero solo para verificar los números de teléfono, antes de usar esta biblioteca, debe importar una gran cantidad de js ... porque libphonenumber.js necesita una biblioteca de cierre ... no es una solución ligera: /
J. BizMai
11

Esto funcionará para números internacionales;

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}$/
MADol
fuente
11

Yo uso este:

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

Ventajas: reconoce los inicios + o 011, lo deja tan largo como sea necesario y maneja muchas convenciones de extensión. (#, x, ext, extensión)

TOBlender
fuente
Este se acerca bastante a la mayoría de los formatos de números de teléfono internacionales.
feeela
9

Aquí hay una versión "optimizada" de su expresión regular:

^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}$

Puede reemplazar la \ds con [0-9]si su sintaxis de expresiones regulares no es compatible \d.

Laurence Gonsalves
fuente
7

Para iOS SWIFT encontré esto útil,

let phoneRegEx = "^((\\+)|(00)|(\\*)|())[0-9]{3,14}((\\#)|())$"
Mohammad Zaid Pathan
fuente
falló para +91 9999999999
Sahil Mahajan
6

Se modificó la expresión regular de @ Eric: se agregó una lista de todos los códigos de país (los obtuve de xxxdepy @ Github . Espero que les resulte útil:

/(\+|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}$/
Dev
fuente
Funciona de maravilla. También para números de teléfono holandeses. ¡Gracias!
mauvm
2

Obviamente, hay una multitud de formas de hacer esto, como lo demuestran todas las diferentes respuestas dadas hasta ahora, pero arrojaré mi valor de $ 0.02 aquí y proporcionaré la expresión regular a continuación, que es un poco más concisa que casi todas las anteriores. , pero también más completo que la mayoría. También tiene el agradable efecto secundario de dejar el código del país en $ 1 y el número 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 +) $

Trekinaz
fuente
2

Sin críticas con respecto a esas excelentes respuestas, solo quiero presentar la solución simple que utilizo para nuestros creadores de contenido de administración:

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

Forzar el comienzo con un más o dos ceros y usar al menos un poco de números, espacios en blanco, llaves, menos y el punto es opcional y no otros caracteres. Puede eliminar de forma segura todos los que no sean números y usar esto en una entrada tel: Los números tendrán una forma común de representación y no tengo que preocuparme por ser demasiado restrictivo.

Blackbam
fuente
1

Una versión simple para números europeos, que coincide con números como 0034617393211 pero también con números largos como 004401484172842.

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

Espero eso ayude :·)

Roc Boronat
fuente
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();
}
Cássio
fuente
1
Si bien este fragmento de código puede responder la pregunta, no proporciona ningún contexto para explicar cómo o por qué. Considere agregar una oración o dos para explicar su respuesta.
brandonscript
1

Aquí hay una expresión regular para los siguientes escenarios de números de teléfono más comunes. Aunque esto se adapta desde una perspectiva estadounidense para códigos de área, funciona para escenarios internacionales.

  1. El número real debe tener solo 10 dígitos.
  2. Para los números de EE. UU., El código de área puede estar entre paréntesis ().
  3. El código de país puede tener de 1 a 3 dígitos. Opcionalmente, puede ir precedido de un signo +.
  4. Puede haber guiones, espacios, puntos o ningún espacio entre el código de país, el código de área y el resto del número.
  5. Un número de teléfono válido no puede ser todo ceros.

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

Explicación:

    ^ - 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

Más ejemplos y explicación: https://regex101.com/r/hTH8Ct/2/

Appy
fuente
1

He usado esto a continuación:

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

El formato + CCC.NNNNNNNNNNxEEEE o 00CCC.NNNNNNNNNNxEEEE

El número de teléfono debe comenzar con '+' o '00' para una llamada internacional. donde C es el código de país de 1 a 3 dígitos,

N tiene hasta 14 dígitos,

y E es la extensión (opcional).

El signo más inicial y el punto que sigue al código de país son obligatorios. El carácter literal "x" es necesario solo si se proporciona una extensión.

Rousonur Jaman
fuente
0

El plan de numeración internacional se basa en el plan de numeración de la UIT E.164 . Supongo que ese es el punto de partida de tu expresión regular.

Actualizaré esto si puedo crear una expresión regular basada en la numeración ITU E.164.

Buhake Sindi
fuente
0

Esta expresión Regex funciona para los números de teléfono de India, Canadá, Europa, Nueva Zelanda, Australia y Estados Unidos, junto con sus códigos de país:

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

Harsha Garg
fuente
0

Sin embargo, esto funciona para mí, sin el prefijo 00, 001, 0011, etc.

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

Prueba esto, me funciona.

^(00|\+)[1-9]{1}([0-9][\s]*){9,16}$
AbdulAhmad Matin
fuente
0

Hice la expresión regular para los números de teléfono europeos, y es específica contra el prefijo de marcación frente a la longitud del número.

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"))
luky
fuente
-4

Prueba esto, no sé si hay algún número de teléfono mayor a 12:

^(00|\+){1}\d{12}$
MKYuones
fuente
1
Esto coincide con números que tienen exactamente 12 dígitos, incluido el código del país. Eso está mal porque no tiene en cuenta la variabilidad de la longitud en todo el mundo. Además, la longitud máxima es en realidad de 15 dígitos .
tmt
1
@tmt ¿Qué tal ^(00|\+){1}\d{12,15}$entonces?
probado el