Hífen dentro de conjuntos em expressões regulares do Python
O hífen - também é um caractere especial dentro de [ ]
(mas fora deles - não). Se você precisa do próprio
hífen como um caractere - coloque-o onde
ele não será interpretado como um separador de
intervalo.
Por que isso é importante: você pode criar um intervalo
de caracteres sem perceber. Por exemplo,
assim - '[:-@]' - você acha que está
selecionando dois-pontos, hífen e arroba, mas na
verdade, obtém-se um intervalo de caracteres entre
: e @. Este intervalo inclui
os seguintes caracteres: ? < = > :
De onde eles vêm? Da tabela ASCII - o dois-pontos tem um número menor que o da arroba - e assim forma-se um intervalo. Ou seja, todos os intervalos são formados de acordo com a tabela ASCII (se desejar, você pode usar isso a seu favor).
Como lidar com isso: coloque o caractere
hífen onde ele definitivamente não será interpretado
como um caractere de intervalo, por exemplo, no início ou
no final (ou seja, depois de [ ou antes
de ]).
Você também pode escapar o hífen - então
ele representará a si próprio, independentemente
da posição. Por exemplo, em vez de [:-@]
escreva [:\-@] - e não haverá mais um intervalo,
mas sim três caracteres - dois-pontos,
hífen e arroba @.
Exemplo
No exemplo a seguir, o padrão de busca é:
dígito 1, depois uma letra de 'a'
a 'z', depois dígito 2:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[a-z]2', '!', txt)
print(res)
Resultado da execução do código:
'! 1-2 ! !'
Exemplo
Agora vamos escapar o hífen. Como
resultado, o padrão de busca é: dígito
1, depois a letra 'a', ou
hífen, ou a letra 'z', depois dígito
2:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[a\-z]2', '!', txt)
print(res)
Resultado da execução do código:
'! ! 1c2 !'
Exemplo
Você pode simplesmente reposicionar o hífen, sem escapá-lo:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[az-]2', '!', txt)
print(res)
Resultado da execução do código:
'! ! 1c2 !'
Exemplo
No exemplo a seguir, o padrão de busca é:
o primeiro caractere é letras minúsculas ou
hífen '-', depois duas letras
'x':
txt = 'axx Axx -xx @xx'
res = re.sub('[a-z-]xx', '!', txt)
print(res)
Resultado da execução do código:
'! Axx ! @xx'
Exemplo
No exemplo a seguir, o padrão de busca é:
o primeiro caractere é letras minúsculas, letras maiúsculas
ou hífen '-', depois duas letras
'x':
txt = 'axx Axx -xx @xx'
res = re.sub('[a-zA-Z-]xx', '!', txt)
print(res)
Resultado da execução do código:
'! ! ! @xx'
Exemplo
Você pode colocar o hífen entre dois intervalos - lá ele definitivamente não criará outro intervalo:
txt = 'axx 9xx -xx @xx'
res = re.sub('[a-z-0-9]xx', '!', txt)
print(res)
Resultado da execução do código:
'! ! ! @xx'
Problemas práticos
Dada a string:
txt = 'xaz xBz xcz x-z x@z'
Encontre todas as strings seguindo o padrão:
letra 'x', letra maiúscula ou minúscula
ou hífen, letra 'z'.
Dada a string:
txt = 'xaz x$z x-z xcz x+z x%z x*z'
Encontre todas as strings seguindo o padrão:
letra 'x', depois ou cifrão, ou
hífen ou sinal de mais, depois letra 'z'.