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

Estoy tratando de armar una expresión regular completa para validar los números de teléfono. Idealmente, manejaría 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.

preguntado el 23 de septiembre de 08 a las 18:09

Esta respuesta se ha agregado a la Preguntas frecuentes sobre expresiones regulares de desbordamiento de pila, en "Tareas de validación comunes". -

30 Respuestas

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

Luego, terminas con valores como:

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

Luego, cuando visualice, cambie el formato al contenido de su corazón. p.ej

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

respondido 10 mar '16, 10:03

El código de formato será una pérdida de tiempo si se permite que los números provengan de fuera de los EE. UU. - Daniel Earwicker

Esto es bueno y todo, pero no valida que lo que se ingresó era en realidad un número de teléfono. Por ejemplo, ¿qué pasa si el usuario no ingresa los 10 dígitos requeridos? Esto debe combinarse con una buena validación de expresiones regulares. - hugh jeffner

Teniendo en cuenta que la pregunta era sobre validación, esta es una respuesta realmente mala. - Plex Q

@PlexQ No estoy de acuerdo. El problema original es tratar de manejar la validación del número de teléfono porque estaba tratando de manejar todas las opciones de formato posibles. En lugar de intentar resolver todo eso, tome la entrada y "elimínela previamente" de todo el formato hasta que tenga solo el "número". Hacer esto resuelve 2 problemas: probar el resultado ahora es fácil y ahora puede asegurarse de que los valores renderizados para su visualización puedan formatearse de manera consistente. El primer comentario de esta respuesta sobre los "Guantes del Complicador" es una buena lectura ... a veces la respuesta a un problema es abordarlo de manera diferente. - scunliffe

¿Cómo diablos es esta una respuesta tan votada? Esto no validar cualquier cosa. Lo que es peor es que todas las otras preguntas de validación de números de teléfono hacen referencia a esta ... jlars62

Resulta que hay 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 permiten delimitadores? ¿Se pueden mezclar delimitadores (p. Ej., + 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+))?$

Respondido el 01 de Septiembre de 10 a las 23:09

here it is without the extension section (I make my users enter ext in a separate field): ^(?:(?:\+?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})$ - aaron

Aquí hay una versión que solo coincide con números de teléfono de 10 dígitos (no de 7 dígitos como 843-1212): /(?:(?:\+?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})/ - Brian Armstrong

Se aceptan 10 dígitos () alrededor del código de área, y no se permiten antes del 1 como código de paí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}) - Brooke.

@StevenSoroka He tenido el libro de Jeffrey Friedl a mi lado en mi escritorio durante los últimos dos años, ya que las expresiones regulares son una parte importante de mi trabajo. Se necesita bastante tiempo para comprender realmente las expresiones regulares. A veces, los lectores de este sitio simplemente buscan una solución existente, en lugar de escribir la suya propia, especialmente en dominios con muchos casos de esquina, como representaciones de números de teléfono. - justin r

@ fatcat1111 Lo entiendo, pero la mayoría de las respuestas aquí son del tipo "yo también" de expresiones regulares únicas que probablemente no se ajustan a ninguno de sus casos de esquina. Luego, estos terminan en todos los sitios web que estoy tratando de usar y no puedo ingresar mi código postal, número de teléfono o dirección de correo electrónico porque alguien usó una expresión regular a medias (por ejemplo: + es un carácter válido en las direcciones de correo electrónico ). Las mejores respuestas en esta página apuntan a los usuarios a las bibliotecas, no a las expresiones regulares garabateadas en servilletas. - steven soroka

.*

Si los usuarios quieren darle sus números de teléfono, confíe en ellos para que lo hagan bien. Si no quieren dárselo, obligarlos a ingresar un número válido los enviará al sitio de un competidor o los hará ingresar una cadena aleatoria que se ajuste a su expresión regular. Incluso podría sentir la tentación de buscar el número de una línea directa del horóscopo de tarifa premium e ingresarlo en su lugar.

También consideraría cualquiera de los siguientes como 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"

Respondido el 18 de diciembre de 19 a las 00:12

Estoy de acuerdo con el sentimiento aquí, pero a veces es bueno realizar la validación cuando el número de teléfono realmente se va a usar para algo importante en interés del usuario. El mejor ejemplo aquí es la autorización con tarjeta de crédito para una compra. Si el número de teléfono es incorrecto, la autenticación puede fallar. - Puntiagudo

Si el usuario no quiere ingresar su número de teléfono, puede permitir que el campo sea opcional, pero ¿es demasiado pedirle al usuario que ingrese un número de teléfono válido si va a ingresar uno? - Joel McBeth

También una función de la validación es simplemente recordar a las personas que agreguen códigos de área, etc., que de otro modo no recordarían agregar, pero que no pueden adivinarse después del hecho. - ben mcintyre

@Pointy Pero la validación de expresiones regulares no te ayudará. La única forma de validar si el número de teléfono es correcto es enviarle un mensaje (en el caso de un teléfono móvil) Y asegurarse de que el usuario lo confirme utilizando algún tipo de código de verificación. Esto es lo que se hace cuando la corrección numérica es importante. Todo lo demás es solo para la conveniencia del usuario para protegerlo contra algunos (pero no todos) errores tipográficos y no valida nada. - Alex B

Fresco. Mi número de teléfono es 1 'O 1 = 1 - PWNED. Vea xkcd.com/327 y owasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005) - aarón newton

También sugeriría mirar el "libphonenumber"Biblioteca de Google. 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 válido. También es compatible con 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 entre líneas fijas, móviles, llamadas gratuitas, tarifas premium, costos compartidos, VoIP y números personales (siempre que 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 número de teléfono posible 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 del número de teléfono es que depende en gran medida de la cultura.

  • América Latina
    • (408) 974–2042 es un IMPORTANTE Número de EE. UU.
    • (999) 974–2042 is no valido Número de EE. UU.
  • Australia
    • 0404 999 999 es un IMPORTANTE Número australiano
    • (02) 9999 9999 es también un IMPORTANTE Número australiano
    • (09) 9999 9999 is no valido Número australiano

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

Sugeriría omitir una expresión regular simple para comparar 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, usted obtiene los siguientes datos de 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

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

Como extra, libphonenumber tiene varios conjuntos de datos para verificar la validez de los números de teléfono, así que verifique un número como +61299999999 (la versión internacional de (02) 9999 9999) devuelve 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 tomar la ubicación donde 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) devuelve 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 idiomas que usan el conjunto de datos de números de teléfono de Google i18n:

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

Respondido 18 Feb 19, 18:02

Teniendo en cuenta que ahora también hay un puerto Go en: github.com/ttacon/libphonenumber - Michaelhanson

Al comprobar si es un número posible, ¿no es necesario especificar un código de país? Estoy usando la versión de PHP y si ingreso un número británico como (reemplace 0 con números reales) 07700000000 yo obtengo Missing or invalid default region. error. Pero si especifico el código del país, pasará. - BugHunterUK

FYI: esta biblioteca no es compatible con algunos países, phpinterviewquestions.co.in/blog/ionic/… - sijo vijayan

@BugHunterUK (y cualquier persona que se encuentre con esta pregunta y se pregunte lo mismo) al analizar un número, puede especificar la región esperada y la biblioteca buscará números no internacionales en esa región. Si no especifica, rechazará todo lo que no esté en un formato internacional válido. - IMSoP

Imagine github.com/nyaruka/números de teléfono ya que se ha convertido en el paquete Go "oficial" recomendado por Google en lugar de libphonenumber. - DeeZone

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

Esto coincide con:

 - (+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

En $ n, ahorra:

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

Puedes probarlo en https://www.regexpal.com/?fam=99127

Respondido el 22 de Septiembre de 17 a las 11:09

Esta fue la expresión regular más completa que he visto. Es fácil moverse hasta que se quita ^ y $ o de lo contrario puedo evitarlo usando [111] [111] [1111] or 111--111--1111 y similares. (lo siento, borré mi último comentario) - bafromca

¿Puede reformular la frase? No puedo entender esto: "Es fácil moverse hasta que eliminas ^ y $ o, de lo contrario, puedo sortearlo usando [111] [111] [1111]". ¿Significa que valida '[111] [111] [1111]' cuando toma el ^ y $? - ismael miguel

Evité tu expresión regular usando [111] [111] [1111] y 111--111--1111 hasta que me quité ^ y $ de la expresión regular. - bafromca

^^^ Este es un gran ejemplo de por qué los hilos de comentarios NO deberían ir al chat. Estoy muy interesado en cómo resultó esta conversación y necesito saber si este ReGex es lo suficientemente resistente para usarlo en mi aplicación. Desafortunadamente, la conversación de chat ya no existe. - Matt Cashatt

Para ser honesto, no fui a charlar. Después de pedir explicaciones varias veces, me quedé sin información. Siempre puedes probarlo tú mismo con todo tipo de números que encuentres en línea, en múltiples formatos. Una cosa que probé con este es usar varios números de teléfono, pero no funciona tan bien si tienen espacios alrededor. Y tengo que encontrar una solución para contar la cantidad de dígitos y hacer cumplir una cantidad específica. - ismael miguel

Aunque la respuesta para eliminar todos los espacios en blanco es clara, realmente no resuelve el problema que se plantea, que es encontrar una expresión regular. Tomemos, por ejemplo, mi script de prueba que descarga una página web y extrae todos los números de teléfono usando la expresión regular. Como necesitaría una expresión regular de todos modos, también podría hacer que la expresión regular haga todo el trabajo. Se me ocurrió esto:

1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?

Aquí hay un script en Perl para probarlo. Cuando coincide, $ 1 contiene el código de área, $ 2 y $ 3 contienen el número de teléfono y $ 5 contiene la extensión. Mi secuencia de comandos de prueba descarga un archivo de Internet e imprime todos los números de teléfono que contiene.

#!/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:

Puede cambiar \ W * a \ s * \ W? \ S * en la expresión regular para ajustarlo un poco. No estaba pensando en la expresión regular en términos de, digamos, validar la entrada del usuario en un formulario cuando lo escribí, pero este cambio hace posible usar la expresión regular para ese propósito.

'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*))?';

Respondido el 23 de Septiembre de 08 a las 23:09

Para su información, la expresión regular también coincide con: (4570457-6789 que sería un error tipográfico bastante común. Los grupos de partidos también se desvían: rubular.com/r/TaTP0mHL5c - SooDesuNe

@SooDesuNe anteponiendo (^|[^\d\n]) (con el indicador multilínea activado) evita el problema general, asegurándose de que no esté inmediatamente precedido por algo numérico. - bciudad

Tenga en cuenta que esto está centrado en América del Norte; falta "44 7911 123456" - ben rodador

Respondí esta pregunta en otra pregunta SO antes de decidir incluir también mi respuesta como respuesta en este hilo, porque nadie estaba abordando cómo requerir / no requerir elementos, solo distribuyendo expresiones regulares: Regex funciona mal, coincide con cosas inesperadas

Desde mi publicación en ese sitio, he creado una guía rápida para ayudar a cualquier persona a crear su propia expresión regular para el formato de número de teléfono deseado, que advertiré (como hice en el otro sitio) que si eres demasiado restrictivo, es posible que no obtenga los resultados deseados y no existe una solución "única para todos" para aceptar todos los números de teléfono posibles en el mundo, solo los que decida aceptar como formato de su elección. Úselo bajo su propio riesgo.

Hoja de trucos rápidos

  • Inicie la expresión: /^
  • Si desea requerir un espacio, use: [\s] or \s
  • Si desea requerir paréntesis, use: [(] y [)] . Utilizando \( y \) es feo y puede confundir las cosas.
  • Si desea que algo sea opcional, coloque un ? después de
  • Si desea un guion, simplemente escriba - or [-] . Sin embargo, si no lo coloca al principio o al final de una serie de otros caracteres, es posible que deba escapar de él: \-
  • Si desea aceptar diferentes opciones en una ranura, coloque entre corchetes las opciones: [-.\s] requerirá un guión, un punto o un espacio. Un signo de interrogación después del último corchete hará que todos sean opcionales para ese espacio.
  • \d{3} : Requiere un número de 3 dígitos: 000-999. Taquigrafía para [0-9][0-9][0-9].
  • [2-9] : Requiere un dígito del 2 al 9 para esa ranura.
  • (\+|1\s)? : Acepta un "más" o un 1 y un espacio (carácter de barra vertical, |, es "o") y hacerlo opcional. Se debe omitir el signo "más".
  • Si desea que números específicos coincidan con un espacio, ingréselos: [246] requerirá un 2, 4 o 6. (?:77|78) or [77|78] requerirá 77 o 78.
  • $/ : Termina la expresión

Respondido 17 Jul 20, 14:07

Esto es muy útil, pero dudo y estoy buscando una expresión {min, max}. ¿Puede usted ayudar? - Ataboy Josef

Si estamos hablando de un solo dígito (y puede hacer que coincida de acuerdo con eso), vea el [2-9] bloque que puse allí. Eso significa que su mínimo es 2 y su máximo es 9. Ajuste en consecuencia. - vapcguy

Escribí de la manera más simple (aunque no necesitaba un punto).

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

Como se menciona a continuación, solo verifica los caracteres, no su estructura / orden

Respondido 29 Jul 15, 23:07

esto valida toneladas de números que son técnicamente inválidos. como, "- + () () ()) ())))". Aprenda a leer expresiones regulares para que pueda comprender lo que está haciendo. - steven soroka

@StevenSoroka técnicamente puede permitir muchos casos inválidos, pero cuando pensamos en ayudar al usuario a evitar errores comunes con la solución más simple posible, este es el camino a seguir :) - felizhardik

esto también coincide con el espacio en blanco, línea vacía - Wasim A.

@HappyHardik. En efecto. Simple y potente, para una validación básica, permita que el usuario escriba más de un punto, guión, corchete o más. - dijipiji

Solo lo usé y está mal en muchos aspectos. Por ejemplo, un número de teléfono del Reino Unido puede comenzar con +44, o un nuber de teléfono puede tener (0) dentro. Pero esto no es válido según su expresión regular. Recomendaría la respuesta de @Ismael Miguel. Funciona bien y te recomendaría que revises tu respuesta. - Stelios Voskos

Tenga en cuenta que pelar () caracteres no funciona para un estilo de escritura de números del Reino Unido que es común: +44 (0) 1234 567890 lo que significa marcar el número internacional:
+441234567890
o en el Reino Unido marcar 01234567890

Respondido 03 ago 15, 05:08

Si solo desea verificar que no tiene basura aleatoria en el campo (es decir, de los spammers de formularios), esta expresión regular debería funcionar bien:

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

Tenga en cuenta que no tiene reglas especiales sobre cuántos dígitos o qué números son válidos en esos dígitos, solo verifica que solo dígitos, paréntesis, guiones, más, espacio, libra, asterisco, punto, coma o las letras e, x, t están presentes.

Debe ser compatible con los formatos de localización y números internacionales. ¿Prevé alguna necesidad de permitir corchetes cuadrados, rizados o en ángulo para algunas regiones? (actualmente no están incluidos).

Si desea mantener las reglas por dígito (como en los códigos de área de EE. UU. Y los prefijos (códigos de intercambio) deben estar en el rango de 200-999), buena suerte. Mantener un conjunto de reglas complejo que podría quedar desactualizado en cualquier momento en el futuro por cualquier país del mundo no suena divertido.

Y aunque la eliminación de todos / la mayoría de los caracteres no numéricos puede funcionar bien en el lado del servidor (especialmente si planea pasar estos valores a un marcador), es posible que no desee alterar la entrada del usuario durante la validación, especialmente si desea que lo hagan. hacer correcciones en otro campo.

Respondido 18 Oct 12, 20:10

¿Has echado un vistazo a Librería RegEx?

Ingresar el número de teléfono de EE. UU. Trajo una gran lista de posibilidades.

Respondido el 23 de Septiembre de 08 a las 21:09

Esta parece una excelente manera de integrar errores desconocidos en su código. - tom señor

Deben evitarse las respuestas de solo enlace porque pueden romperse en el futuro y hacer que la publicación sea inútil. Las soluciones estáticas siempre son necesarias para mantener el valor de una respuesta. Si desea recomendar un hipervínculo, agréguelo como comentario debajo de la pregunta. - mickmackusa

Mi intento de una expresión regular irrestricta:

/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/

Acepta:

+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww

Rechaza:

mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911

Depende de usted desinfectarlo para exhibirlo. Después de validarlo podría aunque sea un número.

Respondido 30 Abr '15, 16:04

Aquí hay un patrón maravilloso que se asemeja más a la validación que necesitaba lograr. No soy el autor original, pero creo que vale la pena compartirlo, ya que encontré este problema muy complejo y sin una respuesta concisa o muy útil.

La siguiente expresión regular capturará combinaciones de números y caracteres ampliamente utilizadas en una variedad de formatos de números de teléfono globales:

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

Positivo:
+(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

Negativo:
926 3 4
8 800 600-MANZANA

Fuente original: http://www.regexr.com/38pvb

Respondido 23 Abr '15, 23:04

Esto tiene un soporte limitado para extensiones. Coincide con "616-555-1234 x567" pero no con "616-555-1234 ext. 567". - jon schneider

Falso positivo para, por ejemplo, "------- ((((((55555555" o "99999999999999999999999" - Mikep

No valida el número de macdonalds de Nitherland +31 76 596 (solo estaba probando números aleatorios) - BIOHAZARD

Encontré que esto funciona bastante bien:

^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$

Funciona para estos formatos de números:

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

Asegúrese de usar indicadores globales Y multilínea para asegurarse.

Enlace: http://www.regexr.com/3bp4b

Respondido el 11 de Septiembre de 15 a las 23:09

Este es mi mejor intento hasta ahora. Maneja los formatos anteriores, pero estoy seguro de que me faltan otros formatos posibles.

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$

Respondido el 23 de Septiembre de 08 a las 21:09

¡Trabajado como un encanto! Gracias por compartir - KdPisda

Si está hablando de validación de formularios, la expresión regular para validar el significado correcto, así como los datos correctos, será extremadamente compleja debido a los diferentes estándares del país y del proveedor. También será difícil mantenerse actualizado.

Interpreto la pregunta como buscar un patrón ampliamente válido, que puede no ser internamente consistente, por ejemplo, tener un conjunto válido de números, pero no validar que la línea troncal, el intercambio, etc., el patrón válido para el prefijo del código de país .

Norteamérica es sencillo, y para internacional prefiero usar un patrón 'idiomático' que cubra las formas en que las personas especifican y recuerdan sus números:

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

El patrón norteamericano asegura que si se incluye un paréntesis, ambos lo están. Las cuentas internacionales para un '+' inicial opcional y un código de país. Después de eso, estás en el idioma. Las coincidencias válidas serían:

  • (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

Esto puede estar sesgado ya que mi experiencia se limita a América del Norte, Europa y un poco de Asia.

Respondido 18 Oct 12, 20:10

He intentado implementar lo anterior en mi script de validación de JavaScript, pero sigo obteniendo un invalid quantifier error. ¿Alguna idea de lo que estoy haciendo mal? - Jannis

Agregaría el caso trivial donde el teléfono se especifica sin símbolos pero tal vez espacios y código de país, en Europa es típico para números locales y móviles: 676412342, 676 46 32 12, 676 463 - rompe

Mi instinto se ve reforzado por la cantidad de respuestas a este tema: que hay un número prácticamente infinito de soluciones para este problema, ninguna de las cuales será elegante.

Honestamente, le recomendaría que no intente validar los números de teléfono. Incluso si pudiera escribir un validador grande y peludo que permitiera todos los diferentes formatos legítimos, terminaría permitiendo casi cualquier cosa que se parezca remotamente a un número de teléfono en primer lugar.

En mi opinión, la solución más elegante es validar una longitud mínima, nada más.

Respondido 14 Abr '11, 21:04

Después de probar varios de estos y revisar los datos existentes y los comentarios de los usuarios, tenderé a estar de acuerdo ... - Christopher King

Sin embargo, a veces es necesario realizar una validación. Si estoy enviando códigos de confirmación, no puedo simplemente enviar un código a cualquier basura aleatoria que un spammer haya ingresado en el campo. Quiero asegurarme de que el número sea probablemente un número de teléfono antes de desperdiciar recursos enviándolo. - zfj3ub94rf576hc4eegm

Este es un patrón de expresión regular simple para números de teléfono móvil de Filipinas:

((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

or

((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

coincidirá con estos:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

El primero coincidirá con CUALQUIER código de país de dos dígitos, mientras que el segundo coincidirá exclusivamente con el código de país de Filipinas.

Pruébelo aquí: http://refiddle.com/1ox

Respondido 18 Oct 12, 20:10

Gracias. ¿Qué hay de los números de teléfono fijo con código de área como 028231234? Me pregunto si los códigos de área son solo números de 2 a 3 dígitos y siempre están precedidos por 0. - tormenta salvaje

Te resultará difícil lidiar con números internacionales con una expresión regular única / simple, consulta esta publicación sobre las dificultades de los números de teléfono internacionales (e incluso norteamericanos).

Querrá analizar los primeros dígitos para determinar cuál es el código de país y luego actuar de manera diferente según el país.

Más allá de eso, la lista que proporcionó no incluye otro formato común de EE. UU., Dejando fuera el 1. La mayoría de los teléfonos celulares en los EE. UU. No lo requieren, y comenzará a desconcertar a las generaciones más jóvenes a menos que hayan marcado internacionalmente.

Has identificado correctamente que es un problema complicado ...

-Adán

contestado el 23 de mayo de 17 a las 12:05

No es una solución ofrecida. ES POSIBLE. El hecho de que sea complicado o complejo no significa que debas levantar los brazos. - eric hodonsky

Después de leer estas respuestas, parece que no había una expresión regular sencilla que pueda analizar un montón de texto y extraer números de teléfono en cualquier formato (incluidos los internacionales con y sin el signo más).

Esto es lo que utilicé recientemente para un proyecto de cliente, en el que tuvimos que convertir todos los números de teléfono en cualquier formato a enlaces tel :.

Hasta ahora, ha estado funcionando con todo lo que le han lanzado, pero si surgen errores, actualizaré esta respuesta.

expresión regular:

/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/

Función PHP para reemplazar todos los números de teléfono con enlaces tel: (en caso de que alguien tenga curiosidad):

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

Respondido 08 Jul 14, 19:07

Esta expresión regular coincidió +1 1234562222222222222222222222. - Varda Elentári

¿Por qué no volver? - thexande

Falso positivo para "999999999999999999999999999999999999999" - ben rodador

Creo que el Número :: Teléfono :: EE. UU. y Regexp :: Común (particularmente la fuente de Regexp :: Común :: URI :: RFC2806) Los módulos de Perl podrían ayudar.

La pregunta probablemente debería especificarse con un poco más de detalle para explicar el propósito de validar los números. Por ejemplo, 911 es un número válido en los EE. UU., Pero 911x no es para ningún valor de x. Eso es para que la compañía telefónica pueda calcular cuándo ha terminado de marcar. Hay varias variaciones sobre este tema. Pero su expresión regular no verifica la parte del código de área, por lo que no parece ser una preocupación.

Al igual que para validar direcciones de correo electrónico, incluso si tiene un resultado válido, no puede saber si está asignado a alguien hasta que lo pruebe.

Si está intentando validar la entrada del usuario, ¿por qué no normalizar el resultado y terminar con él? Si el usuario ingresa un número que no puede reconocer como un número válido, guárdelo como ingresado o elimine los caracteres no disponibles. La Número :: Teléfono :: Normalizar El módulo Perl podría ser una fuente de inspiración.

Respondido el 23 de Septiembre de 08 a las 22:09

Voy a arriesgarme y decir que permitir el 911 como número de teléfono es probablemente una mala idea en casi todas las aplicaciones de esta expresión regular. Aunque es una buena captura. - Nicolás Flynt

Trabajo para una empresa de investigación de mercado y tenemos que filtrar este tipo de insumos todo el tiempo. Lo estás complicando demasiado. Simplemente elimine los caracteres no alfanuméricos y vea si hay una extensión.

Para un análisis más detallado, puedes suscribirte a uno de los muchos proveedores que te darán acceso a una base de datos de números válidos y te dirán si son teléfonos fijos o móviles, desconectados, etc. Cuesta dinero.

Respondido el 23 de Septiembre de 08 a las 21:09

¿Validación? 123% $) *% () $ * () # 456 * () * $ # (* (# $ @ 8908 coincidiría con su solución propuesta. - Plex Q

@PlexQ 555-123-1234, 07777777777, 90210, 01/01/1901: los usuarios son ingeniosos para apisonar la basura a través de la validación. Es mejor no molestar a los que realmente tienen algunos datos extraños utilizando una validación demasiado restrictiva y diciéndoles que están equivocados. - Reactivo Cuervo

Reemplace los caracteres de formato, luego verifique el resto para verificar la validez del teléfono. 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 );

Romper una expresión regular compleja como esta puede ser igual de efectivo, pero mucho más simple.

Respondido 21 Jul 09, 13:07

Encontré que esto era algo interesante. No lo he probado pero parece que funcionaría

<?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.';
}
?>

respondido 01 mar '11, 13:03

Su mensaje parece indicar que no escribió este código. ¿Le importaría citar una fuente, por favor? - Alastair Irvine

Probablemente sería mejor utilizar una entrada enmascarada para esto. De esa manera, los usuarios SOLO pueden ingresar números y usted puede formatear como mejor le parezca. No estoy seguro de si esto es para una aplicación web, pero si lo es, hay un complemento jQuery que ofrece algunas opciones para hacer esto.

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

Incluso repasan cómo enmascarar las entradas de números de teléfono en su tutorial.

Respondido 11 ago 11, 06:08

Aquí hay uno que funciona bien en JavaScript. Está en una cadena porque eso es lo que esperaba el widget Dojo.

Coincide con un número NANP de América del Norte de 10 dígitos con extensión opcional. Se aceptan como delimitadores los espacios, guiones y puntos.

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

contestado el 13 de mayo de 12 a las 20:05

Estaba luchando con el mismo problema, tratando de hacer que mi aplicación fuera a prueba de futuro, pero estos chicos me llevaron en la dirección correcta. En realidad, no estoy verificando el número en sí para ver si funciona o no, solo estoy tratando de asegurarme de que se ingresó una serie de números que pueden tener o no una extensión.

En el peor de los casos, si el usuario tuviera que extraer un número sin formato del archivo XML, aún así simplemente escribiría los números en el teclado numérico del teléfono. 012345678x5, no hay ninguna razón real para mantenerlo bonito. Ese tipo de expresión regular me resultaría algo como esto:

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

Respondido 18 Oct 12, 20:10

Mi inclinación es estar de acuerdo en que lo mejor es eliminar los números que no son dígitos y simplemente aceptar lo que hay. Tal vez para asegurarse de que haya al menos un par de dígitos, aunque eso prohíbe algo como un número de teléfono alfabético "ASK-JAKE", por ejemplo.

Un par de expresiones simples de perl podrían ser:

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

Utilice el primero para mantener juntos los grupos de dígitos, lo que puede dar pistas sobre el formato. Utilice el segundo para lanzar trivialmente todos los que no sean dígitos.

¿Le preocupa que sea necesario hacer una pausa y luego ingresar más claves? ¿O algo como 555-1212 (espere el pitido) 123?

Respondido el 23 de Septiembre de 08 a las 23:09

    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

Debe terminar con un dígito, puede comenzar con (o + o un dígito, y puede contener + - (o)

Respondido 28 Feb 11, 23:02

Para cualquier persona interesada en hacer algo similar con los números de teléfono móvil irlandeses, aquí hay una forma sencilla de lograrlo:

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";

También hay una solución JQuery en ese enlace.

EDIT:

Solución 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.

Respondido 30 Abr '15, 16:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.