python的正则表达式与转义字符?

在字符串前面加个前缀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可以匹配成功呢?

阅读 2.1k
2 个回答

你打印一下pat2和pat3就知道了。'^\\({3,}''^\({3,}'r'^\({3,}'是等价的。举个例子,\n是一个整体,表示换行。你要抑制\n转义,要么就是在\n前面再加一个\,使之变为\\n,要么就是使用raw字符串r'\n'

In [1]: print('\nhaha')

haha

In [2]: print(r'\nhaha')
\nhaha

In [3]: print('\\nhaha')
\nhaha

但括号()在re的模式字符串中有特殊含义,表示匹配组,但也仅仅只在模式字符串中才有特殊含义。同理,(只有一个字符,如果你要抑制(的转义,你要么就\(,要么就r'('。但(仅在re的模式字符串中才有特殊含义,也仅仅是当(用作re的模式字符串的时候你才需要抑制转义,避免(被作为匹配组来解析。所以如果只是简单打印\(r'(',并不会像打印'\nhaha'r'\nhaha''\\nhaha'看起来这么明显,因为作为普通字符串时,(是没有特殊含义的。

In [4]: print('^\\({3,}')
^\({3,}

In [5]: print('^\({3,}')
^\({3,}

In [6]: print(r'^\({3,}')
^\({3,}

In [7]: print(r'^({3,}')
^({3,}
新手上路,请多包涵

在 Python 中,字符串前面加上 r 或 R 表示这个字符串为一个 raw 字符串。在 raw 字符串中,所有的字符都会原样输出,即使它们在非 raw 字符串中是特殊字符。在上面的例子中,在普通字符串中,( 和 ) 都会被当作特殊字符处理,但是在 raw 字符串中,它们变成了普通字符,就可以匹配成功了。

在使用正则表达式的时候,如果正则表达式中包含了许多反斜杠和特殊字符,使用 raw 字符串可以让代码看起来更加清晰,更容易理解。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进