如何使用正则表达式搜索连续递增序列
How to use a regex to search for contiguous incrementing sequences
我想使用正则表达式来提高在大型二进制图像中搜索特定记录的速度。似乎正则表达式搜索总是胜过我自己的搜索方法,所以这就是我研究这个的原因。我已经实现了以下,它有效,但速度不是很快。
我的二进制图像作为单词加载到 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...
这是寻找以 0 到 59 之间的十进制序列号开头的 19 字节长的记录。它在当前搜索位置之前或之后的记录上寻找递增序列以验证记录。
我见过几个例子,其中人们使用 re.escape(例如:How to use a variable inside a regular expression?)将变量制作成字符串,但我似乎无法弄清楚如何搜索不断变化的变量值序列。
我设法让它与正则表达式一起工作,但它比我预期的要复杂一些。正则表达式查找介于 0 和 59 之间的两个值,它们由 72 个字节(18 个字)分隔。我使用了两个正则表达式搜索来确保我不会错过序列末尾的记录:
# First search uses the lookahead assertion to not consume large amounts of data.
SearchPattern1 = re.compile(b'[[=10=]-\x3B][=10=][=10=][=10=](?=.{72}[-\x3B][=10=][=10=][=10=])', re.DOTALL)
# Again using the positive lookbehind assertion (?<= ... ) to grab the ending entries.
SearchPattern2 = re.compile(b'(?<=[[=10=]-\x3B][=10=][=10=][=10=].{72})[-\x3B][=10=][=10=][=10=]', 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 秒!!
我想使用正则表达式来提高在大型二进制图像中搜索特定记录的速度。似乎正则表达式搜索总是胜过我自己的搜索方法,所以这就是我研究这个的原因。我已经实现了以下,它有效,但速度不是很快。
我的二进制图像作为单词加载到 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...
这是寻找以 0 到 59 之间的十进制序列号开头的 19 字节长的记录。它在当前搜索位置之前或之后的记录上寻找递增序列以验证记录。
我见过几个例子,其中人们使用 re.escape(例如:How to use a variable inside a regular expression?)将变量制作成字符串,但我似乎无法弄清楚如何搜索不断变化的变量值序列。
我设法让它与正则表达式一起工作,但它比我预期的要复杂一些。正则表达式查找介于 0 和 59 之间的两个值,它们由 72 个字节(18 个字)分隔。我使用了两个正则表达式搜索来确保我不会错过序列末尾的记录:
# First search uses the lookahead assertion to not consume large amounts of data.
SearchPattern1 = re.compile(b'[[=10=]-\x3B][=10=][=10=][=10=](?=.{72}[-\x3B][=10=][=10=][=10=])', re.DOTALL)
# Again using the positive lookbehind assertion (?<= ... ) to grab the ending entries.
SearchPattern2 = re.compile(b'(?<=[[=10=]-\x3B][=10=][=10=][=10=].{72})[-\x3B][=10=][=10=][=10=]', 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 秒!!