python - Python 正则表达式性能:使用数千个正则表达式迭代文本的最佳方法
问题描述
我进行了很多研究,但没有找到任何真正帮助我的东西。也许我的方法很奇怪——也许有人可以让我的想法朝着正确的方向发展。
所以情况如下:
我需要处理大量文本(数十万)。在这些文本中,我需要查找和处理某些字符串:
- 我从数据库中提取的某些“静态”子字符串(如案例编号)(也有数十万个)
- 我与正则表达式匹配的字符串,该正则表达式动态构建以匹配每个可能出现的情况——正则表达式的最后一部分将被动态设置
很明显,这会导致大量的迭代,因为每个文本都需要输入一个函数来运行数十万个正则表达式——毕竟这会导致非常长的运行时间。
有没有更好更快的方法来完成所需的任务?现在完成的方式可以工作,但速度非常慢,并且会给服务器带来数周的沉重负载。
一些示例代码来说明我的想法:
import re
cases = [] # 100 000 case numbers from db
suffixes = [] # 500 diffrent suffixes to try from db
texts = [] # 100 000 for the beginning - will become less after initial run
def process_item(text: str) -> str:
for s in suffixes:
pattern = '(...)(.*?)(%s|...)' % s
x = re.findall(pattern, text, re.IGNORECASE)
for match in x:
# process the matches, where I need to know which suffix matched
pass
for c in cases:
escaped = re.escape(c)
x = re.findall(escaped, text, re.IGNORECASE)
for match in x:
# process the matches, where I need to know which number matched
pass
return text
for text in texts:
processed = process_item(text)
每个想法都受到高度赞赏!
解决方案
我无法发表评论,但只是一些想法:
从您发布的内容来看,您想要搜索的东西总是相同的,所以为什么不将它们加入大正则表达式并在运行循环之前编译那个大正则表达式。
这样您就不必为每次迭代编译正则表达式,而只需编译一次。
例如
import re
cases = [] # 100 000 case numbers from db
suffixes = [] # 500 diffrent suffixes to try from db
texts = [] # 100 000 for the beginning - will become less after initial run
bre1 = re.compile('|'.join(suffixes), re.IGNORECASE)
bre2 = re.compile('|'.join([re.escape(c) for c in cases]), re.IGNORECASE)
def process_item(text: str) -> str:
x = re.findall(bre1, text)
for match in x:
# process the matches, where I need to know which suffix matched
pass
x = re.findall(bre1, text)
for match in x:
# process the matches, where I need to know which number matched
pass
return text
for text in texts:
processed = process_item(text)
如果您可以case number
在其中可靠地找到text
(例如,如果它之前有一些标识符),最好使用找到案例编号re.search
并将案例编号放入set
其中并测试该集合中的成员资格。
例如
cases = ["123", "234"]
cases_set = set(cases)
texts = ["id:123", "id:548"]
sre = re.compile(r'(?<=id:)\d{3}')
for t in texts:
m = re.search(sre, t)
if m and m.group() in cases_set:
# do stuff ....
pass
推荐阅读
- c++ - shared_ptr 内 string_view 的返回值优化
- c# - 如何在 JB Rider for Xamarin.Forms 中启用智能感知?
- php - 如何不在 Laravel 路由中使用完整的控制器路径
- php - 获取“Cookie “PHPSESSID” 已因无效域而被拒绝。” 当一个模块调用另一个模块时在控制台上
- python - 我在让这个网络爬虫在 django 上启动时遇到问题。输入“python manage.py runserver”时终端出现错误
- python - 如何在 smtplib 中更改字体
- javascript - 当我尝试使用 if 语句过滤它们时,显示从 JavaScript 到 HTML 的数据,加载并在 1 秒后消失。为什么?
- r - 绘制决策树分类器
- azure - Spark, wasb and Jetty 11
- spring-boot-gradle-plugin - no suitable constructor found for File(String)