代码之家  ›  专栏  ›  技术社区  ›  aeiou

将带引号的元组转换为类似csv的字符串

  •  0
  • aeiou  · 技术社区  · 3 年前

    如何转换元组

    text = ('John', '"n"', '"ABC 123\nDEF, 456GH\nijKl"\r\n', '"Johny\nIs\nHere"')
    

    转换为csv格式

    out = '"John", """n""", """ABC 123\\nDEF, 456\\nijKL\\r\\n""", """Johny\\nIs\\nHere"""'
    

    甚至省略了末尾的特殊字符

    out = '"John", """n""", """ABC 123\\nDEF, 456\\nijKL""", """Johny\\nIs\\nHere"""'
    

    我想出了这个怪物

    out1 = ','.join(f'""{t}""' if t.startswith('"') and t.endswith('"')
                               else f'"{t}"' for t in text)
    out2 = out1.replace('\n', '\\n').replace('\r', '\\r')
    
    0 回复  |  直到 3 年前
        1
  •  1
  •   Zach Young mo1010    3 年前

    使用标准库中的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 ,但我看不出这位作家有什么选择。