编辑:我应该注意,我想要任何十六进制数组的一般情况,而不仅仅是我提供的谷歌数据。
编辑背景:背景是网络:我正在解析DNS数据包并尝试获取其QNAME。我将整个数据包作为字符串接收,每个字符代表一个字节。显然这个问题看起来像一个Pascal字符串问题,并且使用struct模块似乎是要走的路。
我在Python 2.7中有一个包含八进制值的char数组。例如,假设我有一个数组
DNS = "\03www\06google\03com\0"
我想得到:
这是一种有效的方法吗?我的第一个想法是迭代DNS char数组并将chars添加到我的新数组答案。每当我看到'\'字符时,我会忽略它后面的'\'和两个字符。有没有办法在不使用新阵列的情况下获得结果www.google.com?
我恶心的实现(我的回答是一系列字符,这不是我想要的,我只想要字符串www.google.com:
DNS = "\\03www\\06google\\03com\\0"
answer = []
i = 0
while i < len(DNS):
if DNS[i] == '\\' and DNS[i+1] != 0:
i += 3
elif DNS[i] == '\\' and DNS[i+1] == 0:
break
else:
answer.append(DNS[i])
i += 1
答案 0 :(得分:2)
既然你已经解释了你的真实问题,那么到目前为止你得到的答案都不会有效。为什么?因为它们可以从字符串中删除\03
之类的序列。但是你没有像<{1}}这样的 序列,你有单个控制字符。
当然,你可以做类似的事情,只需用点替换任何控制字符。
但是你真正尝试做的事情并不是用点替换控制字符,而是解析DNS数据包。
DNS由RFC 1035定义。 DNS数据包中的QNAME是:
表示为标签序列的域名,其中每个标签由长度八位字节后跟该八位字节数组成。域名以根的空标签的零长度八位字节终止。注意,该字段可以是奇数个八位字节;没有使用填充。
所以,让我们解析一下。如果你理解“由长度八位字节组成的标签后跟那个八位字节的数字”与“Pascal字符串”有什么关系,那就更快了。另外,你可以写得更干净,更简洁地作为一个发生器。但是,让我们这样做死的简单方法:
\03
答案 1 :(得分:1)
import re
DNS = "\\03www\\06google\\03com\\0"
m = re.sub("\\\\([0-9,a-f]){2}", "", DNS)
print(m)
答案 2 :(得分:1)
也许是这样的?
#!/usr/bin/python3
import re
def convert(adorned_hostname):
result1 = re.sub(r'^\\03', '', adorned_hostname )
result2 = re.sub(r'\\0[36]', '.', result1)
result3 = re.sub(r'\\0$', '', result2)
return result3
def main():
adorned_hostname = r"\03www\06google\03com\0"
expected_result = 'www.google.com'
actual_result = convert(adorned_hostname)
print(actual_result, expected_result)
assert actual_result == expected_result
main()
答案 3 :(得分:1)
对于最初提出的问题,用点代替"\\03www\\06google\\03com\\0"
等字符串中的反斜杠 - 十六进制序列......
如果您想使用正则表达式执行此操作:
\\
匹配反斜杠。[0-9A-Fa-f]
匹配任何十六进制数字。[0-9A-Fa-f]+
匹配一个或多个十六进制数字。\\[0-9A-Fa-f]+
匹配反斜杠后跟一个或多个十六进制数字。你想找到每个这样的序列,并用点替换它,对吗?如果查看re
文档,您将找到一个名为sub
的函数,该函数用于替换带有替换字符串的模式:
re.sub(r'\\[0-9A-Fa-f]+', '.', DNS)
我怀疑这些可能实际上是八进制,而不是十六进制,在这种情况下你需要[0-7]
而不是[0-9A-Fa-f]
,但没有其他任何东西会改变。
另一种方法是识别这些是有效的Python转义序列。并且,如果我们将它们转移到它们来自的位置(例如,使用DNS.decode('string_escape')
),则会变成一系列长度前缀(也称为“Pascal”)字符串,这是一种可以在任何数字中解析的标准格式方法,包括stdlib struct
模块。这样做的好处是可以在读取数据时验证数据,并且不会被任何可能出现的误报所抛弃,例如,如果其中一个字符串组件在其中间有反斜杠。
当然,这更多地假定数据。似乎很可能这个的真正含义是“一系列长度为前缀的字符串,连接,然后反斜杠转义”,在这种情况下你应该解析它。但它可能只是看起来像是巧合,在这种情况下,解析它是一个非常糟糕的主意。