2017-05-12 4 views
0

Ich habe eine Datei, die sowohl Hex-Daten als auch Nicht-Hex-Daten enthält. Zum Beispiel var _0x36ba=["\x69\x73\x41\x72\x72\x61\x79","\x63\x61\x6C\x6C","\x74\x6F\x53\x74\x72\x69\x6E\x67",]Hex aus Datei lesen (Python)

Wenn ich diesen Code direkt in Python Konsole einfügen, ich habe var _0x36ba=["isArray","call","toString",]

Aber wenn ich versuche, die Datei und Druckinhalte zu lesen, es gibt mir var _0x36ba=["\\x69\\x73\\x41\\x72\\x72\\x61\\x79","\\x63\\x61\\x6C\\x6C","\\x74\\x6F\\x53\\x74\\x72\\x69\\x6E\\x67","\\

Scheint, wie Schrägstriche sind analysiert wie sie sind.

Wie kann ich die Datei lesen und lesbare Ausgabe erhalten?

+0

Entscheiden Sie sich, was Sie wollen. Willst du die Hex-Sequenzen * interpretieren? e. alle Vorkommen von '\ xnn' wo' n' eine hexadezimale Zahl ist? Das könnte mit einer cleveren Regexp-Substitution geschehen (oder wahrscheinlich mit einer Bibliothek, die genau dies tut). – Alfe

+0

Ja, ich möchte alle \ xnn mit lesbaren ersetzen. Wie kann ich das machen? Nach dem Lesen der Datei wird '\\' zu einem separaten Symbol. –

+0

Verwenden Sie die 'binascii'-Bibliothek von stdlib – OmerBA

Antwort

1

EDIT: Bitte verwenden Sie Martijns Lösung. Ich kannte die text.decode('string_escape') noch nicht, und natürlich ist es viel schneller. Unten folgt meine ursprüngliche Antwort.

Mit diesem regulären Ausdruck alle entkam hexadezimal Ausdrücke innerhalb der Zeichenfolge unescape:

def unescape(text): 
    return re.sub(r'\\\\|\\x([0-9a-fA-F]{2})', 
     lambda m: chr(int(m.group(1), 16)) if m.group(1) 
        else '\\', text) 

Wenn Sie wissen, dass die Eingabe einen doppelten Backslash nicht durch eine x (zB foo bar \\x41 bloh die wahrscheinlich interpretiert werden sollte, gefolgt enthalten wird

def unescape(text): 
    return re.sub(r'\\x([0-9a-fA-F]{2})', 
     lambda m: chr(int(m.group(1), 16)), text) 
+0

Dies ist eine sehr langsame Option, wenn Sie die Escape-Syntax mit einem eingebauten Codec einfach entschlüsseln können. –

+0

Absolut richtig, Martijn. Ich kannte den '.decode ('string_escape')' noch nicht. Aber ich war mehrere Minuten schneller bei der Antwort. Andrew muss viele sehr lange Strings entziffern, indem er meine langsame Lösung verwendet, um diese verlorenen Minuten zu summieren ;-) – Alfe

+1

Der Preis der Antwort beim Pendeln. Schade, wir helfen dem OP nur mit dieser Lösung, oder? ;-) –

2

Sie Literale Zeichenfolge mit: foo bar \x41 bloh statt zu foo bar \A bloh), dann können Sie dies vereinfachen 210 Hex-Fluchten.

string_escape
Produce a string that is suitable as string literal in Python source code

Decodierung kehrt diese Codierung:

>>> "\\x69\\x73\\x41\\x72\\x72\\x61\\x79".decode('string_escape') 
'isArray' 
>>> "\\x63\\x61\\x6C\\x6C".decode('string_escape') 
'call' 
>>> "\\x74\\x6F\\x53\\x74\\x72\\x69\\x6E\\x67".decode('string_escape') 
'toString' 

Als eingebauter Codec

text.decode('string_escape') 

die Python Specific Encodings section der codecs Modul Dokumentation Siehe: Sie können diese mit der string_escape Codierung entschlüsseln , das ist viel schneller als mit regulären Ausdrücken:

>>> from timeit import timeit 
>>> import re 
>>> def unescape(text): 
...  return re.sub(r'\\x([0-9a-fA-F]{2})', 
...   lambda m: chr(int(m.group(1), 16)), text) 
... 
>>> value = "\\x69\\x73\\x41\\x72\\x72\\x61\\x79" 
>>> timeit('unescape(value)', 'from __main__ import unescape, value') 
6.254786968231201 
>>> timeit('value.decode("string_escape")', 'from __main__ import value') 
0.43862390518188477 

Das ist etwa 14 mal schneller.