2009-11-06 17 views
5

Nel tentativo di sistemare un file PML (Palm Markup Language), sembra che il mio file di prova abbia caratteri non ASCII che sta causando il rifiuto di MakeBook. La soluzione sarebbe quella di eliminare tutti i caratteri non ASCII nel PML.Come rimuovere estesi ascii usando python?

Quindi, nel tentativo di risolvere questo problema in python, ho

import unicodedata, fileinput 

for line in fileinput.input(): 
    print unicodedata.normalize('NFKD', line).encode('ascii','ignore') 

Tuttavia, questo si traduce in un errore che la linea deve essere "unicode, non str". Ecco un frammento di file.

\B1a\B \tintense, disordered and often destructive rage†.†.†.\t 

Non proprio sicuro come passare correttamente la linea in essere elaborato a questo punto.

+0

Vuoi filtrare qualsiasi carattere il cui valore ASCII è maggiore di 255? –

+0

Strettamente parlando, non esiste una cosa come ASCII estesa. ASCII definisce valori da 0 a 127. Qualsiasi valore superiore a quello può essere interpretato solo arbitrariamente. Forse dovresti usare il termine * caratteri non ASCII *. – dreamlax

+0

Correlati: Funzione di escape sicura per l'output del terminale http://stackoverflow.com/questions/437476/safe-escape-function-for-terminal-output – jfs

risposta

0

Durante la lettura da un file in Python si ottengono stringhe di byte, ovvero "str" ​​in Python 2.xe versioni precedenti. È necessario convertirli nel tipo "unicode" utilizzando il metodo decode. es .:

line = line.decode('latin1') 

Sostituire "latin1" con la codifica corretta.

5

Prova print line.decode('iso-8859-1').encode('ascii', 'ignore') - che dovrebbe essere molto più vicino a quello che vuoi.

+0

Questo sembra funzionare anche se MakeBook si sta ora lamentando dei codici di controllo illegali. –

+0

@Jauder, puoi ovviamente rimuovere anche i codici di controllo, ad esempio dopo 'clean = ''.join (c per c in line if ord (c)> = 32) '(rimuove TUTTI i codici di controllo incluso newline e carriage return - aggiusta a piacere, non possiamo davvero farlo per te senza sapere quali codici di controllo vuoi rimuovere!-). –

+0

@Alex, se lo sapessi, vorrei =). Il problema è che sto lavorando con un solo programma Java senza fonte disponibile che emette solo un messaggio di errore criptico. http://gist.github.com/227882 –

5

Vorreste per trattare line come dati ASCII con codifica, quindi la risposta è di decodificare in testo usando il codec ascii:

line.decode('ascii')

Ciò consentirà di aumentare gli errori per i dati che non è in realtà ASCII-encoded. Ecco come ignorare questi errori:

line.decode('ascii', 'ignore').

Fornisce il testo sotto forma di istanza unicode. Se si preferisce lavorare con dati (ASCII-encoded), piuttosto che di testo, è possibile ricodificarlo per tornare un'istanza str o bytes (a seconda della versione di Python):

line.decode('ascii', 'ignore').encode('ascii')

2

Per escludere i caratteri non ASCII utilizzano line.decode(your_file_encoding).encode('ascii', 'ignore'). Ma probabilmente è meglio utilizzare PLM sequenze di escape per loro:

import re 

def escape_unicode(m): 
    return '\\U%04x' % ord(m.group()) 

non_ascii = re.compile(u'[\x80-\uFFFF]', re.U) 

line = u'\\B1a\\B \\tintense, disordered and often destructive rage\u2020.\u2020.\u2020.\\t' 
print non_ascii.sub(escape_unicode, line) 

Questo uscite \B1a\B \tintense, disordered and often destructive rage\U2020.\U2020.\U2020.\t.

Dropping caratteri non-ASCII e controllo con l'espressione regolare è troppo facile (questo può essere utilizzato in modo sicuro dopo la fuga):

regexp = re.compile('[^\x09\x0A\x0D\x20-\x7F]') 
regexp.sub('', line) 
Problemi correlati