Python认为3000行文本文件长一行?

AP2*_*257 11 python text newline character-encoding

我有一个非常长的文本文件,我正在尝试使用Python进行处理.

但是,以下代码:

for line in open('textbase.txt', 'r'):
    print 'hello world'
Run Code Online (Sandbox Code Playgroud)

仅产生以下输出:

hello world
Run Code Online (Sandbox Code Playgroud)

就好像Python认为文件只有一行长,虽然在文本编辑器中查看时它长达数千行.使用file命令在命令行上检查它会给出:

$ file textbase.txt
textbase.txt: Big-endian UTF-16 Unicode English text, with CR line terminators
Run Code Online (Sandbox Code Playgroud)

有什么不对吗?我需要更换线路终结器吗?

Jos*_*Lee 25

根据文档open(),你应该添加一个U模式:

open('textbase.txt', 'Ur')
Run Code Online (Sandbox Code Playgroud)

这样可以启用" 通用换行符 ",将它们标准化为\n它给你的字符串.

但是,正确的做法是在翻译换行符之前首先将UTF-16BE解码为Unicode对象.否则,偶然0x0d字节可能会错误地变为a 0x0a,导致

UnicodeDecodeError:'utf16'编解码器无法解码位置12中的字节0x0a:截断数据.

Python的codecs模块提供了一个open可以解码Unicode并同时处理换行的函数:

import codecs
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'):
    ...
Run Code Online (Sandbox Code Playgroud)

如果文件具有字节顺序标记(BOM)并指定'utf-16',则它会检测字节顺序并为您隐藏BOM.如果没有(因为BOM是可选的),那么该解码器将继续使用您的系统的字节序,这可能不会很好.

自己指定endianness(with 'utf-16be')不会隐藏BOM,所以你可能希望使用这个hack:

import codecs
firstline = True
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'):
    if firstline:
        firstline = False
        line = line.lstrip(u'\ufeff')
Run Code Online (Sandbox Code Playgroud)

另请参见:Python Unicode HOWTO


pax*_*blo 6

你可能会发现它是"带有CR线路终结器"的游戏.如果您正在使用换行符作为行终止符的平台上工作,它会将您的文件视为一个重要的行.

更改输入文件,以便它使用正确的行终止符.您的编辑器可能比Python实现更宽容.

据我所知,CR行结尾是Mac的东西,你可以使用U模式修饰符open根据找到的第一行终结符自动检测.