Python:更快的正则替换

3 投票
2 回答
826 浏览
提问于 2025-04-17 01:15

我有一大堆大文件,还有一组需要在每个文件中替换的“短语”。
这些替换有一些“业务逻辑”上的限制:

  • 匹配时不区分大小写
  • 正则表达式中的空格、制表符和换行符不能被忽略

我现在的解决方案(见下文)有点慢。有什么办法可以优化一下,既提高输入输出的效率,又加快字符串替换的速度呢?

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 个回答

2

你可以通过使用B树这种数据结构来存储你的短语,这样可以在一次操作中完成。这是最快的方法,时间复杂度是N O(log h),其中N是你输入文件中的字符数量,h是你最长单词的长度。不过,Python并没有现成的B树实现。

你也可以使用哈希表(字典)和一个替换函数来加快速度。如果你想替换的单词都是字母和数字组合的单个单词,这种方法很容易实现。

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()
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 ",但现在并没有匹配到。

撰写回答