在字符串前面加个前缀r ,表示一个 raw 字符串,里面的字符就不需要转义.
s="(((("
pat1 = "^({3,}$"
re.match(pat1,s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.9/re.py", line 191, in match
return _compile(pattern, flags).match(string)
File "/usr/lib/python3.9/re.py", line 304, in _compile
p = sre_compile.compile(pattern, flags)
File "/usr/lib/python3.9/sre_compile.py", line 764, in compile
p = sre_parse.parse(p, flags)
File "/usr/lib/python3.9/sre_parse.py", line 948, in parse
p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)
File "/usr/lib/python3.9/sre_parse.py", line 443, in _parse_sub
itemsappend(_parse(source, state, verbose, nested + 1,
File "/usr/lib/python3.9/sre_parse.py", line 834, in _parse
p = _parse_sub(source, state, sub_verbose, nested + 1)
File "/usr/lib/python3.9/sre_parse.py", line 443, in _parse_sub
itemsappend(_parse(source, state, verbose, nested + 1,
File "/usr/lib/python3.9/sre_parse.py", line 668, in _parse
raise source.error("nothing to repeat",
re.error: nothing to repeat at position 2
没有匹配成功。
引入转义
pat2 = "^\({3,}$"
re.match(pat2,s)
<re.Match object; span=(0, 4), match='(((('>
引入raw字符串
pat3 = r"^\({3,}$"
re.match(pat3,s)
<re.Match object; span=(0, 4), match='(((('>
为何pat3可以匹配成功呢?
你打印一下pat2和pat3就知道了。
'^\\({3,}'
,'^\({3,}'
和r'^\({3,}'
是等价的。举个例子,\n
是一个整体,表示换行。你要抑制\n
转义,要么就是在\n
前面再加一个\
,使之变为\\n
,要么就是使用raw字符串r'\n'
。但括号
()
在re的模式字符串中有特殊含义,表示匹配组,但也仅仅只在模式字符串中才有特殊含义。同理,(
只有一个字符,如果你要抑制(
的转义,你要么就\(
,要么就r'('
。但(
仅在re的模式字符串中才有特殊含义,也仅仅是当(
用作re的模式字符串的时候你才需要抑制转义,避免(
被作为匹配组来解析。所以如果只是简单打印\(
和r'('
,并不会像打印'\nhaha'
、r'\nhaha'
和'\\nhaha'
看起来这么明显,因为作为普通字符串时,(
是没有特殊含义的。