Cómo validar números de teléfono usando expresiones regulares
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.
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
.*
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"
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+))?$
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–2042
es un número válido de EE.UU.(999) 974–2042
no es un número válido de EE.UU.
- Australia
0404 999 999
es un número australiano válido(02) 9999 9999
También es un número australiano válido .(09) 9999 9999
no 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 x1234
obtiene 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 libphonenumber
tiene 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.
/^(?:(?:\(?(?: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:
- Indicador de país
- Número de teléfono
- Extensión
Puedes probarlo en https://regex101.com/r/kFzb1s/42