Como excluir o U+2028 dos separadores de linha em Python ao ler o arquivo?
Pergunta
Eu tenho um arquivo em UTF-8, onde algumas linhas contêm o caractere separador de linha U+2028 (http://www.fileformat.info/info/unicode/char/2028/index.htm).Não quero que seja tratado como uma quebra de linha quando leio as linhas do arquivo.Existe uma maneira de excluí-lo dos separadores quando eu iterar no arquivo ou usar readlines ()?(Além de ler o arquivo inteiro em uma string e depois dividir por .) Obrigado!
Solução
Não posso duplicar esse comportamento no Python 2.5, 2.6 ou 3,0 no Mac OS X - U+2028 é sempre tratado como linha não endividada. Você poderia entrar em mais detalhes sobre onde você vê esse erro?
Dito isto, aqui está uma subclasse da classe "arquivo" que pode fazer o que você deseja:
#/usr/bin/python
# -*- coding: utf-8 -*-
class MyFile (file):
def __init__(self, *arg, **kwarg):
file.__init__(self, *arg, **kwarg)
self.EOF = False
def next(self, catchEOF = False):
if self.EOF:
raise StopIteration("End of file")
try:
nextLine= file.next(self)
except StopIteration:
self.EOF = True
if not catchEOF:
raise
return ""
if nextLine.decode("utf8")[-1] == u'\u2028':
return nextLine+self.next(catchEOF = True)
else:
return nextLine
A = MyFile("someUnicode.txt")
for line in A:
print line.strip("\n").decode("utf8")
Outras dicas
Eu não pude reproduzir esse comportamento, mas aqui está uma solução ingênua que apenas mescla os resultados da linha de leitura até que eles não terminem com o U+2028.
#!/usr/bin/env python
from __future__ import with_statement
def my_readlines(f):
buf = u""
for line in f.readlines():
uline = line.decode('utf8')
buf += uline
if uline[-1] != u'\u2028':
yield buf
buf = u""
if buf:
yield buf
with open("in.txt", "rb") as fin:
for l in my_readlines(fin):
print l
Obrigado a todos por responder. Acho que sei por que você pode não ter conseguido replicar isso. Acabei de perceber que isso acontece se eu decodificar o arquivo ao abrir, como em:
f = codecs.open(filename, encoding='utf-8')
for line in f:
print line
As linhas não estão separadas no U2028, se eu abrir o arquivo primeiro e depois decodificar linhas individuais:
f = open(filename)
for line in f:
print line.decode("utf8")
(Estou usando o Python 2.6 no Windows. O arquivo era originalmente UTF16LE e depois foi convertido em UTF8).
Isso é muito interessante, acho que não vou usar o codec. aberto a partir de agora :-).
Se você usa o Python 3.0 (observe que não, então não posso testar), de acordo com o documentação você pode passar um opcional newline
parâmetro para open
Para especificar qual seperator de linha usar. No entanto, a documentação não menciona u+2028 (apenas menciona \r
, \n
, e \r\n
Como seperadores de linha), então é realmente uma surpresa para mim que isso ocorre até (embora eu possa confirmar isso mesmo com o Python 2.6).
O módulo de codecs está fazendo a coisa CERTA.U+2028 é denominado "LINE SEPARATOR" com o comentário "pode ser usado para representar esta semântica de forma inequívoca".Portanto, tratá-lo como um separador de linhas é sensato.
Presumivelmente, o criador não teria colocado os caracteres U+2028 lá sem um bom motivo...o arquivo tem você" " também?Por que você quer que as linhas não sejam divididas no U+2028?