Регулярные выражения Python для реализации удаления строк - PullRequest
13 голосов
/ 17 августа 2008

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

Ответы [ 5 ]

8 голосов
/ 18 августа 2008

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

В версии 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 голосов
/ 17 августа 2008

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

"\\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 Кена Томпсона ", в котором наш герой использует подобный пример, чтобы объяснить опасности доверяющих компиляторов, которые вы сами не загрузили из машинного кода.

1 голос
/ 17 августа 2008

Идея состоит в том, что я прочитаю экранированную строку и удалю ее (особенность, отсутствующая в 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 голосов
/ 18 августа 2008

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

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

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

0 голосов
/ 17 августа 2008

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