【问题标题】:How do I read / write a file in Python (3) on Windows without introducing carriage returns?如何在不引入回车的情况下在 Windows 上用 Python (3) 读取/写入文件?
【发布时间】:2023-03-28 06:33:02
【问题描述】:

我想在 Windows 上使用 Python 打开一个文件,执行一些正则表达式操作,可选择更改内容,然后将结果写回文件。

我可以创建一个看起来正确的示例文件(基于在 SO 上的其他帖子和文档中使用二进制模式的 cmets)。我看不到的是如何在不引入“\r”字符的情况下将“二进制”数据转换为可用的形式。

一个例子:

import re

# Create an example file which represents the one I'm actually working on (a Jenkins config file if you're interested).
testFileName = 'testFile.txt'
with open(testFileName, 'wb') as output_file:
    output_file.write(b'this\nis\na\ntest')

# Try and read the file in as I would in the script I was trying to write.
content = ""
with open(testFileName, 'rb') as content_file:
    content = content_file.read()

# Do something to the content
exampleRegex = re.compile("a\\ntest")
content = exampleRegex.sub("a\\nworking\\ntest", content) # <-- Fails because it won't operate on 'binary data'

# Write the file back to disk and then realise, frustratingly that something in this process has introduced carriage returns onto every line.
outputFilename = 'output_'+testFileName
with open(outputFilename, 'wb') as output_file:
    output_file.write(content)

【问题讨论】:

  • “不引入回车”是什么意思?它们已经在文件中。我是否正确理解您的要求是将整个文件作为一个连续的字符串(通过摆脱回车)读取,您可以在其上运行正则表达式?所以基本上你的正则表达式可以跨越界限,你不想在你的正则表达式中考虑到这一点,对吧?
  • 我将这个问题解释为“当我打开一个没有 'b' 标志的文件时,有时 '\n' 字符会转换为 '\r\n',这是不可取的。但是当我打开带有 'b' 标志的文件时,我无法使用re.sub。如何在防止自动换行符转换的同时使用sub?"
  • @Paani:如果我在没有'b'选项的情况下打开,Python 会在每一行添加\r。如果我使用二进制选项打开,我将无法执行任何字符串操作,因为他们将其视为二进制数据。
  • 请注意 - 上面的失败行为仅适用于 Python 3 - 我会考虑使用 python-3.x 标记它并在文本中提及 Python 3。

标签: python regex file python-3.x


【解决方案1】:

我想你的意思是,你的文本文件有回车,你不希望它们包含在文本中。

如果你使用 with open(fileName, 'r', encoding="utf-8", errors="ignore", newline="\r\n") as content_file

或者更具体地说,在您的开放调用中设置 newline="\r\n" ,它应该在新行上使用回车。

编辑:或者如果您只想在 \n 上进行操作,那么这个工作示例应该可以做到。

import re

testFileName = 'testFile.txt'
with open(testFileName, 'w', newline='\n') as output_file:
    output_file.write('this\nis\na\ntest')

content = ""
with open(testFileName, 'r', newline='\n') as content_file:
    content = content_file.read()

exampleRegex = re.compile("a\\ntest")
content = exampleRegex.sub("a\\nworking\\ntest", content)

outputFilename = 'output_'+testFileName
with open(outputFilename, 'w', newline='\n') as output_file:
    output_file.write(content)

【讨论】:

  • 不,文件只有 '\n' 行结尾。问题是,如果我在不使用'b' 选项的情况下读/写,Python 会将'\r' 添加到每一行。
  • 如果您在打开文件时明确说明使用的换行符,您的问题就会消失,我认为您不需要使用 'b'。
  • @JonCage 如果为输出文件指定newline="\n" 会怎样?
  • 看来你是对的。实际上,如果您正在读取的文件中没有回车符,则看起来您只需将其添加到输出中即可。
  • 仅在输入文件中添加\r\n 作为换行符是不够的。
【解决方案2】:

如果我正确解释了这个问题,我首先将字节解码为字符串,然后执行正则表达式子。接下来,我将字符串编码为要写入输出文件的字节。

import re

testFileName = 'testFile.txt'
with open(testFileName, 'wb') as output_file:
    output_file.write(b'this\nis\na\ntest')

content = ""
with open(testFileName, 'rb') as content_file:
    content = content_file.read().decode('utf-8')

exampleRegex = re.compile("a\\ntest")
content = exampleRegex.sub("a\\nworking\\ntest", content)

outputFilename = 'output_'+testFileName
with open(outputFilename, 'wb') as output_file:
    output_file.write(content.encode('utf-8'))

【讨论】:

  • 虽然这确实有效,但在输出中指定 '\n' 需要更少的代码。
猜你喜欢
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
相关资源
最近更新 更多