Python:更快的正则表达式替换

时间:2011-09-02 15:47:51

标签: python regex replace

我有一大堆大文件和一组需要在每个文件中替换的“短语” “业务逻辑”强加了几个限制:

  • 匹配必须不区分大小写
  • 正则表达式中的空白,制表符和新行不容忽视

我的解决方案(见下文)有点慢。如何在IO和字符串替换方面进行优化?

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)

更新:通过将所有文字转换为小写并放弃re.IGNORECASE

来加速4倍

2 个答案:

答案 0 :(得分:5)

您可以避免为每个文件重新编译正则表达式:

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)

对于一个文件来说是一样的,但是如果你重复多个文件,那么你就是在重复使用正则表达式。

免责声明:未经测试,可能包含错别字。

[更新]也可以通过用\s*替换各种空格字符来简化正则表达式。我怀疑你有一个错误,因为你想匹配" \t ",但目前没有。

答案 1 :(得分:2)

您可以使用B-Tree数据结构存储短语,从而在1遍中执行此操作。这是以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()