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

StackOverflow https://stackoverflow.com/questions/13791

  •  08-06-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

Идея заключается в том, что я прочитаю экранированную строку и отменю ее экранирование (функция, которой явно не хватает в 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

Вас обманывает представление результирующей строки в 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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top