python regex 使用捕获组来定义另一个组长度

Posted

技术标签:

【中文标题】python regex 使用捕获组来定义另一个组长度【英文标题】:python regex use capture group to define another groups length 【发布时间】:2015-09-14 18:19:38 【问题描述】:

我正在使用 python 正则表达式解析流式十六进制数据。我尝试从数据包流中提取以下数据包结构:

'\xaa\x01\xFF\x44'
\xaa - 数据包开始 \x01 - 数据长度 [值可以在 00-FF 之间变化] \xFF - 数据 \x44 - 数据包结束

我想使用 python 正则表达式来指示要匹配的数据包的数据部分:

r = re.compile('\xaa(?P<length>[\x00-\xFF]1)(.*)?P<length>\x44')

这编译没有错误,但它不起作用。我怀疑它不起作用,因为正则表达式引擎无法将 &lt;length&gt; 命名组十六进制值转换为适当的整数,以便在正则表达式 表达式中使用。有没有一种方法可以在 python 中完成,而无需传播匹配组?

背景:我一直在使用 erlang 进行数据包解包,我在 python 中寻找类似的东西

【问题讨论】:

如果您确定此时的数据包结构以\x44 结尾,您可以使用\xaa.(.*?)\x44 吗?或者您是否有机会在数据包的有效负载中遇到\x44 这是一个通过串行接口运行的流协议。我可能会收到超过 1 个数据包或 1.5 个数据包等的读取。考虑到这一点,我必须验证匹配的内容是否确实是数据包。仅仅匹配开始和结束块是不够的,因为数据本身可能包括 \xaa, \x44 字节 在这种情况下,我不认为正则表达式是你的答案。我会构建一个使用deque 的东西,让新的传入数据包扩展它,然后从它检索一个消费者(可能使用一些基于状态的解析,具体取决于传入流的复杂程度)。 【参考方案1】:

我最终做了以下事情:

self.packet_regex = \
            re.compile('(\xaa)([\x04-\xFF]1)([\x00-\xFF]1)([\x10-\xFF]1)([\x00-\xFF]*)([\x00-\xFF]1)(\x44)')

match = self.packet_regex.search(self.buffer)
if match and match.groups():
    groups = match.groups()
    if (ord(groups[1]) - 4) == len(groups[4]) + len(groups[5]) + len(groups[6]):
        ...

【讨论】:

这个方法好像有一些缺陷;例如使用字符串\xAA\x08\xFF\x22\xDA\x44\xEE\xFC\xAB\xAD\x44\xEE - 它返回\xdaD\xee\xfc\xab,即使数据包长度应该是8。也显示其余代码(在最后一个if语句之后)也没有什么坏处。【参考方案2】:

这几乎可以解决您所要求的问题。看看就好了

import re
orig_str = '\xaa\x01\xFF\x44'
print orig_str
#converting original hex data into its representation form
st = repr(orig_str)
print st
#getting the representation form of regex and removing leading and trailing single quotes 
reg = re.compile(repr("(\\xaa)")[1:-1])
p = reg.search(st)

#creating the representation from matched string by adding leading and trailing single quotes
extracted_repr = "\'"+p.group(1)+"\'"
print extracted_repr

#evaluating the matched string to get the original hex information
extracted_str = eval(extracted_repr)
print extracted_str

>>>
    ��D
    '\xaa\x01\xffD'
    '\xaa'
    �

【讨论】:

以上是关于python regex 使用捕获组来定义另一个组长度的主要内容,如果未能解决你的问题,请参考以下文章

Python:使用JSON API链接通过正则表达式显示命名捕获组

Java Regex替换为捕获组

有没有办法让 Regex.Match 只提供预期的捕获组?

从 Grep RegEx 中捕获组

[javascript] 获取正则子表达式里的内容

如何仅获取给定的捕获组 <regex> c++