Python认为3000行的文本文件只有一行长?
我有一个很长的文本文件,我正试图用Python处理它 但是,以下代码:Python认为3000行的文本文件只有一行长?,python,text,character-encoding,newline,Python,Text,Character Encoding,Newline,我有一个很长的文本文件,我正试图用Python处理它 但是,以下代码: for line in open('textbase.txt', 'r'): print 'hello world' 仅生成以下输出: hello world 这就好像Python认为文件只有一行长,尽管在文本编辑器中查看时有数千行长。使用文件命令在命令行上检查它,可以得到: $ file textbase.txt textbase.txt: Big-endian UTF-16 Unicode English t
for line in open('textbase.txt', 'r'):
print 'hello world'
仅生成以下输出:
hello world
这就好像Python认为文件只有一行长,尽管在文本编辑器中查看时有数千行长。使用文件命令在命令行上检查它,可以得到:
$ file textbase.txt
textbase.txt: Big-endian UTF-16 Unicode English text, with CR line terminators
有什么不对劲吗?我需要更换线路终结者吗?你可能会发现,正是“使用CR线路终结者”让游戏脱颖而出。如果你在一个使用换行符作为行终止符的平台上工作,它会将你的文件视为一个大行 更改输入文件,使其使用正确的行终止符。编辑器可能比Python实现更宽容 据我所知,CR行结束符是Mac的东西,您可以使用
U
模式修饰符open
根据找到的第一行终止符自动检测。open()
返回文件对象。您需要使用:
for line in open('textbase.txt', 'r').readlines():
print line
根据,您应该在模式中添加一个U
:
open('textbase.txt', 'Ur')
这将启用“”,它将它们规范化为它提供给您的字符串中的\n
然而,正确的做法是首先将UTF-16BE解码为Unicode对象,然后再转换换行符。否则,0x0d
字节可能会被错误地转换为0x0a
,从而导致
UnicodeDecodeError:“utf16”编解码器无法解码位置12:截断数据中的字节0x0a
Python提供了一个open
函数,可以同时解码Unicode和处理换行符:
import codecs
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'):
...
如果文件有一个字节顺序标记(BOM),并且您指定了“utf-16”
,则它会检测尾数并为您隐藏BOM。如果没有(因为BOM是可选的),那么解码器将继续使用系统的endianness,这可能不太好
自己指定尾数(使用“utf-16be”
)不会隐藏BOM,因此您可能希望使用以下方法:
import codecs
firstline = True
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'):
if firstline:
firstline = False
line = line.lstrip(u'\ufeff')
另请参见:您的文件似乎只有以CR结尾的行,Python可能期望使用LF或CRLF。尝试使用“通用换行符”:
for line in open('textbase.txt', 'rU'):
print 'hello world'
这是不必要的,因为打开的文件对象的行为类似于迭代器。
Nail+head
combome+1.谢谢。你知道我需要把它们改成什么吗?可以是CR+LF(Windows)或LF(但这会在旧Mac上)。@Adriano:CR是旧Mac的线路终止符。所有的尼克斯系统都是如此。@TZOOTZIOY:我不该犯那个错误。棕色纸袋时间。@OP,textbase.txt来自哪里?窗户?尝试对该文件执行dos2unix,并查看它是否解决了问题problem@jldupont:我认为AP257希望它为输入文件的每一行打印“hello world”,就像代码所说的:-)这是一个for循环,对于一个有很多行的文件:)请参见:+1以了解解决方案,而不仅仅是分析(如我的回答中所示)-你对我来说太快了:-)解决了这个问题,python现在可以看到所有的行。非常感谢:我喜欢这个网站:)@AP257:它们也能正确解码吗?如果它真的是UTF-16BE,那么每一行前面都会有零字节,因为Python的文件对象不知道编码,只是在换行符上拆分。IMHO,您必须(通过使用编解码器模块)正确解码文件,然后才能拆分成行。@Torsten因为我们使用的是big-endian,所以空值在换行之前,所以代码点不会被切成两半。然而,这是一个很好的观点@杰里德夫:对,我的错。我在实验中混淆了测试文件。