El carácter punto . en las expresiones regulares

El carácter . (o punto) en una expresión regular se denomina comodín y coincidirá con cualquier carácter excepto con una nueva línea. Por ejemplo, introduzca lo siguiente en el shell interactivo:

>>> import re
>>> atRegex = re.compile(r'.at')
>>> atRegex.findall('The cat in the hat sat on the flat mat.')
['cat', 'hat', 'sat', 'lat', 'mat']

Recuerde que el carácter punto . sólo coincide con un carácter, por lo que la coincidencia del texto flat en el ejemplo anterior sólo coincide con lat. Si desea hacer uso del punto como parte del texto, escape el punto con una barra invertida: \.

Coincidencia de todo con el punto . y el asterisco *

A veces querrá coincidir con todo y cualquier cosa. Por ejemplo, digamos que quiere hacer coincidir la cadena 'First Name:', seguida de cualquier texto, seguida de 'Last Name:', y luego seguida de cualquier cosa de nuevo. Puede utilizar el punto y le asterisco (.*) para sustituir ese «cualquier cosa». Recuerde que el carácter de punto significa «cualquier carácter simple excepto la nueva línea», y el carácter de estrella significa «cero o más del carácter precedente».

Introduzca lo siguiente en el shell interactivo:

>>> nameRegex = re.compile(r'First Name: (.*) Last Name: (.*)')
>>> mo = nameRegex.search('First Name: Al Last Name: Sweigart')
>>> mo.group(1)
'Al'
>>> mo.group(2)
'Sweigart'

El punto y asterisco .* utiliza el modo codicioso: Siempre tratará de coincidir con la mayor cantidad de texto posible. Para hacer coincidir todo el texto en modo no codicioso, utilice el punto, el asterisco y el signo de interrogación (.*?). Al igual que con las llaves, el signo de interrogación le dice a Python que coincida de una manera no codiciosa.

Introduzca lo siguiente en el intérprete de comandos interactivo para ver la diferencia entre las versiones codiciosas y no codiciosas:

>>> nongreedyRegex = re.compile(r'<.*?>')
>>> mo = nongreedyRegex.search('<To serve man> for dinner.>')
>>> mo.group()
'<To serve man>'

>>> greedyRegex = re.compile(r'<.*>')
>>> mo = greedyRegex.search('<To serve man> for dinner.>')
>>> mo.group()
'<To serve man> for dinner.>'

Ambas regexes se traducen aproximadamente en «Coincidir con un paréntesis angular de apertura, seguido de cualquier cosa, seguido de un paréntesis angular de cierre». Pero la cadena '<To serve man> for dinner.>' tiene dos posibles coincidencias para el paréntesis angular de cierre. En la versión no codiciosa de la regex, Python coincide con la cadena más corta posible. En la versión codiciosa, Python busca la cadena más larga posible.

Coincidencia de nuevas líneas con el carácter punto . re.DOTALL

El punto y asterisco coincide con todo excepto con una nueva línea. Pasando re.DOTALL como segundo argumento a re.compile(), puede hacer que el carácter punto coincida con todos los caracteres, incluyendo el carácter de nueva línea.

Introduzca lo siguiente en el shell interactivo:

>>> noNewlineRegex = re.compile('.*')
>>> noNewlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.'


>>> newlineRegex = re.compile('.*', re.DOTALL)
>>> newlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.'

El regex noNewlineRegex, al que ¡no! se le pasó re.DOTALL a la llamada re.compile() que lo creó, coincidirá con todo sólo hasta el primer carácter de nueva línea, mientras que newlineRegex, al que se le pasó re.DOTALL a re.compile(), coincide con todo. Por ello, la llamada newlineRegex.search() coincide con la cadena completa, incluyendo sus caracteres de nueva línea.

Deja una respuesta