我很好奇是否有一种更容易实现的方法,我并不熟悉。假设这是在网络环境中,我希望从响应中提取值。这些值是用管道分隔的几个数值,例如| 103 | 28 | 48 | 12 | 47 | 54 |。我现在正在使用它。
rep_pipe = e_traffic.replace("|", "||")
extract_value = re.findall(r'\|([0-9]{2,3})\|', rep_pipe)
如果只有一个值,那么它的效果绝对正常。它仅与此字符串的单个实例一起正常工作的原因是因为在这些管道之间找到的每个值都附加到列表中。然而,当响应中存在多个这些字符串时,它们全部附加到同一列表中,现在可以将它们彼此区分开。
假设我们有以下(十进制)值:
|101|102|103|110|111|
|94|81|48|32|103|120|
目前看来,这将出现在[' 101',' 102',' 103',' 110',& #39; 111',' 94',' 81',..' 120']
有没有办法让这些首先转换为十六进制,然后保存为以下内容:
['6566676E6F', '5E5130206778']
可能需要注意的是,这些值会出现在不同长度的不同偏移处,这让我觉得有点困难。对此的任何帮助将不胜感激。
答案 0 :(得分:1)
如果您有一个单字符分隔符(此处为|
)并且想要处理所有这样编码的数据,则不需要使用正则表达式匹配来查找它。相反,只需使用.split()
方法将字符串拆分为分隔符。
如果您有多行文字数据并希望单独处理这些行,请使用.splitlines()
方法获取这些数据。
所以我们有
lines = e_traffic.splitlines()
data = [line.split('|') for line in lines]
data
现在将是一个嵌套的字符串列表:
[['', '101', '102', '103', '110', '111', ''], ['', '94', '81', '48', '32', '103', '120', '']]
您可以使用int()
函数将数字序列(仍为字符串)转换为整数:
int_data = [[int(s) for s in line if s] for line in data]
(内部列表理解的if s
部分删除每行上前导和后退|
的空字符串。)
这为int_data
:
[[101, 102, 103, 110, 111], [94, 81, 48, 32, 103, 120]]
整数序列可以使用bytes()
函数转换为二进制数据:
bin_data = [bytes(seq) for seq in int_data]
最后,可以使用.hex()
类型的bytes
方法将二进制数据转换为十六进制表示形式(再次使用字符串):
hex_values = [b.hex() for b in bin_data]
我们现在有一个hex_values
中的字符串列表:
['6566676e6f', '5e5130206778']
hex_values = [
bytes(
int(n) for n in l.split('|') if n
).hex() for l in e_traffic.splitlines()
]
或者使用函数式的内部迭代:
hex_values = [
bytes(
map(int, filter(None, l.split('|')))
).hex() for l in e_traffic.splitlines()
]
答案 1 :(得分:0)
您可以使用int
函数将整数的字符串表示形式转换为整数。
您可以直接将一个小整数序列视为bytes
值,然后对其进行六重化,或者您也可以使用'02X'
然后join
格式化每个小整数
您可以首先使用finditer
而不是findall
对匹配项进行迭代,但我不知道在这里购买了多少。
把所有这些放在一起:
extract_value = re.finditer(r'\|([0-9]{2,3})\|', rep_pipe)
buf = bytes(map(int, extract_value))
print(buf.hex())
但这只能解决你问题的一半。看起来您希望将每一行作为单独的字符串处理,但您在整个输入中使用正则表达式。虽然你可以使正则表达式和后处理更复杂以处理它,但它可能更容易一次排成一行:
for line in rep_pipe:
extract_value = re.findall(r'\|([0-9]{2,3})\|', line)
buf = bytes(map(int, extract_value))
print(buf.hex())