Obsługa odwołań wstecznych do przechwytywania grup we wzorcu zastępowania odp

86

Chcę wziąć ciąg 0.71331, 52.25378i zwrócić 0.71331,52.25378- tj. Po prostu poszukaj cyfry, przecinka, spacji i cyfry i usuń spację.

To jest mój obecny kod:

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

Ale to mi daje 0.7133,2.25378. Co ja robię źle?

Richard
źródło
4
Ponieważ w rzeczywistości nie chcesz przechwytywać cyfr, bardziej sensowne może być użycie rozglądania się, tj re.sub(r'(?<=\d), (?=\d)', ',', coords). : .
ig0774
1
To konkretne pytanie nie wymaga wyrażenia regularnego, użyj zamiany: coords.replace(' ', '')
Gringo Suave

Odpowiedzi:

116

Powinieneś używać nieprzetworzonych ciągów dla wyrażenia regularnego, spróbuj wykonać następujące czynności:

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

W obecnym kodzie ukośniki odwrotne w zastępczym ciągu znaków zastępują cyfry, więc zastępujesz wszystkie dopasowania odpowiednikami chr(1) + "," + chr(2):

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

Za każdym razem, gdy chcesz pozostawić ukośnik odwrotny w ciągu, użyj rprzedrostka lub użyj znaku ucieczki przed każdym ukośnikiem odwrotnym ( \\1,\\2).

Andrew Clark
źródło
2
Dzięki, to załatwiło sprawę. docs.python.org/library/re.html#raw-string-notation dla każdego, kto to czyta.
Richard
1
Również stackoverflow.com/questions/2081640/ ... dla lepszego wyjaśnienia, czym są nieprzetworzone łańcuchy.
Richard
Jak właściwie wydrukowałbyś nazwę grupy z powyższego przykładu? Powiedzmy, że jeśli grupa jest \1nazywana xCoord , czy można poinstruować, re.subaby zastąpić łańcuchy podrzędne nazwami grup takimi, które re.sub(r"(\d), (\d)", r"\1,\2", coords)spowodowałyby literał ciąguxCoord,52.25378
zelusp
To nie działa w Python3. Użycie \1zastępuje go jakimś dziwacznym znakiem Unicode.
Cerin
15

Python interpretuje \1znak jako znak o wartości ASCII 1 i przekazuje go do sub.

Użyj nieprzetworzonych ciągów, w których Python nie interpretuje \.

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

Jest to omówione na początku redokumentacji , jeśli potrzebujesz więcej informacji.

Petr Viktorin
źródło