我想使用正则表达式来提高我在大型二进制图像中搜索特定记录的速度。 似乎正则表达式搜索总是优于我自己的搜索方法,所以这就是我研究这个问题的原因。 我已经实现了以下内容,它有效,但不是很快。
我的二进制图像作为单词加载到 Numpy 内存映射中。
I_FILE = np.memmap(opts.image_file, dtype='uint32', mode='r')
这是我目前搜索循环的开始(有效):
for i in range(0, FILESIZE - 19):
if (((I_FILE[i] + 1 == I_FILE[i + 19]) or (I_FILE[i - 19] + 1 == I_FILE[i])) and I_FILE[i] < 60):
...do stuff...
这是查找长度为 19 个字节且以 0 到 59 之间的十进制序列号开头的记录。 它在当前搜索位置之前或之后的记录上查找递增序列以验证记录。
我看过一些例子,人们使用 re.escape 将变量制作成字符串(比如这样:如何在正则表达式中使用变量? 但我似乎无法弄清楚如何搜索不断变化的值序列。
我设法让它与正则表达式一起使用,但它比我预期的要复杂一些。正则表达式查找 0 到 59 之间的两个值,这些值由 72 个字节(18 个单词)分隔。 我使用了两个正则表达式搜索来确保我不会错过序列末尾的记录:
# First search uses the lookahead assertion to not consume large amounts of data.
SearchPattern1 = re.compile(b'[ -x3B] (?=.{72}[1-x3B] )', re.DOTALL)
# Again using the positive lookbehind assertion (?<= ... ) to grab the ending entries.
SearchPattern2 = re.compile(b'(?<=[ -x3B] .{72})[1-x3B] ', re.DOTALL)
接下来,执行两个搜索并合并结果。
HitList1 = [m.start(0) for m in SearchPattern1.finditer(I_FILE)]
HitList2 = [m.start(0) for m in SearchPattern2.finditer(I_FILE)]
AllHitList = list(set(HitList1 + HitList2))
SortedHitList = sorted(AllHitList)
现在,我运行的搜索与原始解决方案的条件相同,但它运行的数据集要小得多!
for i in range(0, len(SortedHitList)):
TestLoc = SortedHitList[i]
if (I_FILE[TestLoc] + 1 == I_FILE[TestLoc + 19]) or (I_FILE[TestLoc - 19] + 1 == I_FILE[TestLoc]):
... do stuff ...
结果非常成功! 原始解决方案在 300 MB 二进制文件上运行需要 58 秒,而新的正则表达式解决方案仅用了 2 秒!!