2016-02-06 4 views
-2

У меня есть следующий код Python, но он работает немного медленнее в файле 10mb. Мне интересно, есть ли способ ускорить это? Возможно, сделав re.sub все за один раз (а не две операции) - не знаете, как это сделать, или, может быть, есть другой способ?Ускорение re.sub в python

def ChangeMode(file, amode0, amode1, bmode0, bmode1): 
for line in iter(file): 
    if 'AAA' in line or 'BBB' in line or 'CCC' in line: 
      line = re.sub(mode0, mode1, line) 
      line = re.sub(bmode0, bmode1, line) 
    endstring += line 
return endstring 

Приветствие

+1

Вы можете предварительно скомпилировать шаблон с помощью 're.compile' и передать скомпилированный шаблон в' re.sub'. –

+0

сначала компилируйте регулярное выражение, глядя на 'for line in iter (file)' заставляет меня думать, что вам может не понадобиться регулярное выражение вообще, как вы думаете, что он делает? –

+0

Привет, мне интересно, как это сделать в контексте моей функции? Есть идеи? Я новичок во всем этом ... –

ответ

1

Если пострадавшие линии редко можно ускорить много с помощью re.sub или re.finditer для нахождения этих строк непосредственно вместо итерации линий на уровне Python. И str.replace быстро в случае простых строковых замен:

def fsub(m): 
    return m.group().replace('ij', 'xx').replace('kl', 'yy') 

s = re.sub('(?m)^.*(?:AAA|BBB|CCC).*', fsub, open(path).read()) 

Примечание: (?m) вызывает ^, чтобы соответствовать начало каждой строки и .*, чтобы не захватить за конец строки.

REGEX прекомпиляция может ускорить многие индивидуальный REGEX re.sub-х (если простые строковые замены не применяется) немного:

rec = re.compile(r'ij\d+') # once 
... 
line = rec.sub('xx', line) # often 

(re.sub однако использует уже кэш REGEX компиляции, которая довольно быстро еще .)

Если замена не изменяет размер строки, вы можете значительно ускорить работу с помощью bytearray/буферов или даже mmap и изменить данные на месте. (re.sub() и string.replace и endstring += line вызывают копирование большого количества памяти.)