Cómo validar números de teléfono usando expresiones regulares

Resuelto Nicholas Trandem asked hace 15 años • 46 respuestas

Estoy intentando crear una expresión regular completa para validar los números de teléfono. Lo ideal sería manejar formatos internacionales, pero debe manejar formatos estadounidenses, incluidos los siguientes:

  • 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

Responderé con mi intento actual, pero espero que alguien tenga algo mejor y/o más elegante.

Nicholas Trandem avatar Sep 24 '08 03:09 Nicholas Trandem
Aceptado

Mejor opción... simplemente elimine todos los caracteres que no sean dígitos en la entrada (excepto 'x' y los signos iniciales '+'), teniendo cuidado debido a la tendencia británica de escribir números en una forma no estándar +44 (0) ...cuando se le pide que use el prefijo internacional. (en ese caso específico, debes descartarlo por (0)completo).

Entonces, terminas con valores como:

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

Luego, cuando lo muestre, vuelva a formatear a su gusto. p.ej

  1 (234) 567-8901
  1 (234) 567-8901 x1234
scunliffe avatar Sep 23 '2008 20:09 scunliffe
.*

Si los usuarios quieren darle sus números de teléfono, confíe en ellos para hacerlo bien. Si no quieren dártelo, obligarlos a ingresar un número válido los enviará al sitio de un competidor o los obligará a ingresar una cadena aleatoria que se ajuste a tu expresión regular. Incluso podría sentirme tentado a buscar el número de una línea directa de horóscopos con tarifas superiores e ingresarlo en su lugar.

También consideraría cualquiera de las siguientes entradas válidas en un sitio 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"
Dave Kirby avatar Aug 07 '2009 17:08 Dave Kirby

Resulta que existe una especie de especificación para esto, al menos para América del Norte, llamada NANP .

Debe especificar exactamente lo que desea. ¿Qué son los delimitadores legales? ¿Espacios, guiones y puntos? ¿No se permite ningún delimitador? ¿Se pueden mezclar delimitadores (por ejemplo, +0.111-222.3333)? ¿Cómo se manejarán las extensiones (por ejemplo, 111-222-3333 x 44444)? ¿Qué pasa con los números especiales, como el 911? ¿El código de área será opcional o obligatorio?

Aquí hay una expresión regular para un número de 7 o 10 dígitos, con extensiones permitidas, los delimitadores son espacios, guiones o puntos:

^(?:(?:\+?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+))?$
Justin R. avatar Sep 23 '2008 20:09 Justin R.

También sugeriría mirar la biblioteca de Google " libphonenumber ". Sé que no es una expresión regular pero hace exactamente lo que quieres.

Por ejemplo, reconocerá que:

15555555555

es un número posible pero no un número válido. También admite países fuera de EE. UU.

Aspectos destacados de la funcionalidad:

  • Analizar/formatear/validar números de teléfono para todos los países/regiones del mundo.
  • getNumberType- obtiene el tipo de número basándose en el número mismo; capaz de distinguir números de línea fija, móvil, gratuito, tarifa premium, costo compartido, VoIP y personales (cuando sea posible).
  • isNumberMatch- obtiene un nivel de confianza sobre si dos números podrían ser iguales.
  • getExampleNumber/ getExampleNumberByType: proporciona números de ejemplo válidos para todos los países/regiones, con la opción de especificar qué tipo de número de teléfono de ejemplo se necesita.
  • isPossibleNumber- adivinar rápidamente si un número es un posible número de teléfono utilizando solo la información de longitud, mucho más rápido que una validación completa.
  • isValidNumber- validación completa de un número de teléfono para una región utilizando información de longitud y prefijo.
  • AsYouTypeFormatter- formatea los números de teléfono sobre la marcha cuando los usuarios ingresan cada dígito.
  • findNumbers- encuentra números en la entrada de texto.
  • PhoneNumberOfflineGeocoder- proporciona información geográfica relacionada con un número de teléfono.

Ejemplos

El mayor problema con la validación de números de teléfono es que depende mucho de la cultura.

  • America
    • (408) 974–2042es un número válido de EE.UU.
    • (999) 974–2042no es un número válido de EE.UU.
  • Australia
    • 0404 999 999es un número australiano válido
    • (02) 9999 9999También es un número australiano válido .
    • (09) 9999 9999no es un número australiano válido

Una expresión regular está bien para verificar el formato de un número de teléfono, pero en realidad no podrá verificar la validez de un número de teléfono.

Sugeriría omitir una expresión regular simple para probar su número de teléfono y usar una biblioteca como la de Google libphonenumber(enlace al proyecto GitHub) .

¡Presentamos libphonenumber!

Usando uno de sus ejemplos más complejos, 1-234-567-8901 x1234obtiene los siguientes datos libphonenumber(enlace a la demostración en línea) :

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

Por lo tanto, no solo sabrá si el número de teléfono es válido (que lo es), sino que también obtendrá un formato de número de teléfono consistente en su localidad.

Como beneficio adicional, también libphonenumbertiene una serie de conjuntos de datos para verificar la validez de los números de teléfono, por lo que al verificar un número como +61299999999(la versión internacional de (02) 9999 9999) se obtiene un número válido con formato:

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 también le brinda muchos beneficios adicionales, como obtener la ubicación en la que se detecta el número de teléfono y también obtener la información de la zona horaria del número de teléfono:

PhoneNumberOfflineGeocoder Results
Location        Australia

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

Pero el número de teléfono australiano no válido ( (09) 9999 9999) indica que no es un número de teléfono válido.

Validation Results

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

La versión de Google tiene código para Java y Javascript, pero la gente también ha implementado bibliotecas para otros lenguajes que utilizan el conjunto de datos de números de teléfono Google i18n:

  • PHP : https://github.com/giggsey/libphonenumber-for-php
  • Python : https://github.com/daviddrysdale/python-phonenumbers
  • Rubí : https://github.com/sstephenson/global_phone
  • C# : https://github.com/twcclegg/libphonenumber-csharp
  • Objetivo-C : https://github.com/iziz/libPhoneNumber-iOS
  • JavaScript : https://github.com/ruimarinho/google-libphonenumber
  • Elixir : https://github.com/socialpaidsbv/ex_phone_number

A menos que esté seguro de que siempre aceptará números de una ubicación y que siempre estarán en un formato, le sugiero encarecidamente no escribir su propio código para esto y usar libphonenumber para validar y mostrar números de teléfono.

Tim Groeneveld avatar Mar 26 '2013 18:03 Tim Groeneveld

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

Esto coincide:

 - (+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
 - +1 282 282 2828

En $n, guarda:

  1. Indicador de país
  2. Número de teléfono
  3. Extensión

Puedes probarlo en https://regex101.com/r/kFzb1s/42

Ismael Miguel avatar Jan 07 '2014 12:01 Ismael Miguel