gpt4 book ai didi

python - 以逗号分隔的条件正则表达式

转载 作者:太空宇宙 更新时间:2023-11-04 05:41:59 26 4
gpt4 key购买 nike

我在 python 中拆分一个字符串,我的目标是用逗号拆分,除了引号之间的逗号。我正在使用

fields = line.strip().split(",")

但有些字符串像下面这样:

10,20,"Installations, machines",3,5

如何使用正则表达式来完成此操作?

最佳答案

虽然我同意正则表达式可能不是完成这项工作的最佳工具,但我发现这个问题本身很有趣。

import re
split_on_commas = re.compile(r'[^,]*".*"[^,]*|[^,]+|(?<=,)|^(?=,)').findall

此正则表达式按顺序由四个可选部分组成:

  1. 任意数量的非逗号,后跟用双引号括起来的子字符串,再跟任意数量的非逗号;
  2. 至少一个非逗号;
  3. 逗号后的空子串;
  4. 字符串开头的空子字符串,后跟一个逗号。

一些测试:

assert split_on_commas('10,20,"aaa, bbb",3,5') == ['10', '20', '"aaa, bbb"', '3', '5']
assert split_on_commas('10,,20,"aaa, bbb",3,5') == ['10', '', '20', '"aaa, bbb"', '3', '5']
assert split_on_commas('10,,,20,"aaa, bbb",3,5') == ['10', '', '', '20', '"aaa, bbb"', '3', '5']
assert split_on_commas(',10,20,"aaa, bbb",3,5') == ['', '10', '20', '"aaa, bbb"', '3', '5']
assert split_on_commas('10,20,"aaa, bbb",3,5,') == ['10', '20', '"aaa, bbb"', '3', '5', '']
assert split_on_commas('10,20,"aaa, bbb" ccc,3,5') == ['10', '20', '"aaa, bbb" ccc', '3', '5']
assert split_on_commas('10,20,ccc "aaa, bbb",3,5') == ['10', '20', 'ccc "aaa, bbb"', '3', '5']
assert split_on_commas('10,20,"aaa, bbb" "ccc",3,5,') == ['10', '20', '"aaa, bbb" "ccc"', '3', '5', '']
assert split_on_commas('10,20,"aaa, bbb" "ccc, ddd",3,5,') == ['10', '20', '"aaa, bbb" "ccc, ddd"', '3', '5', '']
assert split_on_commas('10,20,"aaa, "bbb",3,5') == ['10', '20', '"aaa, "bbb"', '3', '5']
assert split_on_commas('10,20,"",3,5') == ['10', '20', '""', '3', '5']
assert split_on_commas('10,20,",",3,5') == ['10', '20', '","', '3', '5']
assert split_on_commas(',,,') == ['', '', '', '']
assert split_on_commas('') == []
assert split_on_commas(',') == ['', '']
assert split_on_commas('","') == ['","']
assert split_on_commas('",') == ['"', '']
assert split_on_commas(',"') == ['', '"']
assert split_on_commas('"') == ['"']

更新:与csv模块方案比较

类似的问题已在 SO 上被问过很多次,每次最佳/接受的答案都是“只需使用 csv 模块”。也许指出推荐的解决方案和我的 re 提议之间的一些差异是有用的。但首先,设计一个与split接口(interface)相同的csv函数(不是惯用的,但符合原始要求):

import csv
split_on_commas = lambda s: csv.reader([s]).next()

首先要注意的是,csv.reader 的作用不仅仅是智能拆分。外部定界符被抑制​​:

assert split_on_commas('10,20,"aaa, bbb",3,5') == ['10', '20', 'aaa, bbb', '3', '5']

这会导致一些奇怪的行为:

assert split_on_commas('10,20,"aaa, bbb" ccc,3,5') == ['10', '20', 'aaa, bbb ccc', '3', '5']
assert split_on_commas('10,20,aaa", bbb ccc",3,5') == ['10', '20', 'aaa"', ' bbb ccc"', '3', '5']

我确信这不是生成的 CSV 的问题,因为违规的双引号会被转义。

更令人震惊的是this module still does not support Unicode :

split_on_commas(u'10,20,"Juan, Chô",3,5')

---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
<ipython-input-83-a0ef82b5fc26> in <module>()
----> 1 split_on_commas(u'10,20,"Juan, Chô",3,5')

<ipython-input-81-18a2b4070348> in <lambda>(s)
1 if __name__ == "__main__":
2 import csv
----> 3 split_on_commas = lambda s: csv.reader([s]).next()
4
5 assert split_on_commas('10,20,"aaa, bbb",3,5') == ['10', '20', 'aaa, bbb', '3', '5']

UnicodeEncodeError: 'ascii' codec can't encode character u'\xf4' in position 15: ordinal not in range(128)

但是当然还有第三个区别:我的解决方案没有经过彻底测试,不能保证在我没有想到的情况下工作......现在,既然这个方法似乎有几个真实的用例(例如,非 TSV 文件,非 ASCII 输入),如果一些正则表达式大师不仅没有将其视为危险,而且可以帮助找出它,我会很高兴限制和改进。

关于python - 以逗号分隔的条件正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33631502/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com