在字符串中查找多个子字符串之一的最快方法

时间:2021-04-20 15:30:24

标签: python python-3.6

我正在做很多文件处理,我在每一行中寻找几个子字符串之一。所以我有与此等效的代码:

with open(file) as infile:
    for line in infile:
        for key in MY_SUBSTRINGS:
            if key in line:
                print(key, line)

MY_SUBSTRINGS 是 6-20 个子字符串的列表。子字符串的长度为 10-30 个字符,并且可能包含空格。

我真的很想找到一种更快的方法来做到这一点。文件中有很多 100k 行。行通常为 150 个字符。文件处理时用户必须等待 30 秒到一分钟。以上不是唯一需要时间的事情,而是需要很多时间。我正在逐行执行各种其他过程,因此不适合一次性搜索整个文件。

我已经尝试了这里的正则表达式和 ahocorasick 答案,但它们在我的测试中都较慢:

Fastest way to check whether a string is a substring in a list of strings

对更快的方法有什么建议吗?

我不太确定共享示例数据集的最佳方式。 Android 手机上的 logcat 就是一个例子。至少有 20 万行。

然后搜索 10 个字符串,例如:

(NL80211_CMD_TRIGGER_SCAN) 已收到

尝试联系

请求解除认证

接口状态 UNINITIALIZED->ENABLED


我尝试过这样的正则表达式:

match_str = "|".join(MY_SUBSTRINGS)
regex = re.compile(match_str)

with open(file) as infile:
    for line in infile:
        match = regex.search(line)
        if match:
            print(match.group(0))

1 个答案:

答案 0 :(得分:1)

我会构建一个正则表达式来搜索文件。

确保您在使用正则表达式时没有在循环中运行每个搜索词。

如果你的每个表达式都在一个正则表达式中,它看起来像这样:

import re

line = 'fsjdk abc def abc jkl'
re.findall(r'(abc|def)', line)

https://docs.python.org/3/library/re.html

如果您需要更快地运行,请考虑与线程同时运行一个进程。这是一个更广泛的主题,但一种可行的方法是首先查看您的问题并考虑瓶颈可能是什么。

如果问题是您的外观在读取时缺乏磁盘吞吐量,您可以做的是首先运行文件并将其拆分为块,然后将这些块映射到可以像队列一样处理数据的工作线程.

肯定需要更多关于您的问题的信息才能准确了解您要解决的问题类型。这里有些人肯定会喜欢挑战。