如何将逗号分隔的字符串解析为列表(caveat)?
时间:2020-03-06 14:34:13 来源:igfitidea点击:
我需要能够像这样的字符串:
'''foo, bar, "one, two", three four'''
进入:
['foo', 'bar', 'one, two', 'three four']
我有一种感觉(有#python的提示),该解决方案将涉及shlex模块。
解决方案
我们可能还需要考虑csv模块。我还没有尝试过,但是看起来输入数据更接近CSV而不是Shell语法(这是shlex解析的结果)。
我们可以执行以下操作:
>>> import re >>> pattern = re.compile(r'\s*("[^"]*"|.*?)\s*,') >>> def split(line): ... return [x[1:-1] if x[:1] == x[-1:] == '"' else x ... for x in pattern.findall(line.rstrip(',') + ',')] ... >>> split("foo, bar, baz") ['foo', 'bar', 'baz'] >>> split('foo, bar, baz, "blub blah"') ['foo', 'bar', 'baz', 'blub blah']
如果不需要漂亮,这可能会助我们一臂之力:
def f(s, splitifeven): if splitifeven & 1: return [s] return [x.strip() for x in s.split(",") if x.strip() != ''] ss = 'foo, bar, "one, two", three four' print sum([f(s, sie) for sie, s in enumerate(ss.split('"'))], [])
这取决于我们要获得的复杂程度...是否要允许一种以上类型的报价。转义的报价怎么样?
语法非常类似于通用CSV文件格式,Python标准库支持该格式:
import csv reader = csv.reader(['''foo, bar, "one, two", three four'''], skipinitialspace=True) for r in reader: print r
输出:
['foo', 'bar', 'one, two', 'three four']
HTH!
shlex模块解决方案允许转义的引号,一个引号的另一个转义以及所有花哨的东西外壳程序支持。
>>> import shlex >>> my_splitter = shlex.shlex('''foo, bar, "one, two", three four''', posix=True) >>> my_splitter.whitespace += ',' >>> my_splitter.whitespace_split = True >>> print list(my_splitter) ['foo', 'bar', 'one, two', 'three', 'four']
转义引号示例:
>>> my_splitter = shlex.shlex('''"test, a",'foo,bar",baz',bar \xc3\xa4 baz''', posix=True) >>> my_splitter.whitespace = ',' ; my_splitter.whitespace_split = True >>> print list(my_splitter) ['test, a', 'foo,bar",baz', 'bar \xc3\xa4 baz']
我想说的是正则表达式将是我们在这里寻找的内容,尽管我对Python的Regex引擎并不十分熟悉。
假设我们使用惰性匹配,则可以在字符串上获取一组匹配项,然后将其放入数组中。