Python 如何使用十六进制值生成正确的正则表达式?

Python 如何使用十六进制值生成正确的正则表达式?,python,Python,我关注的是带有正则表达式的数据。我正在使用python并实现此函数: import re exp = r"\bTimestamp\s+([0-9]+)\s+ID=(\w{32})0*\s+Dest_ID=(\w{32})0*\sASN_Received\s+(?!0000)[0-9A-F]{4}+" rx = re.compile(exp) m=rx.match("Timestamp 1549035123 ID=02141592cc0000000300000000000000 Dest_ID=

我关注的是带有正则表达式的数据。我正在使用python并实现此函数:

import re
exp = r"\bTimestamp\s+([0-9]+)\s+ID=(\w{32})0*\s+Dest_ID=(\w{32})0*\sASN_Received\s+(?!0000)[0-9A-F]{4}+"
rx = re.compile(exp)
m=rx.match("Timestamp 1549035123  ID=02141592cc0000000300000000000000 Dest_ID=00000000000000000000000000000000 Nbr_Received = ec30000000")
m.groups()
print(m.groups())
但它不能正常工作:

我希望得到这样的结果:

('1549033267', '02141592cc0000000500000000000000','00000000000000000000000000000000','ec30000000')
然后我想使用此函数将十六进制值转换为十进制:

def Convert_Decimal(nbr_hex):
nbr_dec = nbr_hex[5] + nbr_hex[2:4] + nbr_hex[0:2]
reversed = int(nbr_dec, 16)
print(reversed)
最后,我想要:

('1549033267', '02141592cc0000000500000000000000','00000000000000000000000000000000','12524')
试试这个:

>>> import re
>>> string = "Timestamp 1549035123  ID=02141592cc0000000300000000000000 Dest_ID=00000000000000000000000000000000 Nbr_Received = ec30000000"
>>> pat = r'Timestamp\s+(\d+)\s+ID=(\w+)\s+Dest_ID=(\d+)\s+Nbr_Received\s+?=\s+?(\w+)'
>>> re.findall(pat, string)
[('1549035123', '02141592cc0000000300000000000000', '00000000000000000000000000000000', 'ec30000000')]

十六进制值仅使用数字0-9和字母A到F(大写或小写),并且在您的情况下为固定长度,因此
[0-9a-fA-F]{32}
足以匹配这些值。当具有固定长度值时,不需要匹配尾随零

您真的不想在这里使用
\w
,您不想匹配下划线、英语字母表的其余部分或Unicode标准中的任何其他类似字母的符号(有数千个)

接下来,您要查找
ASN_Received
,但您的输入字符串使用文本
Nbr_Received=
,在
=
字符周围有空格。因此:

exp = (
    r'\bTimestamp\s+([0-9]+)\s+'
    r'ID=([0-9a-fA-F]{32})\s+'
    r'Dest_ID=([0-9a-fA-F]{32})\s+'
    r'Nbr_Received\s*=\s*([0-9a-fA-F]{4,})'
)
为了更容易理解,我将表达式分成了多行。请注意,我对最后一个十六进制值使用了
{4,}
,匹配4个或更多数字。不能同时使用
+
{n,m}
模式,请选择其中一种

然后你会得到:

>>> import re
>>> exp = (
...     r'\bTimestamp\s+([0-9]+)\s+'
...     r'ID=([0-9a-fA-F]{32})\s+'
...     r'Dest_ID=([0-9a-fA-F]{32})\s+'
...     r'Nbr_Received\s*=\s*([0-9a-fA-F]{4,})'
... )
>>> rx = re.compile(exp)
>>> m = rx.match("Timestamp 1549035123  ID=02141592cc0000000300000000000000 Dest_ID=00000000000000000000000000000000 Nbr_Received = ec30000000")
>>> print(m.groups())
('1549035123', '02141592cc0000000300000000000000', '00000000000000000000000000000000', 'ec30000000')
另请参见,它解释了右侧图案的每个部分

我将通过和将最后一个十六进制数转换为整数:

>>> m.group(4)
'ec30000000'
>>> bytes.fromhex(m.group(4))
b'\xec0\x00\x00\x00'
>>> int.from_bytes(bytes.fromhex(m.group(4)), 'little')
12524

您的
exp
值当前会产生一个
re。错误:在位置95处多次重复出现
异常。为什么负数后面会查找收到的
Nbr\u
编号,为什么不使用正确的
字节。作为int()
struct()
为该值解包,要控制字节顺序,您真的应该包括一个解释,说明OP为什么应该尝试此操作。您的模式匹配的不仅仅是十六进制数字,
\w
实在太宽了。实际上不需要
\s+
括号中的非贪婪分类器,因为它们后面总是跟有非空格字符。这些模式不会消失。你也没有回答问题的十六进制到小数部分,好的。这种模式似乎很稳定。