使用标准库中的csv和io模块,您可以非常接近所需内容:
-
使用csv对分隔符进行正确编码并处理引用规则;它只写入文件句柄
-
对该文件句柄使用io.StringIO,以字符串形式获取结果CSV
import csv
import io
f = io.StringIO()
text = ("John", '"n"', '"ABC 123\nDEF, 456GH\nijKl"\r\n', '"Johny\nIs\nHere"')
writer = csv.writer(f)
writer.writerow(text)
csv_str = f.getvalue()
csv_repr = repr(csv_str)
print("CSV_STR")
print("=======")
print(csv_str)
print("CSV_REPR")
print("========")
print(csv_repr)
并打印:
CSV_STR
=======
John,"""n""","""ABC 123
DEF, 456GH
ijKl""
","""Johny
Is
Here"""
CSV_REPR
========
'John,"""n""","""ABC 123\nDEF, 456GH\nijKl""\r\n","""Johny\nIs\nHere"""\r\n'
-
csv_str
如果你直接向打开的文件写入,你会在文件中看到什么,它是
真正的CSV
-
csv_repr
是你向我们展示时所要求的
out
,但不完全是。您的示例包括“双重转义”换行符
\\n
和回车
\\r\\n
.CSV不再需要转义这些字符,因为整个字段都被引用了。如果你需要,你需要自己动手,比如:
csv_repr.replace(r"\r", r"\\r").replace(r"\n", r"\\n")
但同样,这对于有效的CSV来说是不必要的。
此外,我不知道如何让作者包含
初始空间
在第一个字段之后的每个字段之前,就像您在“John”和“n”之间以及在“n”之后显示的空格一样:
out = 'John, """n""", ...'
读取器可以配置为预期和忽略初始空间
Dialect.skipinitialspace
,但我看不出这位作家有什么选择。