re.match,re.search,re.fullmatch之间的区别[重复]

Posted

技术标签:

【中文标题】re.match,re.search,re.fullmatch之间的区别[重复]【英文标题】:Differences between re.match, re.search, re.fullmatch [duplicate] 【发布时间】:2020-03-05 12:39:16 【问题描述】:

regex docs 上面写着:

Pattern.match(...)

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

Pattern.fullmatch(...)

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

Pattern.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

matchfullmatch 只是 search 方法的快捷方式(如果可以这样称呼的话)吗?还是我忽略了它们的其他用途?

【问题讨论】:

第一个区别:re.matchall 不存在。 @CasimiretHippolyte 打错字了。他们的意思是fullmatch 是的,它们只是捷径。 最重要的是不同的方法名称是有意义的,并告知您的意图。 @Code-Apprentice 我会投票重新提出这个问题,我认为这与该链接中的答案有点不同 【参考方案1】:

感谢@Ruzihm's answer,因为我的部分答案来自他。


快速概览

差异的简要说明:

re.match 锚定在开头 ^pattern 确保字符串以模式开头 re.fullmatch 锚定在模式 ^pattern$ 的开头和结尾 确保完整的字符串与模式匹配(在here 所述的交替中特别有用) re.search 未锚定 pattern 确保字符串包含模式

re.matchre.search 的更深入比较可以找到here


举例:

aa            # string
a|aa          # regex

re.match:     a
re.search:    a
re.fullmatch: aa

 

ab            # string
^a            # regex

re.match:     a
re.search:    a
re.fullmatch: # None (no match)

那么\A\Z 锚点呢?

documentation 声明如下:

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

关于\A\Zre.MULTILINE 的表现都不同,因为\A\Z 实际上是整个字符串中唯一的^$

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


答案(线锚与弦锚)

这告诉我的是 re.matchre.fullmatch 不匹配 线锚 ^$ 分别匹配 字符串锚 em> 分别是\A\Z

【讨论】:

再次感谢您的详细回答。但是使用 \A 和 \Z 怎么样,这会使它们相同吗?【参考方案2】:

是的,它们可以被视为以\A 开头或以\A 开头并以\Z 结尾的re.search 调用的快捷方式。

因为\A 总是指定字符串的开头,所以使用re.search 和前置\A 似乎等同于re.match,即使在MULTILINE 模式下也是如此。一些例子:

import re
haystack = "A\nB\nZ"

matchstring = 'A'
x=re.match(matchstring, haystack) # Match
y=re.search('\A' + matchstring, haystack) # Match

matchstring = 'A$\nB'
x=re.match(matchstring, haystack, re.MULTILINE) # Match
y=re.search('\A' + matchstring, haystack, re.MULTILINE) # Match

matchstring = 'A\n$B'
x=re.match(matchstring, haystack, re.MULTILINE) # No match
y=re.search('\A' + matchstring, haystack, re.MULTILINE) # No match

将搜索字符串置于\A\Z 之间以等同于fullmatch 也是如此。


不包括\A/\Z

不,他们对待 MULTILINE 的方式不同。来自the documentation:

但请注意,在 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'>

同样,在 MULTILINE 模式下,fullmatch() 匹配字符串的开头和结尾,search()'^...$' 匹配每行的开头和结尾。


【讨论】:

@Ruzihm,那么使用 \A 和 \Z 而不是 ^ 和 $ 怎么样?这会使它们始终等效吗? @samuelbrody1249 好点。我编辑了我的答案来解决这个问题。即使在分析他们的运行时(未显示在答案中),我也找不到差异

以上是关于re.match,re.search,re.fullmatch之间的区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

re.match与re.search的区别

Python中re.match与re.search的使用方法详解

python 中 re.match 和 re.search用法

Python3中正则模块re.compilere.match及re.search函数用法详解

Python3中正则模块re.compilere.match及re.search

正则表达式中pattern.match(),re.match(),pattern.search(),re.search()方法的使用和区别