Python正则表达式性能:使用数千个正则表达式迭代文本的最佳方法
我做了很多研究,但没有发现任何真正对我有帮助的东西。也许我的方法很奇怪——也许有人能把我的想法引向正确的方向 因此,情况如下: 我需要处理大量的文本(几十万)。在这些文本中,我需要查找并处理某些字符串:Python正则表达式性能:使用数千个正则表达式迭代文本的最佳方法,python,regex,python-3.x,Python,Regex,Python 3.x,我做了很多研究,但没有发现任何真正对我有帮助的东西。也许我的方法很奇怪——也许有人能把我的想法引向正确的方向 因此,情况如下: 我需要处理大量的文本(几十万)。在这些文本中,我需要查找并处理某些字符串: 我从数据库中提取的某些“静态”子字符串(如案例编号)(也有几十万个) 与正则表达式匹配的字符串,该正则表达式是动态构建的,以匹配每个可能出现的情况,其中正则表达式的最后一部分将动态设置 很明显,这会导致大量的迭代,因为每一个文本都需要输入一个函数来运行它,这个函数可以运行数十万个正则表达式,而且
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
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)
从您发布的内容来看,您想要搜索的内容似乎总是相同的,所以为什么不在运行循环之前将它们加入到大regexp中并编译大regexp呢
通过这种方式,您不必为每次迭代编译正则表达式,只需编译一次
e、 g
如果您能够在文本中可靠地找到案例编号
(例如,如果它前面有某个标识符),则最好使用re.search
查找案例编号,并将案例编号设置在中
并测试该集合中的成员资格
e、 g
cases=[“123”,“234”]
案例集合=集合(案例)
文本=[“id:123”,“id:548”]
sre=re.compile(r’(?我不能评论,但只是一些想法:
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)
从您发布的内容来看,您想要搜索的内容似乎总是相同的,所以为什么不在运行循环之前将它们加入到大regexp中并编译大regexp呢
通过这种方式,您不必为每次迭代编译正则表达式,只需编译一次
e、 g
如果您能够在文本中可靠地找到案例编号
(例如,如果它前面有某个标识符),则最好使用re.search
查找案例编号,并将案例编号设置在中
并测试该集合中的成员资格
e、 g
cases=[“123”,“234”]
案例集合=集合(案例)
文本=[“id:123”,“id:548”]
sre=re.compile(r'(?你说你是从数据库中提取的..你不能生成一个后缀字段吗?@Sayse不确定我是否正确:我从django模型中提取数据,该模型有一个带有后缀的字段。我正在对它们进行迭代,并将它们放在正则表达式模式中,使用我误解的%sAh..基本上是想,而不是想看看如何做到这一点,找出为什么有这么多的变量要开始,看看减少those@Sayse谢谢!我考虑过了。但是我想不出减少它们的方法,因为我永远不知道变量在哪里可以累积,在哪里不可以。所以每个文本都可能匹配生成的任何正则表达式--你说你从数据库中提取它们。.你不能做一个后缀字段吗?@Sayse不确定我是否正确:我从django模型中提取数据,该模型有一个带后缀的字段。我迭代它们,并将它们放在正则表达式模式中,使用我误解的%sAh。基本上,我的想法是,而不是看如何做,找出为什么有这么多变量to从开始,看看减少those@Sayse谢谢!我考虑过了。但是我想不出一个方法来减少它们,因为我永远不知道变量在哪里可以精确,在哪里不可以。所以每一个文本都可能匹配任何生成的正则表达式--谢谢你的时间和努力。今晚我将尝试你的方法。我也一样仔细考虑了如何编写正则表达式(或多个正则表达式)这可以找到文本中的每个案例编号,然后查看它是否存在于我的案例编号列表中。这应该快得多,对吧?顺便说一句,新的贡献者不能发表评论真是太遗憾了……是的,如果你可以编写regexp捕获你的案例编号
,那么它会更快。但是将列表
转换为设置为set
s对于成员资格测试来说更好。另外,如果案例编号
s是“数字”,那么最好将其转换为int
(节省内存)。很高兴您现在可以发表评论!:)这些是非常有用的提示,谢谢!数字是字母数字,所以我将尝试“设置”。对于我这个爱好编码的人来说,处理如此大量的数据是一件新鲜事,所以每一个优化提示都非常有用。关于:新的贡献者不能发表评论真是太遗憾了…-在这种情况下,这是一件好事-否则我们可能不会有这个完全可以接受的答案。在我看来,贡献者往往会感到遗憾无论是新的还是旧的,写下评论,这些评论都可以作为答案。谢谢你的时间和努力。今晚我将尝试你的方法。我只是想知道如何写一个正则表达式(或多个正则表达式)这可以找到文本中的每个案例编号,然后查看它是否存在于我的案例编号列表中。这应该快得多,对吧?顺便说一句,新的贡献者不能发表评论真是太遗憾了……是的,如果你可以编写regexp捕获你的案例编号
,那么它会更快。但是将列表
转换为设置为set
s对于成员资格测试来说更好。另外,如果案例编号
s是“数字”,那么最好将其转换为int
(节省内存)。很高兴您现在可以发表评论!:)这些是非常有用的提示,谢谢!数字是字母数字,所以我将尝试“设置”。