为什么Python正则表达式字符串有时可以不使用原始字符串?

Fiv*_*ver 4 python regex string

Python建议在re模块中定义正则表达式时使用原始字符串.从Python文档:

正则表达式使用反斜杠字符('\')来表示特殊形式或允许使用特殊字符而不调用它们的特殊含义.这与Python在字符串文字中用于相同目的的相同字符的使用相冲突; 例如,要匹配文字反斜杠,可能必须将'\\'写为模式字符串,因为正则表达式必须为\,并且每个反斜杠必须在常规Python字符串文字中表示为\.

但是,在许多情况下,这不是必需的,无论是否使用原始字符串,都会得到相同的结果:

$ ipython

In [1]: import re

In [2]: m = re.search("\s(\d)\s", "a 3 c")

In [3]: m.groups()
Out[3]: ('3',)

In [4]: m = re.search(r"\s(\d)\s", "a 3 c")

In [5]: m.groups()
Out[5]: ('3',)
Run Code Online (Sandbox Code Playgroud)

然而,在某些情况下情况并非如此:

In [6]: m = re.search("\s(.)\1\s", "a 33 c")

In [7]: m.groups()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-12-84a8d9c174e2> in <module>()
----> 1 m.groups()

AttributeError: 'NoneType' object has no attribute 'groups'

In [8]: m = re.search(r"\s(.)\1\s", "a 33 c")

In [9]: m.groups()
Out[9]: ('3',)
Run Code Online (Sandbox Code Playgroud)

并且在不使用原始字符串时必须转义特殊字符:

In [10]: m = re.search("\\s(.)\\1\\s", "a 33 c")

In [11]: m.groups()
Out[11]: ('3',)
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么非转义的,非原始的正则表达式字符串对特殊字符起作用(如上面的命令[2])?

小智 8

上面的例子,因为工作\s\d不逃避蟒蛇序列.根据文件:

与标准C不同,所有未识别的转义序列都保留在字符串中不变,即反斜杠保留在字符串中. 

但最好只使用原始字符串而不担心python转义是什么或不是什么,或者担心如果你改变正则表达式后来改变它.


iCo*_*dez 6

这是因为\s并且\d不是转义序列:

>>> print('\s')
\s
>>> print('\d')
\d
>>>
Run Code Online (Sandbox Code Playgroud)

因此,他们被视为\s\d. \1然而一个转义序列:

>>> print('\1')
?
>>>
Run Code Online (Sandbox Code Playgroud)

这意味着它被解释为?而不是\1.

有关Python的转义序列的完整列表,请参阅文档中的String和Bytes文字.