重新匹配,重新搜索,重新匹配之间的区别

时间:2019-11-08 21:31:32

标签: python regex

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方法的快捷方式(如果可以被称为)吗?还是他们还有我忽略的其他用途?

2 个答案:

答案 0 :(得分:2)

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

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

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

  

请注意,在多行模式下,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()'^...$'在每行的开头和结尾匹配。


答案 1 :(得分:1)

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


快速概述

差异的简要介绍:

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

herere.matchre.search进行了更深入的比较


带有示例:

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实际上是唯一的^和{整个字符串中的{1}}。

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


答案(线锚与弦锚)

这告诉我\Zre.match分别与行锚 re.fullmatch^不匹配,但它们却匹配分别匹配字符串锚点 $\A

相关问题