Подтвердить что ты не робот

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

Из документации python в regex относительно символа '\':

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

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

Я не следую.

Изменить для баунти:

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

4b9b3361

Ответ 1

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

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

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

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

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

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

2 \n

Стандартная нотация строки "\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 - Операции с регулярным выражением говорит: "Регулярные выражения используют символ обратной косой черты ('\'), чтобы указать специальные формы или разрешить использование специальных символов, не ссылаясь на их особое значение. Это сталкивается с использованием Pythons тот же символ для той же цели в строковых литералах..."

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

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

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

Вопросы

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

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

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

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

Q: Как вы соответствуете тем, если они обрабатываются как обратная связь и обратная коса? A. Может быть, вопрос более ясен, если слова "ты" и "это" сделаны более конкретными: как система регулярного выражения соответствует выражениям обратного слэша и обратной косой черты? Как "любой символ пробела" и как "символ табуляции".

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

N.B. Все примеры и ссылки на документы относятся к Python 2.7.

Обновление. Включены пояснения из ответов @Владислава Зорова и @м.бутнера и последующего вопроса о @Aerovistae.

Ответ 2

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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

r'''stuff\
things'''

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

Подробнее см. раздел лексического анализа документации Python.

Ответ 5

В соответствующем разделе руководства Python ( "Строковые и байтовые литералы" ) есть четкое объяснение исходных строковых литералов:

Оба строковых и байтовых литерала могут быть необязательно префиксны буква "r" или "R"; такие строки называются сырыми струнами и обрабатывают обратную косую черту как буквенные символы. В результате, в строковых литералах, Выражения `\ U 'и'\u 'в необработанных строках не обрабатываются специально. Данный что Python 2.xs нечетные символы Unicode ведут себя иначе, чем Python 3.xs синтаксис "ur" не поддерживается.

Новое в версии 3.3: префикс "rb" для литералов необработанных байтов добавлен как синоним "br".

Новое в версии 3.3: Поддержка унаследованного литерала unicode (u'value ') был вновь введен для упрощения обслуживания двойного Python 2.x и 3.x. См. PEP 414 для получения дополнительной информации.

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

Если нет префикса 'r' или 'R', escape-последовательности в строках интерпретируются в соответствии с правилами, аналогичными правилам, применяемым Стандартом C. Признанные escape-последовательности:

Последовательность воспроизведения Примечания Примечания

\newline Обратная косая черта и новая строка игнорируются
\ Backslash()
\ 'Single quote (')
\ "Двойная цитата (" )
\ a ASCII Bell (BEL)
\ b ASCII Backspace (BS)
\ f ASCII Formfeed (FF)
\n Линейная передача ASCII (LF)
Возвращение каретки ASCII (CR)
\ t ASCII Горизонтальная вкладка (TAB) \ v Вертикальная вкладка ASCII (VT)
\ ooo Символ с восьмеричным значением ooo (1,3)
\ xhh Символ с шестнадцатеричным значением hh (2,3)

Эквивалентные последовательности, только распознаваемые в строковых литералах, следующие:

Escape Sequence Значение Примечания \N {имя} Именованное имя персонажа в База данных Unicode (4)\uxxxx Символ с 16-разрядным шестнадцатеричным значением xxxx (5) \ Uxxxxxxxx Символ с 32-разрядным шестнадцатеричным значением xxxxxxxx (6)

Примечания:

  • Как и в стандарте C, принимаются до трех восьмеричных цифр.

  • В отличие от стандартного C требуется ровно две шестнадцатеричные цифры.

  • В байтовом литерале шестнадцатеричные и восьмеричные escape-последовательности обозначают байты с заданным значением. В строковом литерале эти escape-последовательности обозначают Unicode-символ с заданным значением.

  • Изменено в версии 3.3: Добавлена ​​поддержка псевдонимов имен [1].

  • Отдельные кодовые единицы, которые составляют части суррогатной пары, могут быть закодированы с использованием этой escape-последовательности. Точно четыре шестнадцатеричных цифры: требуется.

  • Любой символ Юникода может быть закодирован таким образом, но символы вне базовой многоязычной плоскости (BMP) будут закодированы с использованием суррогатная пара, если Python скомпилирован для использования 16-битных кодовых блоков ( по умолчанию). Требуется восемь шестнадцатеричных цифр.

В отличие от стандарта C все непризнанные escape-последовательности остаются в строка неизменной, то есть обратная косая черта остается в строке. (Эта поведение полезно при отладке: если escape-последовательность ошибочна, полученный результат легче распознается как сломанный.) Это также важно отметить, что escape-последовательности, только распознанные в строке литералы попадают в категорию непризнанных побегов для байтов литералы.

Даже в исходной строке строковые кавычки могут быть экранированы с помощью обратного слэша, но обратная косая черта остается в строке; например, r "\" "является действительным строковый литерал, состоящий из двух символов: обратная косая черта и двойная цитаты; r "\" не является допустимым строковым литералом (даже необработанная строка не может конец в нечетном числе обратных косых черт). В частности, необработанная строка не может закончиться одной обратной косой чертой (поскольку обратная косая черта после символа цитаты). Обратите также внимание на то, что после обратной обратной косой черты по новой строке интерпретируется как эти два символа как часть string, а не как продолжение строки.