2010-11-02 166 views
3

我有一个包含这样的十六进制字符的浮点值的字符串:解压字符串以十六进制

"\\64\\2e\\9b\\38" 

我想提取浮动,但为了做到这一点我必须使Python看到字符串作为4个十六进制字符,而不是16个常规字符。首先我想更换正斜杠,但我得到了一个错误:

>>>> hexstring.replace("\\", "\x") 
ValueError: invalid \x escape 

我发现

struct.unpack("f", "\x64\x2e\x9b\x38") 

不正是我想要的,但我怎么转换字符串?

回答

6

每当我看到(畸形)的字符串,此字符列表,如一个组成:

['\\', '\\', '6', '4', '\\', '\\', '2', 'e', '\\', '\\', '9', 'b', '\\', '\\', '3', '8'] 

当意图是什么是字符名单

['\x64', '\x2e', '\x9b', '\x38'] 

我端起decode('string_escape')方法。

但是要使用它,我们需要用r'\x'替换r'\\'这两个字符。 您可以使用replace(...)方法。

In [37]: hexstring=r'\\64\\2e\\9b\\38' 

In [38]: struct.unpack('f',(hexstring.replace(r'\\',r'\x').decode('string_escape'))) 
Out[38]: (7.3996168794110417e-05,) 

In [39]: struct.unpack("f", "\x64\x2e\x9b\x38") 
Out[39]: (7.3996168794110417e-05,) 

PS。这种decode方法的使用在Python2中起作用,但在Python3中不起作用。在Python3中,codecs.decode仅用于将字节对象转换为字符串对象(err,Python2称为unicode对象),而在上例中,decode实际上是将字符串对象转换为字符串对象。 Python2中的大多数解码器都会将字符串对象转换为unicode对象,但有些像'string_escape'则不会。一般而言,它们已被移至其他模块,或以其他方式调用。

在Python3中,相当于hexstring.decode('string_encode')的是codecs.escape_decode(hexstring)[0]

编辑:另一种方法,在精神上jsbueno的答案相似,就是用binascii.unhexlify

In [76]: import binascii 
In [81]: hexstring=r"\\64\\2e\\9b\\38" 
In [82]: hexstring.replace('\\','') 
Out[82]: '642e9b38' 

In [83]: binascii.unhexlify(hexstring.replace('\\','')) 
Out[83]: 'd.\x9b8' 

这些timeit结果表明binascii.unhexlify是最快的:

In [84]: %timeit binascii.unhexlify(hexstring.replace('\\','')) 
1000000 loops, best of 3: 1.42 us per loop 

In [85]: %timeit hexstring.replace('\\','').decode('hex_codec') 
100000 loops, best of 3: 2.94 us per loop 

In [86]: %timeit hexstring.replace(r'\\',r'\x').decode('string_escape') 
100000 loops, best of 3: 2.13 us per loop 

编辑,每个评论:

This answer contains raw strings. The Department of Public Health advises that eating raw or undercooked strings poses a health risk to everyone, but especially to the elderly, young children under age 4, pregnant women and other highly susceptible individuals with compromised immune systems. Thorough cooking of raw strings reduces the risk of illness.

+1

您应该强调这里的技巧涉及原始字符串。 – detly 2010-11-02 15:17:06

+0

@detly:我很抱歉,但我不明白。虽然我使用原始字符串以方便表示法,但这个技巧并不依赖于表示法。我可以在不使用任何原始字符串的情况下重写代码片段。 – unutbu 2010-11-02 15:37:15

+0

@detly:哦......也许你的意思是说,当我用'r'开始时,OP说''\\ 64 \\ 2e \\ 9b \\ 38'''\\ 64 \\ 2e \\ 9b \\ 38 “'。我猜测这个OP真的意味着'r'\\ 64 \\ 2e \\ 9b \\ 38“',因为在后面的文中他提到它是16个字符长,而len(”\\ 64 \ \ 2e \\ 9b \\ 38“)'只有12. – unutbu 2010-11-02 15:41:30

0

更短的路要走ehr e,就是摆脱“\”字符,并使python使用“hex_codec”将每两个十六进制数字看作一个字节:

struct.unpack("f", "\\64\\2e\\9b\\38".replace("\\", "\").decode("hex_codec"))