我正在尝试拆分使用新行字符LF
,CRLF
和NEL
混合的文字。我需要最好的方法将NEL
字符排除在场景之外。
是否可以选择指示readlines()
在分割线条时排除NEL?我可能read()
并且只能在循环中匹配LF
和CRLF
分割点。
有没有更好的解决方案?
我使用codecs.open()
打开文件以打开utf-8
文本文件。
使用readlines()
时, 以NEL字符分割:
文件内容为:
"u'Line 1 \\x85 Line 1.1\\r\\nLine 2\\r\\nLine 3\\r\\n'"
答案 0 :(得分:9)
file.readlines()
只会在\n
,\r
或\r\n
上分开,具体取决于操作系统以及是否启用了通用新线支持。
U+0085 NEXT LINE (NEL)在此上下文中未被识别为换行符,您不需要执行任何特殊操作即可file.readlines()
忽略它。
引用open()
function documentation:
Python通常使用通用换行符支持构建;提供
'U'
将文件作为文本文件打开,但行可以通过以下任何一种方式终止:Unix行尾约定'\n'
,Macintosh约定'\r'
或者Windows约定'\r\n'
。所有这些外部表示都被Python程序视为'\n'
。如果在没有通用换行符的情况下构建Python,则'U'
的模式与普通文本模式相同。请注意,如此打开的文件对象也有一个名为newlines的属性,其值为None(如果尚未看到换行符),'\n'
,'\r'
,'\r\n'
或包含元组的元组看到的所有换行类型。
和universal newlines glossary entry:
一种解释文本流的方式,其中所有以下内容都被识别为一行:Unix行尾约定
'\n'
,Windows约定'\r\n'
和旧的Macintosh约定'\r'
。有关其他用途,请参阅PEP 278和PEP 3116以及str.splitlines()
。
不幸的是,codecs.open()
打破这个规则; documentation含糊地暗示了被问到的具体编解码器:
行结尾使用编解码器的解码器方法实现,如果 keepends 为真,则包含在列表条目中。
而不是codecs.open()
,使用io.open()
以正确的编码打开文件,然后逐个处理这些行:
with io.open(filename, encoding=correct_encoding) as f:
lines = f.open()
io
是新的I / O基础架构,完全用Python 3替换Python 2系统。它只处理\n
,\r
和\r\n
:
>>> open('/tmp/test.txt', 'wb').write(u'Line 1 \x85 Line 1.1\r\nLine 2\r\nLine 3\r\n'.encode('utf8'))
>>> import codecs
>>> codecs.open('/tmp/test.txt', encoding='utf8').readlines()
[u'Line 1 \x85', u' Line 1.1\r\n', u'Line 2\r\n', u'Line 3\r\n']
>>> import io
>>> io.open('/tmp/test.txt', encoding='utf8').readlines()
[u'Line 1 \x85 Line 1.1\n', u'Line 2\n', u'Line 3\n']
codecs.open()
结果归因于使用str.splitlines()
的代码,has a documentation bug;在拆分unicode字符串时,它会拆分Unicode标准认为是换行符(quite a complex issue)的任何内容。这种方法的文档没有解释这个;它声称只根据Universal Newline规则进行拆分。