在Python中处理Windows行结束符
我有一个来自Windows供应商的700MB的XML文件。
正如你所想的,文件中的换行符是'\r\n'(在vi中显示为^M)。除了让供应商发送'\n'格式的文件之外,还有什么更有效的方法来处理这种情况呢?
- 可以使用 os.linesep
- 可以使用 rstrip()(这需要先打开文件……听起来有点疯狂)
- 使用 通用换行符支持 在我的Mac Snow Leopard上并不标准,所以这不是一个选项。
我对任何需要Python 2.6+的方案都持开放态度,但它需要在Snow Leopard和Ubuntu 9.10上运行,并且对外部依赖的要求要尽量少。我不介意稍微牺牲一点性能,但我希望找到处理这个问题的标准最佳方法。
----编辑----
换行符出现在标签描述符的中间,否则它们就不会成为问题。我知道这样不好,他们不应该把这样的文件发给我,但我现在就是拿到这个文件,而供应商大多数时候都很无能。
4 个回答
你是在以文本模式还是二进制模式打开文件呢?我记得在我的Leopard系统上,文本模式可以处理各种换行符,但也许我从别的地方更新了Python...
总之,我见过很多程序员在这方面吃过亏,因为他们总是直接按'b'键。如果你要打开的是在你这个平台上创建的文本文件,就用't',如果你需要处理各种换行符,就用'U'代替't'。
with file(filename, 'rt') as f:
content = f.read()
补充:评论里提到'r't'是默认选项。这说得对,但Python的风格通常更喜欢明确的写法,而不是隐含的,所以我还是选择这样。
为什么DOS的换行符会成为问题呢?其实大多数程序都能很好地处理它们,包括XML解析器。如果你真的想去掉这些换行符,可以用通用换行符
模式打开文件:
open(filename, 'rU')
Python会自动把所有的换行符转换成UNIX格式的换行符。如果你真的不能使用这个功能(我觉得这有点奇怪),那就没有办法让Python来帮你处理了。不过,不管怎样,你还是得打开文件,所以你对第二点的反对意见听起来有点奇怪。
据说:“这个家伙在标签描述符中间有\r\n,像这样:<ParentRedirec tSequenceID>
。”
我在这里没看到\r\n
。也许你是想说repr(xml)里面包含了这样的内容:
"<ParentRedirec\r\ntSequenceID>"
如果不是的话,尽量用准确的方式表达你的意思,并给出示例。
下面的代码应该可以工作:
>>> import re
>>> guff = """<atag>\r\n<bt\r\nag c="2">"""
>>> re.sub(r"(<[^>]*)\r\n([^>]*>)", r"\1\2", guff)
'<atag>\r\n<btag c="2">'
>>>
如果一个标签中有多个换行符,比如<foo\r\nbar\r\nzot>
,这个方法只会修复第一个。其他的解决办法有:(1) 循环直到多余的部分不再缩减 (2) 自己写一个更聪明的正则表达式 :-)