Регулярные выражения Python для реализации удаления строк

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

>>> 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] на \ [char], но обратные ссылки в Python, похоже, не следуют тем же правилам, что и в любой другой реализации, которую я когда-либо использовал. Может ли кто-то пролить свет?

17.08.2008 18:20:21
5 ОТВЕТОВ
РЕШЕНИЕ

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

В 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 
>>> 
8
17.08.2008 21:36:32

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

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

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

3
17.08.2008 19:41:23

Вы обмануты представлением 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
17.08.2008 19:26:33

Идея состоит в том, что я буду читать в экранированной строке и удалять ее (особенность, отсутствующая в 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
1
17.08.2008 19:40:49

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

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

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

0
17.08.2008 21:55:54