2010-02-15 23 views
11

Me gustaría obtener los números de teléfono de un archivo. Sé que los números tienen diferentes formas, puedo manejar una sola, pero no sé cómo obtener una expresión regular uniforme. Por ejemplogrep con expresión regular para el número de teléfono

  1. xxx-xxx-xxxx

  2. (xxx)xxx-xxxx

  3. xxx xxx xxxx

  4. xxxxxxxxxx

I sólo puede manejar 1, 2, una d 4 juntos

grep '[0-9]\{3\}[ -]\?[0-9]\{3\}[ -]\?[0-9]\{4\}' file 

¿Hay una sola expresión regular que pueda manejar estas cuatro formas?

+0

que tendría que manejar 2 separado a través de la alternancia a juego. El problema es que al usar expresiones regulares básicas no hay forma de saber si los parens están balanceados de otra manera. – Joel

+0

Echa un vistazo a Regexr para obtener ayuda de regex ... http://www.gskinner.com/RegExr/ – Moshe

+0

ver comentario debajo –

Respuesta

12
grep '\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?[0-9]\{3\}[ -]\?[0-9]\{4\}' file 

Explicación:

([0-9]\{3\}) tres cifras entre paréntesis

\| o

[0-9]\{3\} tres dígitos no parens dentro

... con paréntesis de agrupación - \(...\) - alrededor de la alternancia por lo que el resto de la expresión regular se comporta de la misma sin importar qué partidos alternativos.

+0

El problema [leve] de este RegEx es que también coincide con un número con más de 4 dígitos en la última parte, por ejemplo 123-123-12345 o un número con más de 10 dígitos. Esto: 'grep '\ (\ (([0-9] \ {3 \}) \ | [0 -9] \ {3 \} \) [-] \? \) \ {2 \} [0-9] \ {4 \} '' debería manejarlo bien. Consulte mi respuesta a continuación para obtener una explicación. ¡Salud! – MacUsers

+0

@MacUsers: Buen punto. El OP solo preguntó cómo conseguir que la expresión regular coincida con todo lo que debería coincidir, y yo contesté eso. Conseguir que * no * coincida con las cosas que no debería ser es mucho más interesante. –

+0

Tenga en cuenta que otro truco usado aquí es la secuencia "[-] \?" Esto permite emparejar un espacio, un guión o cualquier otro carácter usado para separar los grupos de dígitos en el número de teléfono. –

2

Puede simplemente OR (|) sus expresiones geográficas juntas, ¡será más fácil de leer de esa manera también!

+0

¿me puede mostrar un ejemplo? Sé que O (|) podría funcionar, pero no entendí cómo. – skydoor

1

Mi primer pensamiento es que puede encontrar más fácil ver si su número de candidato coincide con una de las cuatro expresiones regulares. Eso será más fácil de desarrollar/depurar, especialmente cuando/cuando tenga que manejar formatos adicionales en el futuro.

-2

Tengo esto:

debian:tmp$ cat p.txt 
333-444-5555 
(333)333-6666 
123 456 7890 
1234567890 
debian:tmp$ egrep '\(?[0-9]{3}[)-]?[0-9]{3}[ -]?[0-9]{4}' p.txt 
333-444-5555 
(333)333-6666 
123 456 7890 
1234567890 
debian:tmp$ egrep --version 
GNU grep 2.5.3 

Copyright (C) 1988, 1992-2002, 2004, 2005 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

debian:tmp$ 
+0

Esto coincidirá (333-444-555 también. – Joel

+0

sí, así lo hará. – Segfault

+0

Intenté esto, pero no creo que sea correcto. – skydoor

1
grep -P '[0-9]{3}-[0-9]{3}-[0-9]{3}|[0-9]{3}\ [0-9]{3}\ [0-9]{3}|[0-9]{9}|\([0-9]{3}\)[0-9]{3}-[0-9]{3}' 
0

Intente éste:

^(\d{10}|((([0-9]{3})\s){2})[0-9]{4}|((([0-9]{3})\-){2})[0-9]{4}|([(][0-9]{3}[)])[0-9]{3}[-][0-9]{4})$

Esto sólo es aplicable para el formiato se mencionó anteriormente como:

  1. xxxxxxxxxx
  2. xxx xxx xxxx
  3. xxx-xxx-xxxx
  4. (xxx)xxx-xxxx
5

por lo general hay cuatro patrones de números de teléfono

1. xxx-xxx-xxxx   grep -o '[0-9]\{3\}\-[0-9]\{3\}\-[0-9]\{4\}' file.txt 
2. (xxx)xxx-xxxx  grep -o '([0-9]\{3\})[0-9]\{3\}\-[0-9]\{4\}' file.txt 
3. xxx xxx xxxx   grep -o '[0-9]\{3\}\s[0-9]\{3\}\s[0-9]\{4\}' file.txt 
4. xxxxxxxxxx   grep -o '[0-9]\{10\}' file.txt 

En todo

grep -o '\([0-9]\{3\}\-[0-9]\{3\}\-[0-9]\{4\}\)\|\(([0-9]\{3\})[0-9]\{3\}\-[0-9]\{4\}\)\|\([0-9]\{10\}\)\|\([0-9]\{3\}\s[0-9]\{3\}\s[0-9]\{4\}\)' file.txt 

Por supuesto, se podría simplificar la expresión regular anterior, pero también puede dejar esta simplificación a grep propio ~

2

Esta es solo una versión modificada de la solución de Alan Moore. Esto está protegido contra alguna condición de carrera en la última parte de la serie tiene más de cuatro dígitos en ella o en el caso de que el número total de dígitos son más de 10:

grep '\(\(([0-9]\{3\})\|[0-9]\{3\}\)[ -]\?\)\{2\}[0-9]\{4\} ' 

Explicación:

  1. \(([0-9]\{3\})\|[0-9]\{3\}\) coincide exactamente con tres dígitos (por ejemplo, 234) con o sin rodeada de paréntesis. \| realiza la operación 'OR'.
  2. Los primeros \(... \) agrupa el formato anterior seguido de una space o - o no space en todo - ([ -]\?) hace eso.
  3. Los \{2\} coincide exactamente con dos apariciones de los anteriores
  4. Los [0-9]\{4\} ' coincide exactamente un ocurrencia de un número de 4 dígitos seguido de un space

y es un poco más corto también. Probado en RHEL y Ubuntu. ¡¡Aclamaciones!!

+0

¡explicación increíble! Me ahorra tiempo para buscar un tutorial. – FisherCoder

0

Podemos poner todas las validaciones de número de teléfono requeridas una por una usando una condición o que es más probable que funcione bien (pero la codificación tediosa).

grep '^[0-9]\{10\}$\|^[0-9]\{3\}[-][0-9]\{3\}[-][0-9]\{4\}$\|^[0-9]\{3\}[ ][0-9]\{3\}[ ][0-9]\{4\}$\|^[(][0-9]\{3\}[)][0-9]\{3\}[-][0-9]\{4\}$' phone_number.txt 

devuelve todos los formatos específicos:

  • 920-702-9999
  • (920)702-9999
0

+ ? (1 [-])? ((\ D {3}) [-] | (\ d {3} [-]?)) {2} \ d {4}

obras para:

123-678-1234

(123) -678-1234

+1 - (123) -678-1234

1- (123) -678-1234

1 (123) 678 1234

0
grep -oE '\(?\<[0-9]{3}[-) ]?[0-9]{3}[ -]?[0-9]{4}\>' 

coincide con todos sus formatos. (|)

Los \< y \> límites de la palabra evitar que los números que son demasiado largos, tales como 123-123-12345 o 1234-123-1234

Cuestiones relacionadas