在Python中实现preg_match_all

2 投票
3 回答
1367 浏览
提问于 2025-04-15 18:54

我基本上想要在Python中实现和PHP的preg_match_all()一样的功能。

如果我有一个正则表达式和一个字符串,有没有办法在这个字符串中查找,并返回一个字典,里面包含每个元音字母出现的位置?

举个例子:

s = "supercalifragilisticexpialidocious"

会返回:

{
  'u' : 1,
  'e' : 3,
  'a' : 6,
  'i' : 8,
  'a' : 11,
  'i' : 13,
  'i' : 15
}

3 个回答

0

比如这样:

import re

def findall(pattern, string):
    res = {}
    for match in re.finditer(pattern, string):
        res[match.group(0)] = match.start()
    return res

print findall("[aeiou]", "Test this thang")

注意,re.finditer 只会找到不重叠的匹配项。而且字典的键会被覆盖,所以如果你想要第一个匹配结果,你需要把最里面的循环替换成:

    for match in re.finditer(pattern, string):
        if match.group(0) not in res: # <-- don't overwrite key
            res[match.group(0)] = match.start()
6

你可以在不使用正则表达式的情况下,更加快速地完成这个任务。

[(x,i) for i,x in enumerate(s) if x in "aeiou"]

这里有一些时间测试的结果:
对于 s = "supercalifragilisticexpialidocious"

timeit [(m.group(0), m.start()) for m in re.finditer('[aeiou]',s)]
10000 loops, best of 3: 27.5 µs per loop

timeit [(x,i) for i,x in enumerate(s) if x in "aeiou"]
100000 loops, best of 3: 14.4 µs per loop

对于 s = "supercalifragilisticexpialidocious"*100

timeit [(m.group(0), m.start()) for m in re.finditer('[aeiou]',s)]
100 loops, best of 3: 2.01 ms per loop

timeit [(x,i) for i,x in enumerate(s) if x in "aeiou"]
1000 loops, best of 3: 1.24 ms per loop
5

你问的这个东西不能用字典来表示,因为字典里不能有多个相同的键。不过,你可以把它放在一个元组的列表里,像这样:

>>> [(m.group(0), m.start()) for m in re.finditer('[aeiou]',s)]
[('u', 1), ('e', 3), ('a', 6), ('i', 8), ('a', 11), ('i', 13), ('i', 15), ('i', 18), ('e', 20), ('i', 23), ('a', 24), ('i', 26), ('o', 28), ('i', 30), ('o', 31), ('u', 32)]

撰写回答