Регулярное выражение Python - r префикс
Может кто-нибудь объяснить, почему пример 1 ниже работает, когда r
Приставка не используется? Я думал r
префикс должен использоваться всякий раз, когда используются escape-последовательности. Пример 2 и пример 3 демонстрируют это.
# example 1
import re
print (re.sub('\s+', ' ', 'hello there there'))
# prints 'hello there there' - not expected as r prefix is not used
# example 2
import re
print (re.sub(r'(\b\w+)(\s+\1\b)+', r'\1', 'hello there there'))
# prints 'hello there' - as expected as r prefix is used
# example 3
import re
print (re.sub('(\b\w+)(\s+\1\b)+', '\1', 'hello there there'))
# prints 'hello there there' - as expected as r prefix is not used
3 ответа
Так как \
начинайте escape-последовательности, только когда они являются действительными escape-последовательностями.
>>> '\n'
'\n'
>>> r'\n'
'\\n'
>>> print '\n'
>>> print r'\n'
\n
>>> '\s'
'\\s'
>>> r'\s'
'\\s'
>>> print '\s'
\s
>>> print r'\s'
\s
Если нет префикса 'r' или 'R', escape-последовательности в строках интерпретируются в соответствии с правилами, аналогичными тем, которые используются стандартом C. Распознаваемыми escape-последовательностями являются:
Escape Sequence Meaning Notes \newline Ignored \\ Backslash (\) \' Single quote (') \" Double quote (") \a ASCII Bell (BEL) \b ASCII Backspace (BS) \f ASCII Formfeed (FF) \n ASCII Linefeed (LF) \N{name} Character named name in the Unicode database (Unicode only) \r ASCII Carriage Return (CR) \t ASCII Horizontal Tab (TAB) \uxxxx Character with 16-bit hex value xxxx (Unicode only) \Uxxxxxxxx Character with 32-bit hex value xxxxxxxx (Unicode only) \v ASCII Vertical Tab (VT) \ooo Character with octal value ooo \xhh Character with hex value hh
Никогда не полагайтесь на необработанные строки для литералов пути, так как необработанные строки имеют довольно своеобразную внутреннюю работу, которая, как известно, укусила людей в задницу:
При наличии префикса "r" или "R" символ, следующий за обратной косой чертой, включается в строку без изменений, и все обратные косые черты остаются в строке. Например, строковый литерал
r"\n"
состоит из двух символов: обратной косой черты и строчной буквы "n". Строковые кавычки можно экранировать с помощью обратной косой черты, но обратная косая черта остается в строке; например,r"\""
является допустимым строковым литералом, состоящим из двух символов: обратной косой черты и двойной кавычки;r"\"
не является допустимым строковым литералом (даже необработанная строка не может заканчиваться нечетным числом обратных косых черт). В частности, необработанная строка не может заканчиваться одним обратным слешем (так как обратный слеш будет экранировать следующий символ кавычки). Также обратите внимание, что одиночная обратная косая черта, за которой следует новая строка, интерпретируется как эти два символа как часть строки, а не как продолжение строки.
Чтобы лучше проиллюстрировать этот последний пункт:
>>> r'\'
SyntaxError: EOL while scanning string literal
>>> r'\''
"\\'"
>>> '\'
SyntaxError: EOL while scanning string literal
>>> '\''
"'"
>>>
>>> r'\\'
'\\\\'
>>> '\\'
'\\'
>>> print r'\\'
\\
>>> print r'\'
SyntaxError: EOL while scanning string literal
>>> print '\\'
\
"r" означает, что следующее является "необработанной строкой", т.е. Символы обратной косой черты обрабатываются буквально, а не означают специальную обработку следующего символа.
http://docs.python.org/reference/lexical_analysis.html
так '\n'
это одна новая строка
а также r'\n'
это два символа - обратный слеш и буква 'n'
другой способ написать это будет '\\n'
потому что первый обратный слеш избегает второго
эквивалентный способ написания этого
print (re.sub(r'(\b\w+)(\s+\1\b)+', r'\1', 'hello there there'))
является
print (re.sub('(\\b\\w+)(\\s+\\1\\b)+', '\\1', 'hello there there'))
Из-за того, как Python обрабатывает символы, которые не являются допустимыми управляющими символами, не все эти двойные обратные слэши необходимы - например, '\s'=='\\s'
Однако то же самое не относится к '\b'
а также '\\b'
, Я предпочитаю быть явным и удваивать все обратные слеши.
Не все последовательности, включающие обратную косую черту, являются escape-последовательностями. \t
а также \f
например, но \s
не является. В неочищенном строковом литерале любой \
которая не является частью escape-последовательности, рассматривается как просто еще одна \
:
>>> "\s"
'\\s'
>>> "\t"
'\t'
\b
является escape-последовательностью, однако пример 3 завершается неудачно. (И да, некоторые люди считают такое поведение довольно неудачным.)
Посмотрите пример ниже:
print r"123\n123"
#outputs>>>
123\n123
print "123\n123"
#outputs>>>
123
123