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')
这编译没有错误,但它不起作用。我怀疑它不起作用,因为正则表达式引擎无法将 <length>
命名组十六进制值转换为适当的整数,以便在正则表达式 表达式中使用。有没有一种方法可以在 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 使用捕获组来定义另一个组长度的主要内容,如果未能解决你的问题,请参考以下文章