【问题标题】:How can i parse a comma delimited string into a list (caveat)?如何将逗号分隔的字符串解析为列表(警告)?
【发布时间】:2010-09-12 04:44:57
【问题描述】:

我需要能够接受这样的字符串:

'''foo, bar, "one, two", three four'''

进入:

['foo', 'bar', 'one, two', 'three four']

我有一种感觉(来自 #python 的提示)解决方案将涉及 shlex 模块。

【问题讨论】:

    标签: python split escaping quotes


    【解决方案1】:

    这取决于您想要获得的复杂程度...您是否要允许不止一种类型的引用。转义引号怎么样?

    您的语法看起来很像 Python 标准库支持的常见 CSV 文件格式:

    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!

    【讨论】:

    • 是的,csv 模块完全是你想要的。
    • 刚刚测试过,效果很好。比 shlex 模块更直接的语法,所以这得到了我的投票!
    【解决方案2】:

    shlex 模块解决方案允许转义引号、一个引号转义另一个引号以及 shell 支持的所有花哨的东西。

    >>> 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']
    

    【讨论】:

    • 这把三四分开了,规范中没有。
    • 需要修复拆分最后的“三四”。
    • 只需将 my_splitter.whitespace += ',' 更改为 = ',' 即可,但您仍然需要剥离每个元素。
    • 不幸的是 shlex 会忽略空白值。所以 'a,,b' 返回 ['a', 'b'],而不是所需的 ['a', '', 'b']
    • @DRead 是的,你必须引用空字符串,所以 "a,'',b" 会返回你想要的。
    【解决方案3】:

    您可能还想考虑csv 模块。我没试过,但看起来你的输入数据更接近 CSV 而不是 shell 语法(这是 shlex 解析的)。

    【讨论】:

    • 同意。减去封闭的 ''' 部分,看起来很标准的 CSV 格式。 (好吧,在没有 CSV 标准的情况下,尽其所能。)
    • @jdmichal:''' 只是 Python 中引用字符串的一种方式。
    【解决方案4】:

    你可以这样做:

    >>> 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']
    

    【讨论】:

      【解决方案5】:

      我想说正则表达式将是您在此处寻找的内容,尽管我对 Python 的 Regex 引擎并不十分熟悉。

      假设您使用惰性匹配,您可以在一个字符串上获得一组匹配项,您可以将这些匹配项放入您的数组中。

      【讨论】:

        【解决方案6】:

        如果它不需要漂亮,这可能会让你上路:

        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('"'))], [])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-20
          • 1970-01-01
          • 1970-01-01
          • 2023-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-04
          相关资源
          最近更新 更多