2010-11-02 164 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"))