Python中re.split()使用超长pattern列表时如何提升效率?
现在又一个十几万个基因的名字,需要在一段文字中找到这些基因 Gene Symbol,然后从这个 Gene Symbol 两边切一刀,把这段文字切成 list
但是这个 pattern 就会操集长,想到用 re.split 来弄,但是 pattern 太长了,效率低
Python中re.split()使用超长pattern列表时如何提升效率?
5 回复
手写个 AC 自动机?
用 re.compile() 预编译一个合并的正则表达式对象,效率会高得多。别在循环里反复调用 re.split(),尤其是 pattern 列表很长的时候。
核心思路是:用管道符 | 把所有的分隔符 pattern 合并成一个,然后用 re.split() 一次搞定。这样正则引擎只需要编译一次,并且对整个字符串只扫描一遍。
import re
# 假设你原来有一个很长的分隔符列表
long_pattern_list = [r'\s+', r',', r';', r'\d+', r'[a-z]+'] # 示例,可能很长
# 低效做法:循环中反复 split
text = "some sample, text; with123 multiple patterns"
for pattern in long_pattern_list:
# 每次循环都重新编译正则,效率低
parts = re.split(pattern, text)
# ... 处理 parts
# 高效做法:合并 pattern 并预编译
# 1. 合并所有 pattern,用 | 隔开。注意用 (?:) 非捕获组包裹每个 pattern 以避免捕获组影响 split 结果。
combined_pattern = '|'.join(f'(?:{p})' for p in long_pattern_list)
# 示例结果: (?:\\s+)|(?:,)|(?:;)|(?:\\d+)|(?:[a-z]+)
# 2. 预编译
compiled_re = re.compile(combined_pattern)
# 3. 一次性 split
result = compiled_re.split(text)
print(result)
# 输出: ['', 'ample', '', ' ', '123 ', ' ', '']
# 注意:结果中包含空字符串,因为分隔符出现在开头/结尾或连续出现。这是正常现象,按需过滤即可。
# 如果你需要保留分隔符(比如用 split 的捕获组功能),调整合并方式:
# 用捕获组 () 代替非捕获组 (?:)
combined_with_capture = '|'.join(f'({p})' for p in long_pattern_list)
compiled_with_capture = re.compile(combined_with_capture)
result_with_capture = compiled_with_capture.split(text)
print(result_with_capture)
# 输出会包含分隔符作为单独元素
简单说,就是把多个 pattern 打包成一个来用。
FlashText 了解一下?
flashtext 中文好用吗,是不是要先分个词
re 按行操作的话不会很长,python 自己的函数处理文字非常慢,按二进制读文字做匹配速度会快很多

