Python正则表达式-R前缀


87

r没有使用前缀时,谁能解释下面的示例1为何起作用?我认为r无论何时使用转义序列都必须使用前缀。示例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

Answers:


86

因为\仅当它们是有效的转义序列时才开始转义序列。

>>> '\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”的前缀是目前,转义序列在字符串解释根据类似于由标准C的使用的规则识别转义序列是:

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

作为次要解决方案,'\s'(如r'\s''\\s'由于'\s'不是公认的转义序列,因此也表示为。
马苏德·卡里

@MassoodKhaari我发誓我写这个答案的时候输出是正确的。
EstebanKüber'18

1
8年无疑证明了python行为的神奇变化。:D
Massood Khaari '18

34

“ r”表示以下是“原始字符串”,即。反斜杠字符按字面意义处理,而不表示对以下字符进行特殊处理。

http://docs.python.org/reference/lexical_analysis.html#literals

所以'\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'。我的偏好是露骨,将所有反斜杠加倍。


5

并非所有涉及反斜杠的序列都是转义序列。\t并且\f是,例如,但\s并非如此。在非原始字符串文字中,任何\不属于转义序列的内容都被视为另一个\

>>> "\s"
'\\s'
>>> "\t"
'\t'

\b 一个转义序列,但是,示例3失败了。(是的,有些人认为这种行为很不幸。)


究竟。虽然,@ JT,我建议使用'\\ s'或r'\ s',否则您可能会无意中遇到了一些您本不想这样做的转义序列。
布莱尔·康拉德

确实:当您希望字符串包含反斜杠时,请始终使用原始字符串文字(而不是实际需要转义序列。)
Thomas Wouters 2010年

@Thomas:r当某些序列出现在字符串的末尾时,它们仍会转义:r"\"是无效的,您必须这样做"\\"。如果这样做r"\\",则会得到\\ 打印的("\\\\"字符串)。小心点。
EstebanKüber'10

是的,原始字符串文字不能以单个\结束。
Thomas Wouters'2010-2-11

@ Blair / Thomas:谢谢-这是我遵循的一般规则,首先让我感到困惑!...一切都清楚了,谢谢大家。尽管遵循此规则...从纯文本文件中读取模式时,该模式如何作为原始文字字符串传递?
JT。

0

试试看:

a = '\''
'
a = r'\''
\'
a = "\'"
'
a = r"\'"
\'

0

检查以下示例:

print r"123\n123" 
#outputs>>>
123\n123


print "123\n123"
#outputs>>>
123
123
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.