使用Python处理\n vs ^M\n换行符

使用Python处理\n vs ^M\n换行符,python,python-3.x,newline,separator,Python,Python 3.x,Newline,Separator,我正在分析一个包含键值对的文件,如下所示: with open(filename) as f: data = f.read() key_value_pairs = data.split(";\n") 然后有一天,交付的文件有一个不同的行终止符,有人将处理它的行更改为: key_value_pairs = data.split(";^M\n") 找到了解释^M是MS-DOS现象的答案 然后声称Windows终止符是\r\n,没有提到^M\n 作为回溯信息,将提到该列表中的每个元

我正在分析一个包含键值对的文件,如下所示:

with open(filename) as f:
    data = f.read()
    key_value_pairs = data.split(";\n")
然后有一天,交付的文件有一个不同的行终止符,有人将处理它的行更改为:

key_value_pairs = data.split(";^M\n")
找到了解释
^M
是MS-DOS现象的答案

然后声称Windows终止符是
\r\n
,没有提到
^M\n

作为回溯信息,将提到该列表中的每个元素
键值对
在另一个循环中使用
.split(“=”,1)

我希望将来的文件在使用或不使用
^M
的情况下都会有不可预测的行终止,并试图找到一种方法来处理它,而不使用混乱的正则表达式或字符串方法(如果可以避免的话)

也许最好的办法就是在开始时将文件中的每一个
^M
都去掉,然后将它们都当作Unix文件处理。但是,对于文件中的某些base64二进制块来说,这可能有点危险


Python中有什么东西可以在文件打开时干净地处理那些
^M

如您的链接所述,
^M
是ASCII字符13,Python应将其理解为
\r

您只需使用
re.split
解析可选的
\r
即可完成此操作:

import re

data = 'split;\ntest;\r\nhere;\nanother;\r\nyay'

key_value_pairs = re.split(r';\r?\n', data)

# ['split', 'test', 'here', 'another', 'yay']
但是,如果它是文字字符
^
M
,请使用
re.split(r'.^M\n |;\n',data)


这里的“交易”是什么意思?删除它们?将它们转换为其他内容?如果您的
open
调用看起来确实是这样,Python应该自动将
\r\n
转换为
\n
。查看
打开
函数的
换行符
参数:使用换行符拆分文件,这些换行符不可预测地包含或不包含
^M
但尚未在文件中看到
\r
,并且看起来不像
^M
谢谢@Krrr,我认为在将
^M
作为
\r
阅读时需要一些帮助。是否可以添加一个与
^M\n
匹配的替代正则表达式(如果存在),而不是
\r\n
?我已经做了一些实验,但无法让它工作。如前所述,我相信字符
^M
在Python中被解读为
\r
,因此这是正确的解析方法。此处的相关答案:-如果它是一个文字字符
^
M
,请使用
re.split(r'.^M\n | \n',data)
,无论是否使用
^M
,这都非常有效。我不知道为什么会有“literal”字符,希望它不会再次出现,但如果是这样,正则表达式似乎能正确处理它。这取决于数据在到达脚本之前经过的位置。某些处理可能已将ASCII字符13转换为文字字符
^M
,而不是原始字符。是的,此处的“某些处理”可能在到达python之前,将向管理它的人员提及。用ssh传输文件时,我肯定会有一点出错。
data = 'split;\ntest;^M\nhere;\nanother;^M\nyay'

key_value_pairs = re.split(r';\^M\n|;\n', data)

# ['split', 'test', 'here', 'another', 'yay']