Pregunta

Tengo un archivo en UTF-8, donde algunas líneas contienen el carácter de separador de línea U+2028 (http://www.fileformat.info/info/unicode/char/2028/index.htm). No quiero que sea tratado como un descanso de línea cuando leo líneas del archivo. ¿Hay alguna forma de excluirlo de los separadores cuando itero sobre el archivo o uso readlines ()? (Además de leer todo el archivo en una cadena y luego dividirse por n.) ¡Gracias!

¿Fue útil?

Solución

No puedo duplicar este comportamiento en Python 2.5, 2.6 o 3.0 en Mac OS X - U+2028 siempre se trata como no endline. ¿Podría entrar en más detalles sobre dónde ves este error?

Dicho esto, aquí hay una subclase de la clase de "archivo" que podría hacer lo que quieras:

#/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")

Otros consejos

No pude reproducir ese comportamiento, pero aquí hay una solución ingenua que solo fusiona los resultados de lectura hasta que no terminan con 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

Gracias a todos por responder. Creo que sé por qué no hayas podido replicar esto. Me di cuenta de que sucede si decodeo el archivo al abrir, como en:

f = codecs.open(filename, encoding='utf-8')
for line in f:
    print line

Las líneas no están separadas en U2028, si abro el archivo primero y luego decodifique las líneas individuales:

f = open(filename)
for line in f:
    print line.decode("utf8")

(Estoy usando Python 2.6 en Windows. El archivo fue originalmente UTF16LE y luego se convirtió en UTF8).

Esto es muy interesante, supongo que no usaré códecs. Abra mucho de ahora en adelante :-).

Si usa Python 3.0 (tenga en cuenta que no lo hago, así que no puedo probar), de acuerdo con el documentación puedes pasar un opcional newline parámetro open para especificar qué seperator de línea usar. Sin embargo, la documentación no menciona U+2028 en absoluto (solo se menciona \r, \n, y \r\n Como separadores de línea), por lo que en realidad es una sorpresa para mí que esto ocurre (aunque puedo confirmar esto incluso con Python 2.6).

El módulo de códecs está haciendo lo correcto. U+2028 se denomina "separador de línea" con el comentario "puede usarse para representar esta semántica inequívocamente". Por lo tanto, tratarlo como un separador de línea es sensato.

Presumiblemente, el Creador no habría puesto los caracteres U+2028 allí sin una buena razón ... ¿El archivo también tiene " n"? ¿Por qué quieres que las líneas no se dividan en U+2028?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top