Escapando caracteres especiais em expressões regulares do Python
Suponha que você precise fazer com que um caractere especial represente a si mesmo. Para isso, ele deve ser escapado com uma barra invertida. Vejamos alguns exemplos.
Exemplo
No exemplo a seguir, o autor da regex queria
que o padrão de pesquisa fosse: letra
'a', seguida de um sinal de mais '+', seguida
da letra 'x'. No entanto, o autor do código
não escapou o caractere '+' e, portanto,
o padrão de pesquisa na verdade é:
letra 'a' uma ou mais vezes,
depois a letra 'x':
txt = 'a+x ax aax aaax'
res = re.sub('a+x', '!', txt)
print(res)
Resultado da execução do código:
'a+x ! ! !'
Exemplo
Agora, o autor escapou o sinal de mais com uma
barra invertida. Agora o padrão de pesquisa está
como deveria: letra 'a', seguida de sinal de mais
'+', seguida da letra 'x':
txt = 'a+x ax aax aaax'
res = re.sub('a\+x', '!', txt)
print(res)
Resultado da execução do código:
'! ax aax aaax'
Exemplo
Neste exemplo, o padrão é:
letra 'a', seguida de um ponto '.',
seguida da letra 'x':
txt = 'a.x abx azx'
res = re.sub('a\.x', '!', txt)
print(res)
Resultado da execução do código:
'! abx azx'
Exemplo
No exemplo a seguir, o autor esqueceu de escapar o ponto e a regex capturou todas as substrings, pois um ponto não escapado representa qualquer caractere:
txt = 'a.x abx azx'
res = re.sub('a.x', '!', txt)
print(res)
Resultado da execução do código:
'! ! !'
Observação
Preste atenção ao fato de que se você esquecer a barra invertida para o ponto (quando ele deve representar a si mesmo) - isso pode passar despercebido:
res = re.sub('a.x', '!', 'a.x')
print(res) # retorna '!', como queríamos
Visualmente funciona corretamente (já que o ponto
representa qualquer caractere, inclusive
um ponto comum '.'). Mas se mudarmos
a string na qual as substituições ocorrem - nós
veremos nosso erro:
res = re.sub('a.x', '!', 'a.x abx azx')
print(res) # retorna '! ! !', mas esperávamos '! abx azx'
Lista de caracteres especiais e comuns
Se você escapar um caractere comum - nada de ruim acontecerá - ele ainda representará a si mesmo. Exceção - dígitos, eles não podem ser escapados.
Muitas vezes surge a dúvida se um determinado caractere é especial. Alguns chegam a escapar todos os caracteres suspeitos seguidamente. No entanto, esta é uma má prática (polui a regex com barras invertidas).
São caracteres especiais: $ ^ . * + ? \ / {} [] () |
Não são caracteres especiais: @ : , ' " - _ = < > % # ~ `& !
Tarefas práticas
Dada a string:
txt = 'a.a aba aea'
Escreva uma expressão regular que encontrará a string
'a.a', sem capturar as outras.
Dada a string:
txt = '2+3 223 2223'
Escreva uma expressão regular que encontrará a string
'2+3', sem capturar as outras.
Dada a string:
txt = '23 2+3 2++3 2+++3 345 567'
Escreva uma expressão regular que encontrará as strings
'2+3', '2++3', '2+++3',
sem capturar as outras (+ pode ser qualquer
quantidade).
Dada a string:
txt = '23 2+3 2++3 2+++3 445 677'
Escreva uma expressão regular que encontrará as strings
'23', '2+3', '2++3',
'2+++3', sem capturar as outras.
Dada a string:
txt = '*+ *q+ *qq+ *qqq+ *qqq qqq+'
Escreva uma expressão regular que encontrará as strings
'*q+', '*qq+', '*qqq+',
sem capturar as outras.
Dada a string:
txt = '[abc] {abc} abc (abc) [abc]'
Escreva uma expressão regular que encontrará as strings
entre colchetes e as substituirá por
'!'.