re.match、re.search、re.fullmatch 之间的差异

sam*_*249 8 python regex

正则表达式文档它说:

模式.匹配(...)

如果字符串开头的零个或多个字符与此正则表达式匹配

Pattern.fullmatch(...)

如果整个字符串匹配这个正则表达式

模式.search(...)

扫描字符串以查找此正则表达式产生匹配的第一个位置

鉴于上述情况,为什么有人不能总是习惯于search做所有事情?例如:

re.search(r'...'   # search
re.search(r'^...'  or re.search(r'\A...'   # match
re.search(r'^...$' or re.search(r'\A...\Z' # fullmatch
Run Code Online (Sandbox Code Playgroud)

matchfullmatch刚才的快捷方式(如果他们可以被称为是)的search方法?或者它们还有我忽略的其他用途吗?

ctw*_*els 11

给予信贷@ Ruzihm的答案,因为我的答案的部分从他的派生。


快速概览

差异的快速概述:

  • re.match 锚定在开始 ^pattern
    • 确保字符串以模式开头
  • re.fullmatch 锚定在模式的开始和结束 ^pattern$
    • 确保完整的字符串与模式匹配(对于此处描述的交替尤其有用)
  • re.search 没有锚定 pattern
    • 确保字符串包含模式

可以在此处找到对re.matchvs 的更深入比较re.search


举例:

aa            # string
a|aa          # regex

re.match:     a
re.search:    a
re.fullmatch: aa
Run Code Online (Sandbox Code Playgroud)

 

ab            # string
^a            # regex

re.match:     a
re.search:    a
re.fullmatch: # None (no match)
Run Code Online (Sandbox Code Playgroud)

那么,关于\A\Z锚?

文件规定如下:

Python 提供了两种不同的基于正则表达式的原始操作:re.match()只在字符串的开头re.search()检查匹配,而在字符串的任何地方检查匹配(这是 Perl 默认所做的)。

在该Pattern.fullmatch部分中它说:

如果整个字符串与此正则表达式匹配,则返回相应的匹配对象。

而且,正如 Ruzihm 在他的回答中最初发现和引用的那样:

但是请注意,在 MULTILINE 模式下,match() 仅匹配字符串的开头,而使用带有以 开头的正则表达式的 search()^将匹配每行的开头。

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<re.Match object; span=(4, 5), match='X'>
Run Code Online (Sandbox Code Playgroud)
\A^A
B
X$\Z

# re.match('X', s)                  no match
# re.search('^X', s)                no match

# ------------------------------------------
# and the string above when re.MULTILINE is enabled effectively becomes

\A^A$
^B$
^C$\Z

# re.match('X', s, re.MULTILINE)    no match
# re.search('^X', s, re.MULTILINE)  match X
Run Code Online (Sandbox Code Playgroud)

至于\A\Z,既不执行不同的re.MULTILINE,因为\A\Z有效的仅仅是^$整个的字符串中。

因此,使用\A\Z使用这三种方法中的任何一种都会产生相同的结果。


答案(线锚与字符串锚)

这告诉我的是,re.match和分别re.fullmatch不匹配线锚点 ^$,而是分别匹配字符串锚点 \A\Z