2016-04-14 7 views
1

Ich habe eine Binärdatei mit ASCII gemischt, in der es einige Gleitkommazahlen gibt, die ich finden möchte. Die Datei enthält einige Zeilen wie diese:Wie finde ich Gleitkommazahlen in Binärdateien mit Python?

1,1,'11.2','11.3';1,1,'100.4';

In meinem Lieblings Regex Tester fand ich, dass die richtige regex ([0-9]+\.{1}[0-9]+) sein sollte.

Hier ist der Code:

import re 

data = open('C:\\Users\\Me\\file.bin', 'rb') 
pat = re.compile(b'([0-9]+\.{1}[0-9]+)') 
print(pat.match(data.read())) 

ich nicht ein einziges Spiel bekommen, warum ist das so? Ich bin auf Python 3.5.1.

+0

Sind Floats als Zeichenfolgen dargestellt? – Adib

+0

Ja, sie sind ASCII-codiert. – JohnnyFromBF

+1

Was ist eine * Binärdatei mit ASCII * gemischt und wie können Sie die ASCII- und Binärteile identifizieren? Ohne zu wissen, dass ich Ihnen nicht sagen kann, wie Sie die Datei sicher lesen können. BTW, Sie Regex nicht übereinstimmen '1.',' .5', nicht von '1' sprechen (aber für diesen letzten Teil kann es wünschenswert sein, scheitern) –

Antwort

2

Sie können wie diese versuchen,

import re 
with open('C:\\Users\\Me\\file.bin', 'rb') as f: 
    data = f.read() 

re.findall("\d+\.\d+", data) 

Ausgang:

['11.2', '11.3', '100.4'] 

re.findall kehrt string Liste. Wenn Sie konvertieren möchten, schwimmen Sie dies tun können wie

>>> list(map(float, re.findall("\d+\.\d+", data))) 
[11.2, 11.3, 100.4] 
+0

Nicht funktioniert, sagt mir 'TypeError: erwartete Zeichenfolge oder bytes-like Objekt'. Es enthält binäres Zeug. – JohnnyFromBF

+0

@JohnnyFromBF sollten Sie versuchen, 're.findall (" \ d + \. \ D + ", data.read())' –

+0

Ich fürchte, dass es immer noch sagt 'TypeError: kann ein Zeichenfolgenmuster für ein Byte-ähnliches Objekt nicht verwenden '. – JohnnyFromBF

2

How to find floating point numbers in binary file with Python?

float_re = br"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?" 
for m in generate_tokens(r'C:\Users\Me\file.bin', float_re): 
    print(float(m.group())) 

wo float_re is from this answer und generate_tokens() is defined here.


pat.match() versucht ganz am Anfang der Eingabezeichenfolge und die Zeichenfolge nicht starten mit einem Schwimmer entsprechen und Sie deshalb „nicht bekommen, ein einziges Spiel“.


re.findall("\d+\.\d+", data) produziert TypeError, da das Muster Unicode ist (str) aber data ist ein bytes Objekt in Ihrem Fall. Übergeben Sie das Muster als bytes:

+0

Ihr Muster erlaubt ein Leerzeichen nach dem Vorzeichen, was ich für einen Fehler halte. Zum Beispiel ist "- 2.2" keine Fließkommazahl, sondern "-2.2". –

+0

Wenn Sie wirklich pedantisch sein wollen, können Sie die Anzahl der zulässigen Exponentenziffern begrenzen, wenn Sie wüssten, dass dies ein 32- oder 64-Bit Gleitkommawert ist. –

+0

@SteveHollasch Was ein Float ist oder nicht, ist eine Definitionssache. Folgen Sie dem Link, der den Ursprung der Regex erklärt. – jfs

Verwandte Themen