在Python中查找字符串中正则表达式匹配的次数

61 投票
8 回答
74570 浏览
提问于 2025-04-15 14:03

有没有办法让我知道在Python中一个字符串里有多少个正则表达式的匹配项?比如说,我有一个字符串 "It actually happened when it acted out of turn."

我想知道 "t a" 在这个字符串里出现了多少次。在这个字符串中,"t a" 出现了两次。我希望我的函数能告诉我它出现了两次。这可能吗?

8 个回答

20

我知道这个问题是关于正则表达式的。不过我想提一下 count 这个方法,以备将来有人想要一个不使用正则表达式的解决方案。

>>> s = "It actually happened when it acted out of turn."
>>> s.count('t a')
2

这个方法会返回子字符串在字符串中不重叠出现的次数。

69

这段代码是用来处理一些特定的任务的。它可能涉及到数据的输入、输出或者是一些计算。具体来说,代码块中的内容会告诉计算机该怎么做,按照什么步骤来完成工作。

如果你看到代码中的某些部分,比如变量、函数或者循环,这些都是编程中常用的概念。变量就像是一个可以存放信息的小盒子,函数则是一组可以重复使用的指令,而循环则是让某些指令重复执行的方式。

总之,这段代码的目的是为了让计算机按照预定的方式来处理数据,完成特定的功能。理解这些基本概念后,你就能更好地理解代码是如何工作的了。

import re
len(re.findall(pattern, string_to_search))
31

现有的基于 findall 的解决方案对于不重叠的匹配是可以的(而且在匹配数量不大的情况下效果很好),不过如果你只关心匹配的数量,可以使用其他方法,比如 sum(1 for m in re.finditer(thepattern, thestring)),这样就不会生成一个完整的列表。还有一种比较特别的做法是使用 subn,然后忽略返回的字符串……

def countnonoverlappingrematches(pattern, thestring):
  return re.subn(pattern, '', thestring)[1]

这个后者的想法唯一的好处是,如果你只想统计(比如说)最多100个匹配,那么 re.subn(pattern, '', thestring, 100)[1] 可能是个不错的选择(无论匹配数量是100、1000,还是更多,它都会返回100)。

要统计重叠的匹配,你需要写更多的代码,因为内置的函数都是针对不重叠的匹配。还有一个定义的问题,比如当模式是 'a+',而字符串是 'aa' 时,你会认为这是一个匹配,还是三个匹配(第一个 a、第二个 a、还是两个都算)?

假设你想要可能重叠的匹配,并且这些匹配要从字符串中的不同位置开始(这样在上面的例子中就会得到两个匹配):

def countoverlappingdistinct(pattern, thestring):
  total = 0
  start = 0
  there = re.compile(pattern)
  while True:
    mo = there.search(thestring, start)
    if mo is None: return total
    total += 1
    start = 1 + mo.start()

注意,在这种情况下你确实需要将模式编译成一个正则表达式对象:函数 re.search 不接受 start 参数(即搜索的起始位置),而 方法 search 是可以的,所以你需要在遍历字符串时进行切片——这比直接从下一个可能的起始点开始搜索要麻烦得多,这也是我在这个函数中所做的。

撰写回答