2008-08-17 11 views
11

Próbuję zaimplementować ciąg znaków bez znaków z wyrażeniem regularnym w języku Python i odsyłaczami wstecznymi i wydaje się, że nie chce on działać bardzo dobrze. Jestem pewien, że coś robię źle, ale nie mogę dowiedzieć się, co ...Wyrażenia regularne w języku Python służące do implementacji usuwania ciągów znaków

>>> import re 
>>> mystring = r"This is \n a test \r" 
>>> p = re.compile("\\\\(\\S)") 
>>> p.sub("\\1", mystring) 
'This is n a test r' 
>>> p.sub("\\\\\\1", mystring) 
'This is \\n a test \\r' 
>>> p.sub("\\\\1", mystring) 
'This is \\1 a test \\1' 

Chciałbym wymienić \\ [char] z \ [char], ale odwołania wstecznego w Pythonie nie wydaje się, aby przestrzegać tych samych zasad, które stosują w każdej innej implementacji, w jakiej kiedykolwiek korzystałem. Czy ktoś mógłby rzucić trochę światła?

Odpowiedz

8

Czy nie to właśnie Anders "Drugi przykład ma?

w 2,5 istnieje również string-escape kodowania można zastosować:

>>> mystring = r"This is \n a test \r" 
>>> mystring.decode('string-escape') 
'This is \n a test \r' 
>>> print mystring.decode('string-escape') 
This is 
a test 
>>> 
3

Cóż, myślę, że masz nieodebrane R lub miscounted ukośniki ...

"\\n" == r"\n" 

>>> import re 
>>> mystring = r"This is \\n a test \\r" 
>>> p = re.compile(r"[\\][\\](.)") 
>>> print p.sub(r"\\\1", mystring) 
This is \n a test \r 
>>> 

Które, jeśli rozumieć to, co było wymagane.

Podejrzewam, że bardziej powszechne prośba jest taka:

>>> d = {'n':'\n', 'r':'\r', 'f':'\f'} 
>>> p = re.compile(r"[\\]([nrfv])") 
>>> print p.sub(lambda mo: d[mo.group(1)], mystring) 
This is \ 
a test \ 
>>> 

Zainteresowany student powinien także czytać Ken Thompson Reflections on Trusting Trust", w którym nasz bohater wykorzystuje podobny przykład wyjaśnić niebezpieczeństwa zaufanych kompilatory nie masz bootstrapped od sam kod maszynowy.

0

Jesteś oszukiwany przez reprezentację napisu w Pythonie. Wyrażenie Python:

'This is \\n a test \\r' 

reprezentuje ciąg

This is \n a test \r 

który myślę, co chciał. Spróbuj dodać "print" przed każdym z twoich wywołań p.sub(), aby wydrukować rzeczywisty ciąg zwracany zamiast reprezentacji napisanej w Pythonie.

>>> mystring = r"This is \n a test \r" 
>>> mystring 
'This is \\n a test \\r' 
>>> print mystring 
This is \n a test \r 
0

Chodzi o to, że będę czytać w zbiegłego sznurka i przywróceniu znaczenia go (funkcja szczególnie brakuje od Pythona, który nie ma potrzeby uciekać się do wyrażeń regularnych w pierwszej kolejności). Niestety nie mam czym oszukane przez ukośniki ...

Innym przykładem ilustracyjne:

>>> mystring = r"This is \n ridiculous" 
>>> print mystring 
This is \n ridiculous 
>>> p = re.compile(r"\\(\S)") 
>>> print p.sub('bloody', mystring) 
This is bloody ridiculous 
>>> print p.sub(r'\1', mystring) 
This is n ridiculous 
>>> print p.sub(r'\\1', mystring) 
This is \1 ridiculous 
>>> print p.sub(r'\\\1', mystring) 
This is \n ridiculous 

Co chciałbym go wydrukować to

This is 
ridiculous 
0

Mark; jego drugi przykład wymaga, aby każda znak Escaped wprowadzony do tablicy początkowo generował KeyError, jeśli sekwencja unikowa nie znajduje się w tablicy. Umrze na czymkolwiek poza dostarczonymi trzema znakami (da \ v próbę), i wyliczanie każdej możliwej sekwencji escape za każdym razem, gdy chcesz unescape string (lub utrzymywanie globalnej tablicy) jest naprawdę złym rozwiązaniem. Analogicznie do PHP, używa się preg_replace_callback() z lambdą zamiast preg_replace(), co w tej sytuacji jest zupełnie niepotrzebne.

Przykro mi, jeśli będę o tym mówić, jestem po prostu sfrustrowany Pythonem.Jest to obsługiwane przez każdy inny mechanizm wyrażeń regularnych, z którego korzystałem, i nie mogę zrozumieć, dlaczego to nie zadziała.

Dziękuję za odpowiedź; funkcja string.decode('string-escape') jest dokładnie tym, czego początkowo szukałem. Jeśli ktoś ma ogólne rozwiązanie problemu z odnośnikiem zwrotnym regex, możesz go opublikować, a ja również przyjmuję to jako odpowiedź.