Вопрос-Ответ

What exactly is a "raw string regex" and how can you use it?

Что именно представляет собой "необработанное строковое регулярное выражение" и как вы можете его использовать?

Из документации python по регулярному выражению, касающейся '\' символа:


Решение заключается в использовании необработанной строковой нотации Python для шаблонов регулярных выражений; обратная косая черта не обрабатывается каким-либо особым образом в строковом литерале с префиксом 'r'. So r"\n" - это двухсимвольная строка, содержащая '\' и 'n', а "\n" - односимвольная строка, содержащая перевод строки. Обычно шаблоны выражаются в коде Python с использованием этой необработанной строковой нотации.


Что это за необработанная строковая нотация? Если вы используете формат необработанной строки, означает ли это, что "*" воспринимается как буквальный символ, а не как индикатор, равный нулю или более? Очевидно, что это не может быть правильным, иначе регулярное выражение полностью потеряло бы свою силу. Но тогда, если это необработанная строка, как она распознает символы перевода строки, если "\n" это буквально обратная косая черта и "n"?

Я не понимаю.

Редактировать для получения вознаграждения:

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

Переведено автоматически
Ответ 1

Ответ Зарконнена действительно отвечает на ваш вопрос, но не напрямую. Позвольте мне попытаться быть более прямым и посмотреть, смогу ли я получить награду от Зарконнена.

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

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

Во-первых, поймите, что строка представляет собой последовательность символов (т. Е. байтов или кодовых точек Юникода; различие здесь не имеет большого значения). Существует множество способов представления строки в исходном коде Python. Необработанная строка - это просто одно из этих представлений. Если два представления приводят к одинаковой последовательности символов, они приводят к эквивалентному поведению.

Представьте двухсимвольную строку, состоящую из символа обратной косой черты, за которым следует символ n. Если вы знаете, что значение символа для обратной косой черты равно 92, а для n равно 110, то это выражение генерирует нашу строку:

s = chr(92)+chr(110)
print len(s), s

2 \n

Обычная строковая нотация Python "\n" не генерирует эту строку. Вместо этого она генерирует односимвольную строку с символом перевода строки. В документах Python 2.4.1. Строковые литералы говорится: "Символ обратной косой черты (\) используется для экранирования символов, которые в противном случае имеют особое значение, таких как перевод строки, сама обратная косая черта или символ кавычки".

s = "\n"
print len(s), s

1
 

(Обратите внимание, что в этом примере не виден символ новой строки, но если вы посмотрите внимательно, то увидите пустую строку после "1".)

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

s = "\\n"
print len(s), s

2 \n

Что, если вы хотите представлять строки, в которых много символов обратной косой черты? Документы по Python 2.4.1. Строковые литералы продолжение: "Строковые литералы необязательно могут иметь префикс буквы 'r' или 'R'; такие строки называются необработанными строками и используют разные правила для интерпретации escape-последовательностей обратной косой черты". Вот наша двухсимвольная строка, использующая представление в виде необработанной строки:

s = r"\n"
print len(s), s

2 \n

Итак, у нас есть три разных строковых представления, все из которых содержат одну и ту же строку или последовательность символов:

print chr(92)+chr(110) == "\\n" == r"\n"
True

Теперь давайте обратимся к регулярным выражениям. В документах Python, 7.2. reОперации с регулярными выражениями говорится: "Регулярные выражения используют символ обратной косой черты ('\') для обозначения специальных форм или для разрешения использования специальных символов без использования их особого значения. Это противоречит использованию Python того же символа для тех же целей в строковых литералах ..."

Если вам нужен объект регулярного выражения Python, который соответствует символу перевода строки, то вам нужна двухсимвольная строка, состоящая из символа обратной косой черты, за которым следует символ n. Все следующие строки кода задаются prog для объекта регулярного выражения, который распознает символ перевода строки:

prog = re.compile(chr(92)+chr(110))
prog = re.compile("\\n")
prog = re.compile(r"\n")

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

Вопросы

Вопрос: а как насчет выраженияre.compile(r"\s\tWord")? A: Его легче понять, если отделить строку от компиляции регулярного выражения и понимать их по отдельности.

s = r"\s\tWord"
prog = re.compile(s)

Строка s содержит восемь символов: обратную косую черту, s, обратную косую черту, t, а затем четыре символа Word.

Вопрос: Что происходит с символами табуляции и пробела? A: На уровне языка Python строка s не содержит символов табуляции и пробела. Оно начинается с четырех символов: обратная косая черта, s, обратная косая черта, t . Система регулярных выражений, тем временем, обрабатывает эту строку как исходный код на языке регулярных выражений, где это означает "сопоставлять строку, состоящую из пробельного символа, символа табуляции и четырех символов " Word.

Вопрос: Как вы сопоставляете их, если они обрабатываются как обратная косая черта-s и обратная косая черта-t? A: Возможно, вопрос прояснится, если слова "вы" и "это" будут более конкретными: как система регулярных выражений соответствует выражениям обратная черта-s и обратная косая черта-t? Как 'любой символ пробела' и как 'символ табуляции'.

Вопрос: Или что, если у вас есть 3-символьная строка с обратной косой чертой-n-перевод строки? A: В языке Python 3-символьная строка с обратной косой чертой-n-перевод строки может быть представлена как обычная строка "\\n\n", или raw плюс обычная строка r"\n" "\n", или другими способами. Система регулярных выражений сопоставляет 3-символьную строку с обратной косой чертой-n-newline, когда находит любые два последовательных символа новой строки.

Примечание: Все примеры и ссылки на документы приведены на Python 2.7.

Обновление: включены пояснения из ответов @Vladislav Zorov и @m.buettner, а также из последующего вопроса @Aerovistae.

Ответ 2

В большинстве этих вопросов много слов, и, возможно, трудно найти ответ на ваш конкретный вопрос.

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

Если вы используете raw string и передаете шаблон типа r"\ t" анализатору регулярных выражений, Python не выполняет никакой интерпретации и создает буфер с двумя байтами в нем: '\' и 't'. (0x5c, 0x74).

Анализатор регулярных выражений знает, что делать с последовательностью '\ t' - он сопоставляет ее с табуляцией. Он также знает, что делать с символом 0x09 - который также соответствует табуляции. По большей части результаты будут неразличимы.

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

Ответ 3

Проблема с использованием обычной строки для записи регулярных выражений , содержащих \ заключается в том, что в конечном итоге вам приходится писать \\ для каждого \. Итак, строковые литералы "stuff\\things" и r"stuff\things" выдают одну и ту же строку. Это становится особенно полезным, если вы хотите написать регулярное выражение, которое соответствует обратным косым чертам.

Используя обычные строки, регулярное выражение, соответствующее строке, \ будет"\\\\"!

Почему? Потому что нам приходится экранировать \ дважды: один раз для синтаксиса регулярного выражения и один раз для синтаксиса строки.

Вы можете использовать тройные кавычки для перевода строк, например, так:

r'''stuff\
things'''

Обратите внимание, что обычно python обрабатывает \-newline как продолжение строки, но в необработанных строках это не так. Также обратите внимание, что обратная косая черта по-прежнему экранирует кавычки в необработанных строках, но остается сама по себе. Таким образом, необработанный строковый литерал r"\"" создает строку \". Это означает, что вы не можете заканчивать необработанный строковый литерал обратной косой чертой.

Смотрите раздел лексического анализа документации Python для получения дополнительной информации.

Ответ 4

Похоже, вы боретесь с идеей, что регулярное выражение является не частью Python, а другим языком программирования с собственным синтаксическим анализатором и компилятором. Необработанные строки помогают безопасно передавать "исходный код" регулярного выражения в анализатор регулярных выражений, который затем присваивает значение последовательностям символов, таким как \d, \w, \n и т.д...

Проблема существует из-за того, что Python и регулярные выражения используют \ в качестве управляющего символа, что, кстати, является совпадением - существуют языки с другими управляющими символами (например, "`n" для перевода строки, но даже там вам приходится использовать "\n" в регулярных выражениях). Преимущество в том, что вам не нужно различать raw и не-raw строки в этих языках, они не будут одновременно пытаться преобразовать текст и вырезать его, потому что они реагируют на разные escape-последовательности.

python regex