【问题标题】:Split by comma and how to exclude comma from quotes in split用逗号分割以及如何从分割的引号中排除逗号
【发布时间】:2022-03-18 01:30:58
【问题描述】:

蟒蛇2.7代码

cStr = \"aaaa\",\"bbbb\",\"ccc,ddd\"\' 
newStr = cStr.split(\',\')
print newStr  # -> [\"aaaa\"\',\"bbbb\"\',\"ccc\',\'ddd\"\' ]

但是,我想要这个结果。

result = [\"aaa\"\',\"bbb\"\',\"ccc,ddd\"\'] 
  • 为什么不拆分 \" 然后删除所有大小为 1 的结果?
  • 你不能用 \'\\\",\\\"\' 分割吗?然后如果您仍然想要引号,请在之后添加它们。

标签: python split


【解决方案1】:

使用re.split()函数的解决方案:

import re

cStr = '"aaaa","bbbb","ccc,ddd"'
newStr = re.split(r',(?=")', cStr)

print newStr

输出:

['"aaaa"', '"bbbb"', '"ccc,ddd"']

,(?=") - 前瞻肯定断言,确保分隔符 , 后跟双引号 "

【讨论】:

  • cha(10)后面跟“aaa”时如何拆分()?
  • @JongpyoJeon,这是什么意思" 下一个 chr(10) 拆分?
  • alist = '"aaa","bbb","ccc,ddd" chr(10) "a-1","b-1","c-1"' "ccc,ddd" 之间有 chr (10)和“a-1”我想要...结果= [[“aaa”,“bbb”,“ccc,ddd”],[“a-1”,“b-1”,“c-1... ..chr(10)xxx "] ]
【解决方案2】:

尝试使用 CSV。

import csv
cStr = '"aaaa","bbbb","ccc,ddd"'
newStr = [ '"{}"'.format(x) for x in list(csv.reader([cStr], delimiter=',', quotechar='"'))[0] ]

print newStr

检查Python parse CSV ignoring comma with double-quotes

【讨论】:

  • 我建议使用“next(csv.reader([cStr]))”而不是“list(csv.reader([cStr]))[0]”。
【解决方案3】:

pyparsing 有一个内置表达式,commaSeparatedList

cStr = '"aaaa","bbbb","ccc,ddd"' 
import pyparsing as pp
print(pp.commaSeparatedList.parseString(cStr).asList())

印刷:

['"aaaa"', '"bbbb"', '"ccc,ddd"']

您还可以添加解析时操作来去除这些双引号(因为您可能只想要内容,而不是引号):

csv_line = pp.commaSeparatedList.copy().addParseAction(pp.tokenMap(lambda s: s.strip('"')))
print(csv_line.parseString(cStr).asList())

给出:

['aaaa', 'bbbb', 'ccc,ddd']

【讨论】:

  • 对于几年后阅读本文的任何人,commaSeparatedList 已被弃用,取而代之的是common.comma_separated_list
【解决方案4】:

通过使用正则表达式试试这个:

COMMA_MATCHER = re.compile(r",(?=(?:[^\"']*[\"'][^\"']*[\"'])*[^\"']*$)")
split_result = COMMA_MATCHER.split(string)

【讨论】:

    【解决方案5】:

    在这种情况下使用正则表达式会更好。 re.findall('".*?"', cStr) 准确返回您需要的内容

    星号是贪心通配符,如果你使用'".*"',它将返回最大匹配,即第一个和最后一个双引号之间的所有内容。问号使其不贪心,因此'".*?"' 返回可能的最小匹配。

    【讨论】:

      【解决方案6】:

      尽可能使用现有库总是更好,但我一直在努力让我的特定用例与上述所有答案一起工作,所以我为 python 3.9 编写了自己的库(可能会工作到 3.6,并删除类型提示将使您获得 2.x 兼容性)。

      def separate(string) -> List[str]:
          """
          Split a comma separated string into a List of strings.
      
          Resulting list elements are trimmed of double quotes.
          Comma's inside double quotes are ignored.
      
          :param string: A string to be split into chunks
          :return: A list of strings, one element for every chunk
          """
          comma_separated_list: List[str] = []
      
          chunk: str = ''
          in_quotes: bool = False
      
          for character in string:
              if character == ',' and not in_quotes:
                  comma_separated_list.append(chunk)
                  chunk = ''
      
              elif character == '"':
                  in_quotes = False if in_quotes else True
      
              else:
                  chunk += character
      
          comma_separated_list.append(chunk)
          return comma_separated_list
      
      

      而且测试...

      def test_separator():
          string = '"aaaa","bbbb","ccc,ddd"' 
      
          expected = ['"aaaa"', '"bbbb"', '"ccc,ddd"']
          actual = separate(string)
      
          assert expected == actual
      

      【讨论】:

      • 断言失败,因为在实际结果中没有引号,而在预期的数组中 - 不是
      【解决方案7】:

      我喜欢Mark de Haan' 解决方案,但我不得不重新设计它,因为它删除了引号字符(尽管它们是必需的),因此他的示例中的断言失败了。我还添加了两个额外的参数来处理不同的分隔符和引号字符。

      def tokenize( string, separator = ',', quote = '"' ):
          """
          Split a comma separated string into a List of strings.
      
          Separator characters inside the quotes are ignored.
      
          :param string: A string to be split into chunks
          :param separator: A separator character
          :param quote: A character to define beginning and end of the quoted string
          :return: A list of strings, one element for every chunk
          """
          comma_separated_list = []
      
          chunk = ''
          in_quotes = False
      
          for character in string:
              if character == separator and not in_quotes:
                  comma_separated_list.append(chunk)
                  chunk = ''
      
              else:
                  chunk += character
                  if character == quote:
                      in_quotes = False if in_quotes else True
      
          comma_separated_list.append( chunk )
      
          return comma_separated_list
      

      而且测试...

      def test_tokenizer():
          string = '"aaaa","bbbb","ccc,ddd"' 
      
          expected = ['"aaaa"', '"bbbb"', '"ccc,ddd"']
          actual = tokenize(string)
      
          assert expected == actual
      

      【讨论】:

      • 这是最好的解决方案(它对我有用),没有使用任何库,所有代码都在那里,可以根据我们的需要进行更好的控制。
      【解决方案8】:

      你可以先将字符串用"分割,然后过滤掉''',',最后格式化,这可能是最简单的方法:

      ['"%s"' % s for s in cStr.split('"') if s and s != ',']
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      • 如果使用 split,则可以按字符串而不是单个字符进行拆分:cStr[1:-1].split('","')
      【解决方案9】:

      你需要一个解析器。您可以构建自己的,或者您可以将其中一个图书馆投入使用。在这种情况下,json 可以(ab)使用。

      import json
      
      cStr = '"aaaa","bbbb","ccc,ddd"' 
      jstr = '[' + cStr + ']'
      result = json.loads( jstr)             # ['aaaa', 'bbbb', 'ccc,ddd']
      result = [ '"'+r+'"' for r in result ] # ['"aaaa"', '"bbbb"', '"ccc,ddd"']
      

      【讨论】:

        【解决方案10】:

        这不是标准模块,您必须通过 pip 安装它,但作为选项尝试 tssplit:

        In [3]: from tssplit import tssplit
        In [4]: tssplit('"aaaa","bbbb","ccc,ddd"', quote='"', delimiter=',')                                                            
        Out[4]: ['aaaa', 'bbbb', 'ccc,ddd']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-08-21
          • 2012-05-23
          • 2017-04-07
          • 2013-04-02
          • 2021-10-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多