首页 > 解决方案 > 使用 Python 处理 \n vs ^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

作为背景信息,将提到该列表中的每个元素key_value_pairs在另一个循环中进一步拆分.split("=", 1)

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

也许最好的选择是^M在开始时去掉文件中的所有内容,然后将它们全部视为 Unix 文件。但是,对于文件中的某些 base64 二进制块,这可能有点危险。

^MPython中有什么东西可以在文件打开时干净地处理这些问题吗?

标签: pythonpython-3.xnewlineseparator

解决方案


正如您提到的链接,^M是 ASCII 字符 13,它应该被\rPython 读取。

你可以简单地通过解析一个可选\r的来完成这个re.split

import re

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

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

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

但是,如果它是文字字符^and M,请使用re.split(r';\^M\n|;\n', data)

data = 'split;\ntest;^M\nhere;\nanother;^M\nyay'

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

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

推荐阅读