Обратные косые черты в регулярных выражениях Python [дубликат]

этот вопрос уже есть ответ здесь:

меня смущает с обратной косой чертой в регулярных выражениях. В регулярном выражении a имеет особое значение, например d означает десятичную цифру. Если вы добавляете обратную косую черту перед обратной косой чертой, это особое значение теряется. В regex-howto можно прочесть:

возможно, самый важный метасимвол-это обратная косая черта,. Как и в строковых литералах Python, обратная косая черта может сопровождаться различными символами для сигнала различных специальных последовательностей. Он также используется для побег всех метасимволов, так что вы все еще можете сопоставить их в шаблонах; например, если вам нужно соответствовать [ или , вы можете предшествовать им с обратной косой чертой, чтобы удалить их особый смысл:[ или .

так print(re.search('d', 'd')) дает None, потому что d соответствует любой десятичной цифре, но нет в d.

я теперь ожидал бы print(re.search('d', 'd')) в матче d но ответ все еще None.

только print(re.search('\d', 'd')) дает вывод <_sre.SRE_Match object; span=(0, 2), match='d'>.

у кого-нибудь есть объяснение?

3 ответов


путаница связана с тем, что символ обратной косой черты \ используется как побег на двух разных уровнях. Во-первых, интерпретатор Python сам выполняет подстановки для \ до re модуль не видит строки. Например, \n превращается в символ новой строки, \t преобразуется в символ табуляции и т. д. Чтобы получить фактический \ персонаж, вы можете избежать его, так что \ один \ символ. Если символ после \ не распознан escape-символ, тогда \ обрабатывается как любой другой символ и передается, но я не рекомендую в зависимости от этого. Вместо этого, всегда избежать вашего \ символы путем их удвоения, т. е. \.

если вы хотите увидеть, как Python расширяет эскейпы строк, просто распечатайте строку. Например:

s = 'a\b\tc'
print s

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

как только вы узнаете, как кодируется ваша строка, вы можете подумать о том, что re модуль сделает с ним. Например, если вы хотите избежать \ в строке вы передаете в re модуль, вам нужно будет пройти \ to re, что означает, что вы должны использовать \\ в вашей цитируемой строке Python. Строка Python в конечном итоге будет иметь \ и re модуль будет рассматривать это как один литерал \ символ.

альтернативный способ включения \ символы в строках Python должны использовать необработанные строки, например r'a\b' эквивалентно "a\b".


символ r перед регулярным выражением сообщает в вызове search () указывает, что регулярное выражение является необработанной строкой. Это позволяет использовать обратные косые черты в регулярном выражении как обычные символы, а не в escape-последовательности символов. Позвольте мне объяснить ...

прежде чем метод поиска модуля re обрабатывает переданные ему строки, интерпретатор Python выполняет начальный проход по строке. Если в строке присутствуют обратные косые черты, интерпретатор Python должен решить, является ли каждый из них частью escape-последовательности Python (например, \n или \t) или нет.

Примечание: На данный момент Python не волнует, является ли " \ " метасимволом регулярного выражения.

если за " \ " следует распознанный символ побега Python (t,n и т. д.), затем обратная косая черта и escape-символ заменяются фактическим Unicode или 8-битным символом. Например, "\t " будет заменен символом ASCII для tab. Иначе он передается и интерпретируется как символ"\".

учитывать следующее.

>>> s = '\t'
>>> print ("[" + s  + "]")
>>> [       ]           // an actual tab character after preprocessing

>>> s = '\d'
>>> print ("[" + s  + "]")
>>> [\d]                // '\d' after preprocessing

иногда мы хотим включить в строку последовательность символов, которая включает"\", не интерпретируемую Python как escape-последовательность. Для этого мы избегаем " \ "с"\". Теперь, когда Python видит"\", он заменяет две обратные косые черты одним символом"\".

>>> s = '\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing

после того, как интерпретатор Python передаст обе строки, они будут переданы метод поиска модуля re. Метод поиска анализирует строку регулярного выражения для идентификации метасимволов регулярного выражения.

теперь " \ " также является специальным метасимволом регулярного выражения и интерпретируется как один, если он не экранируется во время выполнения метода re search ().

рассмотрим следующий вызов.

>>> match = re.search('a\t','a\t')        //Match is None

здесь, матч нет. Почему? Давайте посмотрим на строки после того, как интерпретатор Python делает его пройти.

String 1: 'a\t'
String 2: 'a\t' 

так почему совпадение равно None? Когда search () интерпретирует строку 1, поскольку это регулярное выражение, обратная косая черта интерпретируется как мета-символ, а не обычный символ. Однако обратная косая черта в строке 2 не находится в регулярном выражении и уже обработана интерпретатором Python, поэтому она интерпретируется как обычный символ.

таким образом, метод search() ищет "escape-t" в строке "A\t", которые не являются спичка.

чтобы исправить это, мы можем сказать методу search (), чтобы не интерпретировать " \ " как мета-символ. Мы можем сделать это, сбежав от него.

рассмотрим следующий вызов.

>>> match = re.search('a\\t','a\t')          // Match contains 'a\t'

опять же, давайте посмотрим на строки после того, как интерпретатор Python сделала его пройти.

String 1: 'a\t'
String 2: 'a\t'

теперь, когда метод search() обрабатывает регулярное выражение, он видит, что вторая обратная косая черта экранируется первой и не должна рассматриваться как мета-символ. Он поэтому интерпретирует строку как "A\t", которая соответствует строке 2.

альтернативный способ заставить search () рассматривать " \ " как символ-поместить r перед регулярным выражением. Это говорит интерпретатору Python не предварительно обрабатывать строку.

рассмотреть этот вопрос.

>>> match = re.search(r'a\t','a\t')           // match contains 'a\t'

здесь интерпретатор Python не изменяет первую строку, но обрабатывает вторую строку. Строки, переданные в search ():

String 1: 'a\t'
String 2: 'a\t'

как и в предыдущем например, поиск интерпретирует " \ "как один символ"\", а не мета-символ, таким образом, соответствует строке 2.


собственный синтаксический анализ строки Python (частично) встает на вашем пути.

если вы хотите увидеть, что re видит, типа

print '\d'
print '\d'
print '\\d'

в командной строке Python. Вы видите, что \d и \d и в результате \d последняя заботятся интерпретатором Python строкой.

если вы хотите избежать каких-либо проблем с ними, используйте необработанные строки, как предложено документация модуля re: r'\d' в результате \d увиденный RE модуль.