Ускорьте сопоставление регулярных выражений в Python - PullRequest
0 голосов
/ 30 марта 2020

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

Как вы можете сделать этот код быстрее?

Мне нужны индексы двух массивов в качестве вывода (в файл наконец).

import re
from timeit import default_timer as timer

a = ['apple_789456',
     'banana_741',
     'pear_11112222',
     'orange_454545',
     'pineapple_7777888',
     'banana_999999'
    ]
regs = [r'ple.*?7',
        r'a.*?74',
        r'range.*?5',
        r'45'
       ]
regs_re = [re.compile(r) for r in regs]

start = timer()
for i in range(len(a)):
   for j in range(len(regs)):
      if re.search(regs_re[j],a[i]):
         print('regs_re['+str(j)+'] found in a['+str(i)+']: '+a[i])
print(timer() - start)

1 Ответ

1 голос
/ 31 марта 2020

Одним из способов ускорить его было бы выполнение каждого выражения только один раз по всему тексту (объединенные строки). Это не приведет к получению результатов в том же порядке, но сделает это в несколько раз быстрее на тысячах строк.

Очевидно, что печать, когда вы go полностью испортит измерение времени, поэтому я поместил результаты в список для сравнения времени выполнения.

from bisect import bisect_left
from itertools import accumulate
start     = timer()
text      = "\n".join(a)                      # single string with all lines      
lineIndex = [i for i,c in enumerate(text) if c=="\n"] # map positions to line number
result    = []                                # accumulate results in a list
for j,expr in enumerate(regs):                # execute each expression only once
    previ = -1                                # finditer may find multiple occurrences on same line
    for m in re.finditer(expr,text):          # go through all occurrences
         i = bisect_left(lineIndex,m.start()) # determine line number
         if i == previ: continue
         previ = i         
         result.append((i,j))                 # build result list
print(timer() - start)
for i,j in result:
    print(f"regs_re[{j}] found i a[{i}]: {a[i]}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...