3

我有一个 UTF-8 文件,其中一些行包含 U+2028 行分隔符字符(http://www.fileformat.info/info/unicode/char/2028/index.htm)。当我从文件中读取行时,我不希望它被视为换行符。当我遍历文件或使用 readlines() 时,有没有办法将它从分隔符中排除?(除了将整个文件读入一个字符串,然后用 \n 分割。)谢谢!

4

5 回答 5

2

我无法重现这种行为,但这是一个简单的解决方案,它只是合并 readline 结果,直到它们不以 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
于 2009-07-09T18:04:17.133 回答
2

我无法在 mac os x 上的 python 2.5、2.6 或 3.0 中复制此行为 - U+2028 始终被视为非结束行。您能否更详细地了解您在哪里看到此错误?

也就是说,这是“文件”类的一个子类,它可能会做你想做的事:

#/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")
于 2009-07-09T21:04:52.197 回答
1

感谢大家的回答。我想我知道为什么您可能无法复制它。我刚刚意识到,如果我在打开文件时解码文件,就会发生这种情况,如下所示:

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

如果我先打开文件然后解码各个行,则这些行在 u2028 上没有分隔:

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

(我在 Windows 上使用 Python 2.6。该文件最初是 UTF16LE,然后被转换为 UTF8)。

这很有趣,我想从现在开始我不会使用 codecs.open 了:-)。

于 2009-07-09T22:24:58.387 回答
0

如果您使用 Python 3.0(请注意,我没有,所以我无法测试),根据文档,您可以传递一个可选newline参数来open指定要使用的行分隔符。但是,文档根本没有提到 U+2028(它只提到\r,\n\r\n作为行分隔符),所以这甚至发生对我来说实际上是一个惊喜(尽管我可以用 Python 2.6 确认这一点)。

于 2009-07-09T17:03:54.493 回答
0

编解码器模块正在做正确的事情。U+2028 被命名为“LINE SEPARATOR”,并带有注释“可用于明确表示此语义”。因此将其视为行分隔符是明智的。

大概创建者不会没有充分的理由将 U+2028 个字符放在那里……文件也有 u"\n" 吗?为什么你不希望在 U+2028 上分割行?

于 2009-07-10T01:15:31.583 回答