You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现词库与多正则表达式的最快匹配优化?

词库与多正则匹配的性能优化方案

需求背景

需要将大型词库中的每个单词与所有小写字母有序双组合(如ab、ba等)对应的正则表达式.*{let1}.*{let2}.*进行匹配,最终建立双组合到对应匹配单词的映射。

现有实现及性能

首次尝试(低效)

%%time
mapping = {f'{k1}{k2}':[] for k1 in string.ascii_lowercase for k2 in string.ascii_lowercase}

for word in word_list[:1000]:
    for let1,let2 in mapping:
        if re.search(rf'.*{let1}.*{let2}.*', word):
            mapping[let1+let2].append(word)

耗时:Wall time: 22.2 s

优化后实现

%%time
mapping = {f'{k1}{k2}':
                [word for word in word_list[:1000] if re.search(rf'.*{k1}.*{k2}.*', word)] 
          for k1,k2 in itertools.product(string.ascii_lowercase, string.ascii_lowercase)}

耗时:Wall time: 608 ms

进一步优化方案

方案1:预编译正则表达式

原优化版每次生成正则时都会隐式编译,预编译所有正则可避免重复编译的开销,进一步提速:

import string
import itertools
import re
from nltk.corpus import words
import time

word_list = words.words()[:1000]

# 预编译所有双字母组合对应的正则
regex_cache = {}
for k1, k2 in itertools.product(string.ascii_lowercase, string.ascii_lowercase):
    regex_cache[f"{k1}{k2}"] = re.compile(rf'.*{k1}.*{k2}.*')

# 构建映射
start = time.time()
mapping = {
    key: [word for word in word_list if regex_cache[key].search(word.lower())]
    for key in regex_cache
}
end = time.time()

print(f"耗时: {end - start:.3f} s")

优化点:提前编译所有正则,避免循环中重复编译;统一转小写处理,确保大小写不影响匹配结果。

方案2:抛弃正则,用字符位置判断(最优)

正则匹配本身有一定开销,我们可以直接通过分析单词中字符的出现顺序来替代正则逻辑,完全规避正则开销:

import string
import itertools
from nltk.corpus import words
import time

word_list = words.words()[:1000]

# 初始化映射字典
mapping = {f"{k1}{k2}": [] for k1, k2 in itertools.product(string.ascii_lowercase, string.ascii_lowercase)}

start = time.time()

for word in word_list:
    word_lower = word.lower()
    # 记录单词中每个字符的位置(仅保留小写字母)
    char_pos = [(char, idx) for idx, char in enumerate(word_lower) if char in string.ascii_lowercase]
    # 生成所有符合let1在let2之前的有序对
    for i in range(len(char_pos)):
        let1, pos1 = char_pos[i]
        for j in range(i, len(char_pos)):
            let2, pos2 = char_pos[j]
            key = f"{let1}{let2}"
            mapping[key].append(word)

# 对每个列表去重(避免单词因重复字母被多次添加)
for key in mapping:
    mapping[key] = list(set(mapping[key]))

end = time.time()
print(f"耗时: {end - start:.3f} s")

优化点:

  • 完全脱离正则,用纯字符串遍历和位置判断实现匹配逻辑,速度远超正则方案
  • 仅处理单词中的有效小写字母,减少无效计算
  • 最后对列表去重,保证每个单词在对应键下只出现一次

方案3:批量处理与向量化(针对超大规模词库)

如果词库规模极大(百万级以上),可以结合pandas进行向量化处理,利用底层优化进一步提升效率:

import string
import itertools
import pandas as pd
from nltk.corpus import words

word_list = words.words()[:1000]
df = pd.DataFrame({"word": word_list})
df["word_lower"] = df["word"].str.lower()

mapping = {}
for k1, k2 in itertools.product(string.ascii_lowercase, string.ascii_lowercase):
    # 用pandas的str.contains实现批量匹配
    mask = df["word_lower"].str.contains(rf'.*{k1}.*{k2}.*')
    mapping[f"{k1}{k2}"] = df.loc[mask, "word"].tolist()

优化点:利用pandas的向量化字符串操作,底层基于C实现,批量处理效率更高。

复现代码

import nltk
nltk.download('words')
from nltk.corpus import words
word_list = words.words()

内容的提问来源于stack exchange,提问作者You_Donut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:25:12