【问题标题】:Looking for difference between re.match(pattern, ...) and re.search(r'\A' + pattern, ...)寻找 re.match(pattern, ...) 和 re.search(r'\A' + pattern, ...) 之间的区别
【发布时间】:2013-09-01 21:05:24
【问题描述】:

(下面的所有代码都假定import re 已经被评估的上下文。)

关于re.matchre.search 之间差异的documentation 专门比较了运行re.match(pattern, ...) 和运行re.search('^' + pattern, ...)。在我看来,这有点像稻草人,因为真正的测试是将re.match(pattern, ...)re.search(r'\A' + pattern, ...) 进行比较1

更具体地说,我无法轻易想出patternstring 的组合,其结果是

m = re.match(pattern, string)

将与结果不同

m = re.search(r'\A' + pattern, string)

(请注意,如果pattern 中的原始模式恰好是unicode 类型,那么r'\A' + pattern 中修改后的模式也是如此,非常方便。)

让我强调一下,我对性能、便利性等方面可能存在的差异感兴趣。目前我只对最终结果的差异感兴趣(即最终结果的差异) m) 的值。

为了更笼统地表达这个问题,我正在寻找patternflagsstringkwargs 的组合,这样m 的最终值在

r0 = re.compile(pattern, flags=flags)
m = r0.match(string, **kwargs)

m的最终值不同

r1 = re.compile(r'\A' + pattern, flags=flags)
m = r1.search(string, **kwargs)

可能不存在输入 patternflagsstringkwargs 的此类组合,但要能够满怀信心地做出此断言,需要深入了解Python 正则表达式引擎的内部结构。 IOW,与“肯定答案”(即仅由描述的输入的一个组合组成的答案)相反,对这个问题的“否定答案”相当于一个相当权威的陈述,因此它要令人信服,需要在更深层次上提出案例(而不是“肯定”答案)。

总结一下:我正在寻找两种可能的答案之一:

  1. patternflagsstringkwargs 的组合将在上面给出的最后两种情况下产生不同的 m 值;
  2. 基于 Python 正则表达式内部知识的权威“否定”答案(即不存在这样的输入组合)。

1\A 将匹配锚定到字符串的开头,无论匹配是否为多行。顺便说一句,用于字符串结尾匹配的\A 的对应项是\Z。很烦人的是,Python 的 \Z 对应于 Perl 的 \z,而 对应于 Perl 的 \Z。当我写这篇文章的早期版本时,这让我大吃一惊。 (顺便说一句,在 Python 正则表达式中 \z 没有特殊含义;它只匹配 z。)感谢 John Y 发现我的错误。

【问题讨论】:

  • 你的助记词错了。根据您链接到的文档,\A 的对应项是\Z。在这两种情况下都是大写字母。可以肯定的是,我在交互式 Python 会话中对其进行了测试,并且行为与文档相匹配。 \z(小写)的行为与 z 相同(即反斜杠没有区别,这对于 Python 中没有任何特殊正则表达式含义的字符来说是正常的)。
  • 感谢您发现我的错误!我现在已经修好了。我记错了 Perl 的特殊正则表达式序列,就好像它们是 Python 的一样。我真正需要的是保持这两个笔直的助记符!

标签: python regex


【解决方案1】:

这里可能有一些我看不到的东西,但我认为区别很明显。

  1. re.match() 返回成功匹配仅当您要查找的模式位于字符串的开头,并且从文档中的示例看起来 @ 987654322@ 使用 \A 将匹配锚定到字符串的开头,不是多行模式下的行首。

  2. re.search() 返回一个成功的匹配不管只要有匹配的目标字符串内的模式,当然只要你不锚定模式故意的。

现在回答您的主要问题,re.match(pattern, …)re.search(r'\A' + pattern, …) 之间有什么区别?

好吧,没有任何区别,这只是一种方便的方法,所以你不必每次都输入r'\A' + pattern,我猜如果你想锚定你的比赛,我想这种情况经常发生。

只需查看您发布的比较链接中的最后一个示例,您就可以更加确定 re.match() 在内部使用 \A

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<_sre.SRE_Match object at ...>

【讨论】:

  • 我想你误解了我的问题;我在我的帖子中添加了措辞(主要是在最后),希望能减少这种误解。
  • @kjo 我想我理解你提出的两个问题中的第一个问题,我不是权威人士,但我敢肯定你不会找到两者匹配不同事物的组合。跨度>
  • 事情是这样的:我也可以说“我确定”我不会找到这样的组合,”我真正的意思是我只是想不出一个,甚至想不出怎么会有一个。因此,发布这样一个问题的唯一目的就是让我得到一些确认(来自有比我有更多的专家/幕后知识)这个“确定性”,或者对这个“确定性”进行一些反驳(以一个例子的形式表明我的“确定性”实际上是没有根据的——毕竟,正则表达式是一个出了名的违反直觉的概念)。
  • @kjo 我明白你的意思。我认为如果他们调用了startsWith 方法会更方便。尽管如此,我还是觉得很好,因为我知道每当我调用这两种方法时会对它们有什么期望,并且不知道它们在内部是如何工作的,这对我来说很好。
猜你喜欢
  • 2020-03-05
  • 1970-01-01
  • 2014-05-16
  • 2023-01-04
  • 1970-01-01
  • 2020-01-28
  • 2012-03-21
  • 1970-01-01
相关资源
最近更新 更多