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
match
和 fullmatch
只是 search
方法的快捷方式(如果可以这样称呼的话)吗?还是我忽略了它们的其他用途?
【问题讨论】:
第一个区别:re.matchall
不存在。
@CasimiretHippolyte 打错字了。他们的意思是fullmatch
是的,它们只是捷径。
最重要的是不同的方法名称是有意义的,并告知您的意图。
@Code-Apprentice 我会投票重新提出这个问题,我认为这与该链接中的答案有点不同
【参考方案1】:
感谢@Ruzihm's answer,因为我的部分答案来自他。
快速概览
差异的简要说明:
re.match
锚定在开头 ^pattern
确保字符串以模式开头
re.fullmatch
锚定在模式 ^pattern$
的开头和结尾
确保完整的字符串与模式匹配(在here 所述的交替中特别有用)
re.search
未锚定 pattern
确保字符串包含模式
re.match
与 re.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
和\Z
,re.MULTILINE
的表现都不同,因为\A
和\Z
实际上是整个字符串中唯一的^
和$
。
因此,将\A
和\Z
与这三种方法中的任何一种一起使用都会产生相同的结果。
答案(线锚与弦锚)
这告诉我的是 re.match
和 re.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之间的区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章
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()方法的使用和区别