2011-10-13 14 views
34

Estoy tratando de extraer todas las apariciones de palabras etiquetadas de una cadena utilizando expresiones regulares en Python 2.7.2. O simplemente, quiero extraer cada fragmento de texto dentro de las etiquetas [p][/p]. Aquí es mi intento:Python regex findall

regex = ur"[\u005B1P\u005D.+?\u005B\u002FP\u005D]+?" 
line = "President [P] Barack Obama [/P] met Microsoft founder [P] Bill Gates [/P], yesterday." 
person = re.findall(pattern, line) 

impresión person produce ['President [P]', '[/P]', '[P] Bill Gates [/P]']

¿Cuál es la expresión regular correcta para obtener: ['[P] Barack Obama [/P]', '[P] Bill Gates [/p]'] o ['Barrack Obama', 'Bill Gates'].

Gracias. :)

Respuesta

54
import re 
regex = ur"\[P\] (.+?) \[/P\]+?" 
line = "President [P] Barack Obama [/P] met Microsoft founder [P] Bill Gates [/P], yesterday." 
person = re.findall(regex, line) 
print(person) 

produce

['Barack Obama', 'Bill Gates'] 

La expresión regular ur"[\u005B1P\u005D.+?\u005B\u002FP\u005D]+?" es exactamente el mismo Unicode como u'[[1P].+?[/P]]+?' excepto más difícil de leer.

El primer grupo entre corchetes [[1P] dice re que cualquiera de los caracteres en la lista ['[', '1', 'P'] debe coincidir, y de manera similar con el segundo grupo entre corchetes [/P]] .Eso no es lo que desea en absoluto. Por lo tanto,

  • Retire los corchetes exteriores que encierran. (También quite la parásita 1 delante de P.)
  • para proteger los soportes de literales en [P], escapar de los soportes con una barra invertida : \[P\].
  • Para devolver solo las palabras dentro de las etiquetas, coloque el paréntesis de agrupación alrededor de .+?.
10

Prueba esto:

for match in re.finditer(r"\[P[^\]]*\](.*?)\[/P\]", subject): 
     # match start: match.start() 
     # match end (exclusive): match.end() 
     # matched text: match.group() 
+0

me gusta mucho esta respuesta. Si desea procesar solo las coincidencias, esto lo hace sin ninguna declaración adicional, como 1) guardar la lista, 2) procesar la lista no es equivalente a str = 'purple [email protected], blah monkey [email protected] bla 'lavavajillas' ## Aquí re.findall() devuelve una lista de todas las cadenas de correo electrónico encontradas correos electrónicos = re.findall (r '[\ w \ .-] + @ [\ w \ .-] +', str) ## ['[email protected]', 'bob @ abc.com '] para correo electrónico en correos electrónicos: # hacer algo con cada cadena de correo electrónico encontrado imprimir correo electrónico – kkron

3

Su pregunta no es 100% claro, pero estoy asumiendo que usted quiere encontrar todas las piezas de texto dentro [P][/P] tags:

>>> import re 
>>> line = "President [P] Barack Obama [/P] met Microsoft founder [P] Bill Gates [/P], yesterday." 
>>> re.findall('\[P\]\s?(.+?)\s?\[\/P\]', line) 
['Barack Obama', 'Bill Gates'] 
1

que pueda reemplace su patrón con

regex = ur"\[P\]([\w\s]+)\[\/P\]" 
+0

Tenga cuidado con su formateo; * use la región de vista previa *. Debido a que no lo formateó correctamente, las barras invertidas se consumieron (la reducción es mala). –

+0

¿Por qué haces '[\ w \ s] +' en lugar de '. *?' Que es lo que usó? Me parece que '. *?' Es más probable que sea lo que él quiere, de todos modos. '[\ w \ s]' es terriblemente limitante. –

+0

La limitación en intencional. Yo uso [\ w \ s] + porque aparentemente el asker quiere extraer nombres que rara vez contienen números. También tenga en cuenta que el asker quería extraer palabras, no números. Sólo mi opinión, cmiiw – pram

1

Use esto patrón,

pattern = '\[P\].+?\[\/P\]'

Comprobar here