Pergunta

Eu uso uma ferramenta 3o partido que gera um arquivo no formato Unicode. No entanto, eu prefiro que seja em ASCII. A ferramenta não tem configurações para alterar o formato de arquivo.

Qual é a melhor maneira de converter todo o formato de arquivo usando Python?

Foi útil?

Solução

Você pode converter o arquivo com bastante facilidade apenas usando a função unicode, mas você vai correr em problemas com caracteres Unicode sem um equivalente ASCII em linha reta.

Este blog recomenda o módulo unicodedata , que parece cuidar de aproximadamente converter os caracteres ASCII correspondentes sem valores directos, por exemplo,

>>> title = u"Klüft skräms inför på fédéral électoral große"

é tipicamente convertido em

Klft skrms infr p fdral lectoral groe

que é muito errado. No entanto, utilizando o módulo unicodedata, o resultado pode ser muito mais próximo do texto original:

>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'

Outras dicas

Penso que esta é uma questão mais profunda do que você imagina . Basta mudar o arquivo de Unicode para ASCII é fácil, no entanto, recebendo todos os caracteres Unicode para traduzir em contrapartes ASCII razoáveis ??(muitas cartas não estão disponíveis em ambas as codificações) é outra.

Este tutorial Python Unicode pode lhe dar uma melhor idéia do que acontece com cadeias de caracteres Unicode que são convertidos para ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html

Aqui está uma citação útil a partir do site:

Python 1.6 também recebe um "unicode" built-in função, para a qual você pode especificar a codificação:

> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>

Todos os três destes retornar o mesmo coisa, já que os personagens de 'Olá' são comuns a todas as três codificações.

Agora vamos codificar algo com um sotaque europeu, que está fora de ASCII. O que você vê em um console pode depender do seu sistema operacional localidade; Windows permite que me digitar ISO-Latin-1.

> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'

Se você não pode digitar uma letra aguda e, você pode digitar o string 'Andr \ 202', que é inequívoca.

Unicode suporta todos os comum operações tais como iteração e divisão. Não vamos passar por cima deles aqui.

A propósito, estes é uma iconv comando linux para fazer este tipo de trabalho.

iconv -f utf8 -t ascii <input.txt >output.txt

Aqui está um código simples (e estúpido) para fazer codificação de tradução. Estou assumindo (mas você não deve) que o arquivo de entrada é em UTF-16 (Windows chama isso simplesmente 'Unicode').

input_codec = 'UTF-16'
output_codec = 'ASCII'

unicode_file = open('filename')
unicode_data = unicode_file.read().decode(input_codec)
ascii_file = open('new filename', 'w')
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec)))

Note que isso não vai funcionar se houver quaisquer caracteres no arquivo Unicode que não são também caracteres ASCII. '?' Você pode fazer o seguinte para transformar caracteres não reconhecidos em s:

ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))

Confira os docs para escolhas mais simples. Se você precisa fazer algo mais sofisticado, talvez você queira dar uma olhada no O UNICODE Martelo em o Cookbook Python.

Como esta:

uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')

Note, no entanto, que esta vontade falha com uma exceção UnicodeDecodeError se existem quaisquer caracteres que não podem ser convertidos para ASCII.

EDIT: Como Pete Karl fora apenas pontas, não existe um mapeamento um-para-um de Unicode para ASCII. Assim, alguns personagens simplesmente não pode ser convertido em uma forma de preservação da informação. Além disso, ASCII padrão é mais ou menos um subconjunto de UTF-8, então você realmente não precisa mesmo de fazer qualquer decodificação.

Para o meu problema onde eu só queria ignorar os caracteres não-ASCII e saída apenas somente de saída ascii, o abaixo solução funcionou muito bem:

    import unicodedata
    input = open(filename).read().decode('UTF-16')
    output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')

É importante notar que não existe um formato de arquivo 'Unicode'. Unicode podem ser codificados para bytes de várias maneiras diferentes. Mais comumente UTF-8 ou UTF-16. Você precisa saber qual é a sua ferramenta de 3-parte é saída. Depois de saber que, a conversão entre diferentes codificações é muito fácil:

in_file = open("myfile.txt", "rb")
out_file = open("mynewfile.txt", "wb")

in_byte_string = in_file.read()
unicode_string = bytestring.decode('UTF-16')
out_byte_string = unicode_string.encode('ASCII')

out_file.write(out_byte_string)
out_file.close()

Como observado nas outras respostas, você provavelmente vai querer fornecer um manipulador de erro com o método de codificação. Usando 'substituir' como o manipulador de erro é simples, mas vai mangle seu texto se ele contém caracteres que não podem ser representados em ASCII.

Como outras pôsteres, ASCII é um subconjunto do unicode.

No entanto, se você:

  • tem um aplicativo legado
  • você não controlar o código para esse aplicativo
  • você está certo de sua entrada cai na ASCII subconjunto

Em seguida, o exemplo abaixo mostra como fazê-lo:

mystring = u'bar'
type(mystring)
    <type 'unicode'>

myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
    <type 'str'>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top