2009-09-10 14 views
18

Quiero hacer una coincidencia de expresiones regulares (en Python) en el registro de salida de un programa. El registro contiene algunas líneas que se ven así:¿Cómo puedo emparejar la expresión regular con la agrupación con un número desconocido de grupos?

... 
VALUE 100 234 568 9233 119 
... 
VALUE 101 124 9223 4329 1559 
... 

Me gustaría capturar la lista de números que se produce después de la primera incidencia de la línea que comienza con el valor. es decir, quiero que devuelva ('100','234','568','9233','119'). El problema es que no sé de antemano cuántos números habrá.

He intentado utilizar esto como una expresión regular:

VALUE (?:(\d+)\s)+ 

Esto coincide con la línea, pero sólo capta el último valor, por lo que sólo get ('119',).

+1

Basado en una pregunta anterior, veo que no es posible con expresiones regulares: http://stackoverflow.com/questions/464736/python-expresiones-regulares-como-capturar-múltiples-grupos-desde-a -wildcard-expre # 464755 –

Respuesta

16

Lo que está buscando es un analizador, en lugar de una expresión regular coincidente. En su caso, me gustaría considerar el uso de un programa de análisis muy simple, split():

s = "VALUE 100 234 568 9233 119" 
a = s.split() 
if a[0] == "VALUE": 
    print [int(x) for x in a[1:]] 

Se puede utilizar una expresión regular para ver si su línea de entrada coincida con el formato esperado (usando la expresión regular en su pregunta), entonces se puede Ejecute el código anterior sin tener que verificar "VALUE" y sabiendo que la conversión int(x) siempre tendrá éxito ya que ya ha confirmado que los siguientes grupos de caracteres son todos dígitos.

2

Se podía correr estás principal partido de expresiones regulares a continuación, ejecutar una expresión regular secundaria en esos partidos para obtener los números:

matches = Regex.Match(log) 

foreach (Match match in matches) 
{ 
    submatches = Regex2.Match(match) 
} 

Ésta es, por supuesto, también si no desea escribir un analizador completo .

+2

¿Qué lenguaje de programación es este? –

9
>>> import re 
>>> reg = re.compile('\d+') 
>>> reg.findall('VALUE 100 234 568 9233 119') 
['100', '234', '568', '9223', '119'] 

que no valida que la palabra clave 'VALOR' aparece al principio de la cadena, y no valida que hay exactamente un espacio entre los elementos, pero si se puede hacer eso como una separada paso (o si no necesita hacer eso en absoluto), entonces encontrará todas las secuencias de dígitos en cualquier cadena.

2

Otra opción no descrita aquí es tener un grupo de grupos de captura opcionales.

VALUE *(\d+)? *(\d+)? *(\d+)? *(\d+)? *(\d+)? *$ 

Esta expresión regular captura hasta 5 grupos de dígitos separados por espacios. Si necesita más grupos potenciales, simplemente copie y pegue más bloques *(\d+)?.

0

Tuve el mismo problema y mi solución fue usar dos expresiones regulares: la primera para unir todo el grupo que me interesa y la segunda para analizar los subgrupos. Por ejemplo, en este caso, me gustaría empezar con esto:

VALUE((\s\d+)+) 

Esto debe resultar en tres partidos: [0] toda la línea, [1] la materia después de valor [2] el último espacio + valor.

[0] y [2] puede ser ignorado y luego [1] se puede utilizar con los siguientes:

\s(\d+) 

Nota: estas expresiones regulares no fueron probados, espero que la idea sin embargo.


La razón por la Greg's answer no funciona para mí es debido a que la segunda parte del análisis es más complicado y no simplemente algunos números separados por un espacio.

Sin embargo, honestamente voy con la solución de Greg para esta pregunta (probablemente sea mucho más eficiente).

Estoy escribiendo esta respuesta en caso de que alguien esté buscando una solución más sofisticada como la que necesitaba.

Cuestiones relacionadas