El guion dentro de conjuntos en expresiones regulares de Python
El guion también es un carácter especial dentro de [ ]
(pero fuera de ellos, no). Si necesitas el guion
como símbolo, colócalo en una posición
donde no sea interpretado como un separador
de rango.
Por qué es importante: puedes crear un rango
de caracteres sin darte cuenta. Por ejemplo,
así - '[:-@]' - tú crees que estás
seleccionando dos puntos, un guion y una arroba,
pero en realidad obtienes un rango de caracteres entre
: y @. Este rango incluye
los siguientes caracteres: ? < = > :
¿De dónde salieron? De la tabla ASCII - los dos puntos tienen un número menor que la arroba - y se forma un rango. Es decir, todos los rangos se forman según la tabla ASCII (si se desea, se puede aprovechar esto).
Cómo solucionarlo: coloca el carácter
guion donde definitivamente no sea interpretado
como un carácter de rango, por ejemplo, al principio o
al final (es decir, después de [ o antes de
]).
También se puede escapar el guion - entonces
representará a sí mismo independientemente
de su posición. Por ejemplo, en lugar de [:-@]
escribir [:\-@] - y no habrá rango,
sino que habrá tres caracteres: dos puntos,
guion y arroba @.
Ejemplo
En el siguiente ejemplo, el patrón de búsqueda es:
dígito 1, luego letra de 'a'
a 'z', luego dígito 2:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[a-z]2', '!', txt)
print(res)
Resultado de la ejecución del código:
'! 1-2 ! !'
Ejemplo
Ahora escapemos el guion. Como
resultado, el patrón de búsqueda es: dígito
1, luego letra 'a', o
guion, o letra 'z', luego dígito
2:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[a\-z]2', '!', txt)
print(res)
Resultado de la ejecución del código:
'! ! 1c2 !'
Ejemplo
Se puede simplemente reubicar el guion, sin escaparlo:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[az-]2', '!', txt)
print(res)
Resultado de la ejecución del código:
'! ! 1c2 !'
Ejemplo
En el siguiente ejemplo, el patrón de búsqueda es:
primer carácter - letras minúsculas o
guion '-', luego dos letras
'x':
txt = 'axx Axx -xx @xx'
res = re.sub('[a-z-]xx', '!', txt)
print(res)
Resultado de la ejecución del código:
'! Axx ! @xx'
Ejemplo
En el siguiente ejemplo, el patrón de búsqueda es:
primer carácter - letras minúsculas, mayúsculas
o guion '-', luego dos letras
'x':
txt = 'axx Axx -xx @xx'
res = re.sub('[a-zA-Z-]xx', '!', txt)
print(res)
Resultado de la ejecución del código:
'! ! ! @xx'
Ejemplo
Se puede colocar el guion entre dos rangos - allí definitivamente no creará otro rango:
txt = 'axx 9xx -xx @xx'
res = re.sub('[a-z-0-9]xx', '!', txt)
print(res)
Resultado de la ejecución del código:
'! ! ! @xx'
Problemas prácticos
Dada la cadena:
txt = 'xaz xBz xcz x-z x@z'
Encuentra todas las cadenas según el siguiente patrón:
letra 'x', letra mayúscula o minúscula
o guion, letra 'z'.
Dada la cadena:
txt = 'xaz x$z x-z xcz x+z x%z x*z'
Encuentra todas las cadenas según el siguiente patrón:
letra 'x', luego signo de dólar, o
guion o signo más, luego letra 'z'.