2016-12-07 3 views
0

Ich habe vor kurzem ein Skript geschrieben, um alle Lesezeichen aus einer PDF-Datei zu extrahieren und sie in einer docx-Datei zu speichern. Es funktioniert für 90% der Dateien, aber leider gibt es einige, die Probleme mit Unicode haben.Python entfernen ungültige ASCII-Zeichen

ich die Lesezeichen in einer Liste wie folgt aus:

[[u'3. Mechatronik f\xfcr Doppelkupplungsgetriebe, Sicherungshalter B, Sicherung 14 auf Sicherungshalter C', 2], 
[u'4. Geber f\xfcr Getriebeeingangsdrehzahl, Hydraulikdruckgeber 1 f\xfcr automatisches Getriebe, Magnetventil 2, Magnetventil \x04, Magnetventil 5', 2], 
[u'5. W\xe4hlhebel, Schalter f\xfcr W\xe4hlhebel in P gesperrt, Magnet f\xfcr W\xe4hlhebelsperre', 2], 
[u'6. W\xe4hlhebel, Geber 2 f\xfcr Antriebswellendrehzahl, W\xe4hlhebel-Positionsanzeige', 2]] 

Wenn ich versuche, die Funktion i den Fehler zu laufen:

ValueError('All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters',) 

Code:

from docx import Document 

list1 = [[u'3. Mechatronik f\xfcr Doppelkupplungsgetriebe, Sicherungshalter B, Sicherung 14 auf Sicherungshalter C', 2], 
    [u'4. Geber f\xfcr Getriebeeingangsdrehzahl, Hydraulikdruckgeber 1 f\xfcr automatisches Getriebe, Magnetventil 2, Magnetventil \x04, Magnetventil 5', 2], 
    [u'5. W\xe4hlhebel, Schalter f\xfcr W\xe4hlhebel in P gesperrt, Magnet f\xfcr W\xe4hlhebelsperre', 2], 
    [u'6. W\xe4hlhebel, Geber 2 f\xfcr Antriebswellendrehzahl, W\xe4hlhebel-Positionsanzeige', 2]] 

def save_docx(list1): 
document = Document('default.docx') 
file = open("Error_Log.txt", 'w') 
for i in list1: 
    try: 
     p = document.add_paragraph() 
     p.add_run(i[0]).bold = True 
    except Exception as e: 
     file.write(repr(e) + '\n') 
file.close() 
document.save('Bookmarks.docx') 

save_docx(list1) 

Im Das Problem zu erraten ist die \x0 aber ich kann nicht herausfinden, wie man Teile wie diese entfernt, ohne das ganze d zu ruinieren Okument. Ich habe verschiedene Codierungen und alles andere versucht, das ich online finden konnte, aber nichts hat so weit gearbeitet.

Jede Hilfe wäre sehr willkommen!

+0

haben Sie das versucht? 'i [0] .encode ('utf-8')' basierend auf der Diskussion in http://stackoverflow.com/questions/5760936/handle-wrongly-encoded-character-in-python-unicode-string –

+0

ja ich versucht, auf verschiedene Arten zu de- und encodieren 'i [0] .encode ('ascii' 'ignore')' usw. hat nicht funktioniert. Habe mir auch Bibliotheken angeschaut, die helfen könnten, bisher aber kein Glück. – TacashiX

+0

nette Antwort von @jackmorris. Könnte es sein, dass nach der Kodierung das Kontrollzeichen noch in der Zeichenfolge war? Das Endergebnis wäre also das gleiche (Fehler 'keine Steuerzeichen') –

Antwort

0

Ihre Annahme scheint korrekt zu sein: \x04 ist ein Steuerzeichen, und Ihre Fehlermeldung besagt explizit, dass Steuerelemente nicht zulässig sind.

Sie können Steuerzeichen aus Ihren Zeichenfolgen herausfiltern, bevor Sie sie zum Dokument hinzufügen, was Ihr Problem beheben sollte. Dies kann mit Pythons unicodedata module, speziell unicodedata.category getan werden. Die Kategorien, die Sie ausschließen möchten, beginnen mit "C" (von http://www.unicode.org/reports/tr44/#GC_Values_Table), die alle Steuerzeichen umfasst.

Die folgende Beschreibung ist, anstelle der aktuellen add_run Linie arbeiten:

line = filter(lambda c: unicodedata.category(c)[0] != 'C', i[0]) 
p.add_run(line).bold = True 

Als beiseite, ist die typische Art und Weise Unicode-Zeichen in einem Unicode-String von einschließlich ist mit \ uXXXX, anstatt \ xXX (wo XXXX ist das Hex des Unicode-Codepunkts).

+0

Die von UnicodeData für '\ x04' zurückgegebene Kategorie ist' Cc', nicht 'C'. Und ich würde nicht sagen, dass die '\ uXXXX'-Notation die" typische "Art ist, es gibt keinen Unterschied zwischen' \ xXX', '\ u00XX' und' \ U000000XX' für einen Codepunkt unter 256 und Python selbst immer verwendet die kürzest mögliche Form, zB 'ascii (" \ U000000FF ")' (oder 'repr (u" \ U000000FF ")' in python2) gibt '\ xff'. – mata

+0

Die Kategorie 'C' enthält 'Cc', sowie 'Cf', welches ein Formatkontrollzeichen ist. –

+0

Zum anderen Punkt ist "typisch" wahrscheinlich das falsche Wort, aber ich denke, es macht mehr Sinn, Unicode-Zeichen als Codepunkte anstelle von Bytewerten anzugeben, besonders wenn Sie 256 überschreiten. Sie haben Recht damit macht keinen Unterschied für niedrigwertige Codepunkte. –

Verwandte Themen