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
你可能会发现它是"带有CR线路终结器"的游戏.如果您正在使用换行符作为行终止符的平台上工作,它会将您的文件视为一个重要的行.
更改输入文件,以便它使用正确的行终止符.您的编辑器可能比Python实现更宽容.
据我所知,CR行结尾是Mac的东西,你可以使用U模式修饰符open根据找到的第一行终结符自动检测.
| 归档时间: |
|
| 查看次数: |
1841 次 |
| 最近记录: |