Manejo de backreferences para capturar grupos en el patrón de reemplazo re.sub

86

Quiero tomar la cadena 0.71331, 52.25378y regresar 0.71331,52.25378, es decir, solo buscar un dígito, una coma, un espacio y un dígito, y eliminar el espacio.

Este es mi código actual:

coords = '0.71331, 52.25378'
coord_re = re.sub("(\d), (\d)", "\1,\2", coords)
print coord_re

Pero esto me da 0.7133,2.25378. ¿Qué estoy haciendo mal?

Ricardo
fuente
4
Dado que en realidad no desea capturar los dígitos, puede tener más sentido para utilizar Vista-around, es decir: re.sub(r'(?<=\d), (?=\d)', ',', coords).
ig0774
1
Esta pregunta en particular no necesita regex, use reemplazar: coords.replace(' ', '')
Gringo Suave

Respuestas:

116

Debería utilizar cadenas sin formato para expresiones regulares, intente lo siguiente:

coord_re = re.sub(r"(\d), (\d)", r"\1,\2", coords)

Con su código actual, las barras invertidas en su cadena de reemplazo se escapan de los dígitos, por lo que está reemplazando todas las coincidencias por el equivalente de chr(1) + "," + chr(2):

>>> '\1,\2'
'\x01,\x02'
>>> print '\1,\2'
,
>>> print r'\1,\2'   # this is what you actually want
\1,\2

Siempre que desee dejar la barra invertida en la cadena, use el rprefijo o escape cada barra invertida ( \\1,\\2).

Andrew Clark
fuente
2
Gracias, eso hizo el truco. docs.python.org/library/re.html#raw-string-notation para cualquiera que lea esto.
Richard
1
También stackoverflow.com/questions/2081640/… para una mejor explicación de qué son las cadenas sin procesar.
Richard
¿Cómo imprimiría realmente el nombre del grupo en el ejemplo anterior? Diga, si el grupo se \1llamó xCoord , ¿es posible indicar re.subque se reemplacen las subcadenas con nombres de grupo que re.sub(r"(\d), (\d)", r"\1,\2", coords)xCoord,52.25378
resulten
Esto no funciona en Python3. El uso lo \1reemplaza con algún extraño carácter Unicode.
Cerin
15

Python interpreta \1como un carácter con valor ASCII 1 y se lo pasa a sub.

Utilice cadenas sin formato, en las que Python no interpreta el \.

coord_re = re.sub(r"(\d), (\d)", r"\1,\2", coords)

Esto se cubre desde el principio de la redocumentación , en caso de que necesite más información.

Petr Viktorin
fuente