Python: более быстрое регулярное выражение заменяет - PullRequest
3 голосов
/ 02 сентября 2011

У меня большой набор больших файлов и набор «фраз», которые необходимо заменить в каждом файле.
«Бизнес-логика» накладывает несколько ограничений:

  • Соответствие должнобыть без учета регистра
  • Пробелы, табуляции и новые строки в регулярном выражении нельзя игнорировать

Мое решение (см. ниже) немного медленное.Как его можно оптимизировать, как с точки зрения ввода-вывода, так и замены строк?

data = open("INPUT__FILE").read()
o = open("OUTPUT_FILE","w")
for phrase in phrases: # these are the set of words I am talking about
        b1, b2 = str(phrase).strip().split(" ")
        regex = re.compile(r"%s\ *\t*\n*%s"%(b1,b2), re.IGNORECASE)
        data = regex.sub(b1+"_"+b2,data)
o.write(data)

UPDATE : ускорение в 4 раза путем преобразования всего текста в нижний регистр и удаления re.IGNORECASE

Ответы [ 2 ]

5 голосов
/ 02 сентября 2011

вы можете избежать перекомпиляции вашего регулярного выражения для каждого файла:

precompiled = []
for phrase in phrases:
    b1, b2 = str(phrase).strip().split(" ")
    precompiled.append(b1+"_"+b2, re.compile(r"%s\ *\t*\n*%s"%(b1,b2), re.IGNORECASE))

for (input, output) in ...:
    with open(output,"w") as o:
        with open(input) as i:
            data = i.read()
            for (pattern, regex) in precompiled:
                data = regex.sub(pattern, data)
            o.write(data)

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

заявление об отказе: не проверено, может содержать опечатки.

[ update ] также вы можете немного упростить регулярное выражение, заменив различные пробелы на \s*.я подозреваю, что у вас есть ошибка, в которой вы хотели бы соответствовать " \t ", а в настоящее время нет.

2 голосов
/ 02 сентября 2011

Вы можете сделать это за 1 проход, используя структуру данных B-Tree для хранения ваших фраз. Это самый быстрый способ сделать это с временной сложностью N O(log h), где N - количество символов во входном файле, а h - длина вашего самого длинного слова. Однако Python не предлагает готовую реализацию B-Tree.

Вы также можете использовать Hashtable (словарь) и функцию замены, чтобы ускорить процесс. Это легко реализовать, если слова, которые вы хотите заменить, состоят только из букв и цифр.

replace_data = {}

# Populate replace data here
for phrase in phrases:
    key, value = phrase.strip().split(' ')
    replace_data[key.lower()] = value

def replace_func(matchObj):
    # Function which replaces words
    key = matchObj.group(0).lower()
    if replace_data.has_key(key):
        return replace_data[key]
    else:
        return key

# Original code flow
data = open("INPUT_FILE").read()
output = re.sub("[a-zA-Z0-9]+", replace_func, data)
o = open('OUTPUT_FILE', 'w')
o.write(output)
o.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...