python-regex搜索和查找

2024-06-01 06:59:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要在给定正则表达式的字符串中找到所有匹配项。我一直在用findall()来做这件事,直到我遇到一个案例,它没有做我期望的事情。例如:

regex = re.compile('(\d+,?)+')
s = 'There are 9,000,000 bicycles in Beijing.'

print re.search(regex, s).group(0)
> 9,000,000

print re.findall(regex, s)
> ['000']

在这种情况下,^{}返回我需要的内容(最长的匹配),但是^{}的行为不同,尽管文档暗示应该相同:

findall() matches all occurrences of a pattern, not just the first one as search() does.

  • 为什么行为不同?

  • 我怎样才能用findall()(或者别的什么东西)达到search()的结果?


Tags: 字符串inresearchgroup事情are案例
3条回答

好吧,我知道怎么回事了。。。从文档中:

If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group.

事实证明,您确实有一个组,“(\d+,?)”。。。所以,它返回的是这个组的最后一次出现,即000。

一种解决方案是用一个组包围整个regex,如下所示

regex = re.compile('((\d+,?)+)')

然后,它将返回[('9000000','000')],这是一个包含两个匹配组的元组。当然,你只关心第一个。

就我个人而言,我会使用下面的regex

regex = re.compile('((\d+,)*\d+)')

为了避免类似“这是个坏数字9123”这样的匹配

编辑。

下面是一种避免用括号括住表达式或处理元组的方法

s = "..."
regex = re.compile('(\d+,?)+')
it = re.finditer(regex, s)

for match in it:
  print match.group(0)

finditer返回一个迭代器,您可以使用它访问找到的所有匹配项。这些匹配对象与re.search返回的结果相同,因此组(0)返回预期的结果。

@aleph@null的answer正确地解释了导致您问题的原因,但我认为我有更好的解决方案。使用此正则表达式:

regex = re.compile(r'\d+(?:,\d+)*')

为什么会更好:

  1. (?:...)是一个非捕获组,因此每次匹配只能得到一个结果。

  2. \d+(?:,\d+)*是一个更好的正则表达式,效率更高,返回误报的可能性更小。

  3. 如果可能的话,您应该始终对正则表达式使用Python的原始字符串;您不太可能对正则表达式转义序列(例如,\b用于单词边界)被解释为字符串文字转义序列(例如,\b用于退格)感到惊讶。

相关问题 更多 >