Реализация preg_match_all в Python - PullRequest
2 голосов
/ 04 февраля 2010

Мне в основном нужна та же функциональность, что и в preg_match_all() от PHP на языке Python.

Если у меня есть шаблон регулярного выражения и строка, есть ли способ найти строку и получить словарь каждого вхождения гласного, вместе с его положением в строке?

Пример:

s = "supercalifragilisticexpialidocious"

Вернется:

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

Ответы [ 3 ]

6 голосов
/ 04 февраля 2010

Вы можете сделать это быстрее без регулярных выражений

[(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 голосов
/ 04 февраля 2010

То, что вы просите, не может быть словарем, так как оно имеет несколько идентичных ключей. Тем не менее, вы можете поместить его в список кортежей, например так:

>>> [(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)]
0 голосов
/ 04 февраля 2010

Вот так, например:

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 находит только непересекающиеся совпадения. А ключи dict будут перезаписаны, поэтому, если вы хотите первое совпадение, вам придется заменить самый внутренний цикл на:

    for match in re.finditer(pattern, string):
        if match.group(0) not in res: # <-- don't overwrite key
            res[match.group(0)] = match.start()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...