2012-07-11 19 views
42
>>> match = re.findall(r'\w\w', 'hello') 
>>> print match 
['he', 'll'] 

Dado que \ w \ w significa dos caracteres, se esperan 'he' y 'll'. ¿Pero por qué 'el' y 'lo' no coinciden con la expresión regular?¿Cómo encontrar coincidencias superpuestas con una expresión regular?

>>> match1 = re.findall(r'el', 'hello') 
>>> print match1 
['el'] 
>>> 
+2

[Lookahead] (http://stackoverflow.com/questions/320448/overlapping-matches-in-regex) –

Respuesta

70

findall no cede partidos superpuestas de forma predeterminada. Esta expresión hace sin embargo:

>>> re.findall(r'(?=(\w\w))', 'hello') 
['he', 'el', 'll', 'lo'] 

Aquí (?=...) es una lookahead assertion:

(?=...) coincide si ... partidos siguientes, pero no consume cualquiera de la cadena . Esto se llama una afirmación de anticipación. Por ejemplo, Isaac (?=Asimov) coincidirá con 'Isaac ' solo si va seguido de 'Asimov'.

7

Excepto por la aserción de longitud cero, el carácter en la entrada siempre se consumirá en la coincidencia. Si alguna vez está en el caso en que desea capturar cierto carácter en la cadena de entrada más una vez, necesitará una aserción de longitud cero en la expresión regular.

Hay varias afirmación de longitud cero (por ejemplo ^ (inicio de la entrada/línea), $ (final de la entrada/línea), \b (límite de palabra)), pero mira-around ((?<=) positivo mirada-atrás y (?=) look-ahead positivo) son la única forma en que puede capturar texto superpuesto de la entrada. Las visualizaciones negativas ((?<!) look-behind negativo, (?!) look-ahead negativo) no son muy útiles aquí: si son ciertas, la captura en el interior falló; si afirman que es falso, entonces la coincidencia falla. Estas aserciones son de longitud cero (como se mencionó anteriormente), lo que significa que afirmarán sin consumir los caracteres en la cadena de entrada. En realidad, coincidirán con la cadena vacía si la afirmación pasa.

La aplicación de los conocimientos anteriores, una expresión regular que funcione para su caso sería:

(?=(\w\w)) 
20

Puede utilizar el new Python regex module, que apoya la superposición de partidos.

>>> import regex as re 
>>> match = re.findall(r'\w\w', 'hello', overlapped=True) 
>>> print match 
['he', 'el', 'll', 'lo'] 
Cuestiones relacionadas