2008-08-17 5 views
11

Я пытаюсь реализовать строку unescaping с регулярным выражением и обратными ссылками Python и, похоже, не очень хорошо работает. Я уверен, что это то, что я делаю неправильно, но я не могу понять, что ...Python Regular Выражения для реализации строки unescaping

>>> 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' 

Я хотел бы заменить \\ [символ] с \ [Char], но обратные ссылки в Python по-видимому, не соответствуют тем же правилам, которые они применяют в каждой другой реализации, которую я когда-либо использовал. Может ли кто-то пролить свет?

ответ

8

Разве это не то, что Андерс второй пример?

В 2.5 есть также string-escape кодировки Вы можете применить:

>>> 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

Ну, я думаю, что вы, возможно, пропустили г или просчитались обратный слэш ...

"\\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 
>>> 

Что, если я понял то, что было предложено.

Я подозреваю, что более общий запрос состоит в следующем:

>>> 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 \ 
>>> 

Заинтересованный студент должен также прочитать Кен Томпсон Reflections on Trusting Trust", в котором наш герой использует аналогичный пример для объяснения опасностей доверяющих компиляторов вы не бутстрапируемые от машинный код самостоятельно.

0

Вы обманываете представление Python строки результата. Выражение Python:

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

представляет собой строку

This is \n a test \r 

, который я думаю, что вы хотели. Попробуйте добавить 'print' перед каждым вызовом p.sub(), чтобы напечатать фактическую строку, возвращаемую вместо представления строки Python.

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

Идея заключается в том, что я буду читать в сбежавшей строке, и его экранирование в (функции особенно не хватает из Python, которые вы не должны прибегать к регулярным выражениям для в первой очереди). К сожалению, я не осмеянный ... обратных слэши

Другой показательный пример:

>>> 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 

То, что я хотел бы, чтобы напечатать это

This is 
ridiculous 
0

Марк; его второй пример требует, чтобы каждый экранированный символ сначала попадал в массив, который генерирует KeyError, если escape-последовательность не входит в массив. Он умрет на чем угодно, кроме трех предоставленных символов (дайте \ v a try), и перечисление каждой возможной escape-последовательности каждый раз, когда вы захотите отменить строку (или сохранить глобальный массив), является действительно плохим решением. Аналогично PHP, это использует preg_replace_callback() с лямбдой вместо preg_replace(), что совершенно не нужно в этой ситуации.

Извините, если я схожу с ума, я просто разочарован Python.Это поддерживается всеми другими механизмами регулярных выражений, которые я когда-либо использовал, и я не понимаю, почему это не сработает.

Благодарим за отзыв; функция string.decode('string-escape') - это именно то, что я искал изначально. Если у кого-то есть общее решение проблемы с regex backreference, не стесняйтесь публиковать его, и я соглашусь с этим как на ответ.

 Смежные вопросы

  • Нет связанных вопросов^_^