Para além das expressões regulares que eu usava com o FLEX, e também depois, com o PERL e o PHP, o Python tem umas expressões novas, que me parecem ter sido criadas pelo próprio Python, e que são bastante interessantes.
*?, +?, ??
Cria uma versão não gananciosa dos quantificadores *, +, ?. Neste caso, vai ser encontrada a expressão mínima, ao invés da expresão máxima.
{m,n}?
Da mesma forma que no caso anterior, aqui vai ser encontrada a expressão mínima de {m,n}. Por exemplo, para a string de 6 carateres 'aaaaaa', a{3,5} emparelha 5 carateres 'a', enquanto que a{3,5}? emparelha apenas 3 carateres.
(?...)
É uma notação de extensão. O caráter após o ? define o resto da sintaxe. Ver abaixo.
(?iLmsux)
As letras 'i', 'L', 'm', 's', 'u', 'x' correpondem às flags re.I (ignore case), re.L (locale dependent), re.M (multi-line), re.S (dot matches all), re.U (Unicode dependent), and re.X (verbose), para toda a expressão regular. Alternativamente, também se pode passar a flag na função re.compile().
(?:...)
Captura uma expressão, mas ignora-a no grupo de expressões capturadas
(?P<name>...)
Atribui um nome ao objeto capturado. Substitui o nome group. Na mesma expressão, o nome name é único. Por exemplo, (?P<quote>['"]).*?(?P=quote) captura qualquer string delimitada por aspas ou plicas.
(?P=name)
Equivalente ao anterior.
(?#...)
Comentário. Ignorado.
(?#...)
Emparelha, se ... emparelhar o próximo, mas não consome a string. É chamada uma lookahead assertion. Por exemplo, Isaac (?=Asimov) emparelha 'Isaac ' apenas se seguido de 'Asimov'.
(?!...)
Emparelha se não emparelhar o próximo. É uma negative lookahead assertion. Por exemplo, Isaac (?!Asimov) emparelha 'Isaac ' apenas se não for seguido de 'Asimov'.
(?<=...)
Emparelha se a posição atual na string for precedida por um emparelhamento de ... que termine na posição atual. É denominada uma positive lookbehind assertion. (?<=abc)def emparelha com abcdef, uma vez que o lookbehind volta atrás 3 carateres e verifica se o padrão mencionado emparelha.
>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0)
'def'
Outro exemplo, que procura uma palavra que segue um hífen.
>>> m = re.search('(?<=-)\w+', 'spam-egg') >>> m.group(0)
'egg'
(?<!...)
Emparelha, se a posição atual na string não for precedida por um .... É chamado um negative lookbehind assertion. É o oposto do anterior.
(?(id/name)yes-pattern|no-pattern)
Tenta emparelhar com yes-pattern se o grupo com o id ou o name existir, e com no-pattern se não existir. no-pattern é opcional e pode ser omitido. Por exemplo, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>) é um padrão fraco para emparelhar emails, que emparelha '<user@host.com>' assim como 'user@host.com', masn não '<user@host.com'.
