2011-06-29 38 views
5

tengo cadenas que parecen siguientes:Python expresiones regulares para extraer la fecha

{server}_{date:YYYYMMDD}{int:######} 
{server}_{date:MON DAY YYYY}{int:######} 

... y más, en diferentes formatos de fecha. Además, puede haber cualquier cantidad de {} bloques, y pueden aparecer en cualquier orden.

Estoy tratando de obtener solo la parte de "fecha" entre las llaves en Python 3.2. Entonces, para la primera cadena, quiero obtener solo "{date: YYYYMMDD}" y para la segunda cadena solo quiero "{date: MON DAY YYYY}". Los únicos caracteres que quiero dentro del bloque "fecha" son alfa y espacio en blanco.

Mi patrón de expresión es:

\{date:(\w|\s)*\} 

He probado esto en this Regex builder, pero no se emparejan como se esperaba. Este es mi resultado en Python:

>>> import re 
>>> re.findall('\{date:(\w|\s)*\}', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['D', 'Y'] 
>>> re.findall('\{date:(\w|\s)*\}', '{server}_{date:MON DAY YYYY}{int:######}') 
['Y'] 

¿Puede alguien indicar qué problema hay en mi patrón?

+0

¡Gracias por todas las respuestas! Al ver las respuestas de todos ahora, es obvio que omití detalles importantes en mi pregunta. Edité mi publicación y agregué algunos más detalles. – tgxiii

Respuesta

5

'(\{date:[\w\s]+\})' da lo que quiere:

>>> import re 
>>> re.findall('(\{date:[\w\s]+\})', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['{date:YYYYMMDD}', '{date:MONDAYYYYY}'] 
>>> re.findall('(\{date:[\w\s]+\})', '{server}_{date:MON DAY YYYY}{int:######}') 
['{date:MON DAY YYYY}'] 

Si desea que sólo valor de datos, utilice '\{date:([\w\s]+)\}'.

1

probar esto

str = '{server}_{date:MON DAY YYYY}{int:######}' 
re.findall('\{date:.*\}(?=\{)',str) 

que vuelve este

['{date:MON DAY YYYY}'] 

y

str = '{server}_{date:YYYYMMDD}{int:######}' 
re.findall('\{date:.*\}(?=\{)',str) 

devuelve lo siguiente:

[ '{fecha: AAAAMMDD}']

la (?=..\{) hace lo siguiente:

(? = ...) Partidos ... si coincide siguiente, pero doesn no consuma ninguna de las cuerdas. Esto se llama una afirmación de anticipación. Por ejemplo, Isaac (? = Asimov) coincidirá con 'Isaac' solo si es seguido por 'Asimov'. (source)

nota: esto sólo funcionará si otro bloque {..} siguiente {fecha}, supongo que esto es necesario, y si se echa en falta su entrada puede ser válido.

+0

Debería haber mencionado que puede haber cualquier cantidad de {} bloques, y pueden aparecer en cualquier orden. Mi mal, mi pregunta no fue lo suficientemente detallada. Aunque aprecio la respuesta. – tgxiii

+0

bueno, esto todavía encontrará el bloque que comienza con '{date:. *]' Siempre que otro bloque lo siga. – matchew

0
'{server}_({date:.+?}){int:' 

suficiente

.

o, puede ser mejor

'(?<={server}_)({date:.+?})(?={int:)' 
2
>>> re.findall('\{date:([\w\s]*)\}', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['YYYYMMDD', 'MONDAYYYYY'] 
0

utilizar un grupo de captura de alrededor de toda la expresión regular, y un grupo no captura para la parte (\w|\s):

(\{date:(?:\w|\s)*\})

que la voluntad dé como resultado la salida que desea:

>>> re.findall('(\{date:(?:\w|\s)*\})', '{server}_{date:MON DAY YYYY}{int:######}') 
['{date:MON DAY YYYY}'] 
>>> re.findall('(\{date:(?:\w|\s)*\})', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['{date:YYYYMMDD}', '{date:MONDAYYYYY}'] 
+0

No es realmente necesario colocar paréntesis alrededor de la expresión regular completa si usa un grupo que no captura. ''\ {date: (?: \ w | \ s) * \}'' genera el mismo resultado. – senderle

Cuestiones relacionadas