【问题标题】:Regex to convert csv to pipe-separated正则表达式将 csv 转换为管道分隔
【发布时间】:2018-06-12 17:44:58
【问题描述】:

我有以下字符串:

s = "XIDJIJFHD8","Gothika","a0KU000000JMYCrMAP","USA","English","Sub & Audio","VOD","SD","01/01/2011 00:00:00.000000","12/31/2049 00:00:00.000000",,"Confirmed",,,,"Feature",,"2003-11-21","2004-03-23",,"R","for violence, brief language and nudity.","2024863","6000008953",,,"10.5240/A6FC-02AE-8093-3B05-6240-T","10.5240/D052-B470-0D01-25DF-DA91-4","2024863_6000008953","idwb:2024863_6000008953","CA-0000950613"

我需要将其转换为“管道分隔”。字段用引号" 括起来,但如果字段为空,则不会有任何内容。最终输出中| 的数量应该是 31。这是我目前所拥有的:

re.sub(r'(\,|\")(,)(,|\")', '|', s)

但是,上面的长度只有 23。正确的正则表达式是什么?

或者,更好的是,也许我可以直接在 csv 模块中完成。比如:

string_with_pipes = csv.write(s, delimiter="|")

请注意,我只想获取修改后的字符串,而不是实际保存文件。

【问题讨论】:

  • 正则表达式不起作用,因为连续的逗号被一个管道替换。实际上,它们应该用一个管道替换为每个
  • @ruaridhw 对,那该怎么做呢?
  • 在下面查看我的答案 :) 通过在第一组和第三组的开头添加 (? 来对原来的正则表达式进行一个小调整。您也不需要转义,或 " 字符和 | 可以替换为选择的允许字符。(\,|\") 变为 (?[,"])

标签: python regex csv


【解决方案1】:

no need for regular expressions。您可以使用csv.reader()csv.writer() 的组合使用临时缓冲区,我们将使用StringIO

import csv
from StringIO import StringIO


s = '"XIDJIJFHD8","Gothika","a0KU000000JMYCrMAP","USA","English","Sub & Audio","VOD","SD","01/01/2011 00:00:00.000000","12/31/2049 00:00:00.000000",,"Confirmed",,,,"Feature",,"2003-11-21","2004-03-23",,"R","for violence, brief language and nudity.","2024863","6000008953",,,"10.5240/A6FC-02AE-8093-3B05-6240-T","10.5240/D052-B470-0D01-25DF-DA91-4","2024863_6000008953","idwb:2024863_6000008953","CA-0000950613"'

reader = csv.reader([s])

buffer = StringIO()
writer = csv.writer(buffer, delimiter="|")
writer.writerows(reader)

buffer.seek(0)
print(buffer.getvalue())

打印:

XIDJIJFHD8|Gothika|a0KU000000JMYCrMAP|USA|English|Sub & Audio|VOD|SD|01/01/2011 00:00:00.000000|12/31/2049 00:00:00.000000||Confirmed||||Feature||2003-11-21|2004-03-23||R|for violence, brief language and nudity.|2024863|6000008953|||10.5240/A6FC-02AE-8093-3B05-6240-T|10.5240/D052-B470-0D01-25DF-DA91-4|2024863_6000008953|idwb:2024863_6000008953|CA-0000950613

【讨论】:

  • 太好了,我最喜欢这种方法。但是,当我执行writerows 时,我收到一个错误:TypeError: unicode argument expected, got 'str'。有什么想法吗?
  • 貌似不能直接在python2.7中完成——stackoverflow.com/a/13120279/651174。您能否修改您的答案以写入字节?
  • @David542 是的,正在寻找一种兼容 Python 2 和 3 的方式。使用单独的基于“BytesIO”的 Python 2.x 解决方案进行了更新。谢谢。
  • 很酷——如果你只是更改导入语句from StringIO import StringIO,它实际上也可以工作
  • 我在第一个中更新了您的导入语句,现在它适用于 python 2 和 3,所以不需要第二个答案:)
【解决方案2】:

连续的逗号被包含在一个匹配中。

您需要一个不将它们包含在替换本身中但确保它们存在的正则表达式

re.sub(r'(?<=[,"])(,)(?=[,"])', '|', s)

这使用前瞻和后瞻来检查 , 或 " 是否存在而不替换它们。

  1. (,) 匹配逗号
  2. (?&lt;=[,"]) 前面紧跟逗号或双引号
  3. (?=[,"]) 后面紧跟逗号或双引号

第一组和第三组中的(?确保这些组不包含在替换中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 2016-04-02
    相关资源
    最近更新 更多