在保持 \r\n 不变的情况下替换 \n

Replacing \n while keeping \r\n intact

我有一个巨大的 CSV 文件(196244 行),其中除了新行外还有 \n,我想删除那些 \n 但保持 \r\n 完好无损。 我试过 line.replace 但似乎无法识别 \r\n 所以接下来我尝试了正则表达式

with open(filetoread, "r") as inf:
    with open(filetowrite, "w") as fixed:
        for line in inf:
            line = re.sub("(?<!\r)\n", " ", line)
            fixed.write(line)

但它没有保留 \r\n 它正在删除所有内容。我无法在 Notepad++ 中执行此操作,它在这个文件上崩溃了。

您没有将换行符暴露给正则表达式引擎。此外,当使用 openr 模式时,换行符被“规范化”为 LF,为了将它们全部保留在输入中,您可以使用 [=13= 以二进制模式读取文件].然后,您还需要记住在正则表达式模式和替换中使用 b 前缀。

您可以使用

with open(filetoread, "rb") as inf:
    with open(filetowrite, "wb") as fixed:
        fixed.write(re.sub(b"(?<!\r)\n", b" ", inf.read()))

现在,整个文件将被读入一个字符串(inf.read()),换行符将被匹配,并最终被替换。

关注

  • "rb" 读取
  • 中的文件时
  • "wb" 写出文件
  • re.sub(b"(?<!\r)\n", b" ", inf.read()) 包含带有字符串文字的 b 前缀,inf.read() 将文件内容读入单个变量。

当您使用天真的 open() call, it will load a view of the file with a variety of newlines to be simply \n via TextIOWrapper

打开文件时

明确设置 newline="\r\n" 应该允许您按照预期的方式读写换行符

with open(path_src, newline="\r\n") as fh_src:
    with open(path_dest, "w", newline="\r\n") as fh_dest:
        for line in fh_src:  # file-likes are iterable by-lines
            fh_dest.write(line[:-2].replace("\n", " "))
            fh_dest.write("\r\n")

内容示例

>>> with open("test.data", "wb") as fh:
...     fh.write(b"""foo\nbar\r\nbaz\r\n""")
...
14
>>> with open("test.data", newline="\r\n") as fh:
...     for line in fh:
...         print(repr(line))
...
'foo\nbar\r\n'
'baz\r\n'