在python中使用特定逗号拆分,但不在引号内

在python中使用特定逗号拆分,但不在引号内,python,split,Python,Split,我有这个字符串,我想用“,”分开它 这是我真正的绳子 x = 'Outward ,Supply , ,Tax Invoice ,IN9195212470,31/12/2019,VPS AGRO & AUTO PVT LTD ,311954,06AAACV9344F1ZA ,"VILLAGE KHANPUR KOLIAN, N.H. 1 ",6 K.M. FRO,KURUKSHETRA ,HARYANA ,136131,VPS AGRO & AUTO PVT LTD ,31

我有这个字符串,我想用“,”分开它

这是我真正的绳子

x = 'Outward   ,Supply , ,Tax Invoice ,IN9195212470,31/12/2019,VPS AGRO & AUTO PVT LTD ,311954,06AAACV9344F1ZA ,"VILLAGE KHANPUR KOLIAN, N.H. 1 ",6 K.M. FRO,KURUKSHETRA   ,HARYANA ,136131,VPS AGRO & AUTO PVT LTD ,311954,"VILLAGE KHANPUR KOLIAN, N.H. 1",6 K.M. FRO,KURUKSHETRA                             ,HARYANA             ,136131,503675,SM VAL. GENUINE DIESEL ENG. OIL 1/9 L   ,27101980,360,LTR,58204.04,9,5238.36,9,5238.36,0,0,0,0,0,0,0,68680.76,                    ,                    ,                              ,          ,          ,,               ,          ,06AAACW0287A1ZR   ,VALVOLINE CUMMINS PVT LTD-AMBALA        ,"KHASHRA NO-108/1/2,                                         ",          ,AMBALA                                  ,133004,HARYANA             ,                    ,                  ,                              , ,'
它返回这个结果

['a','b','c','d','"x','x','2', 'hi']
但是我想要这个

['a', 'b', 'c' , 'd' , '"x,x,2"' , 'hi']
如何在python中实现这一点


帮帮我吧

如果不进行大量的前/后处理数据的黑客攻击,没有任何内置程序可以实现这一点

  • shlex.split
    在一定程度上适用于此示例,但它是欺骗,因为它在空格上拆分。如果两个元素仅用逗号进行比较,则此操作将失败
  • ast.literal\u eval
    无法工作,因为。。。有些项目不是文字
  • csv.reader
    object几乎用
    [x.strip()表示下一个(csv.reader([x])]中的x]
    实现了这个技巧,但是引号没有得到正确处理,因为引号和逗号之间有空格
但通过一个简单的状态机循环遍历每个字符,这可以做到:

x = 'a, b, c , d , "x,x,2" , hi'

in_quote = False
current = []
output = []
for c in x:
    if in_quote:
        current.append(c)
        if c=='"':
            output.append("".join(current))
            current = []
            in_quote = False
        continue

    if c==",":
        output.append("".join(current))
        current = []
    elif c==" ":
        pass
    else:
        current.append(c)
        if c=='"':
            in_quote = True

output.append("".join(current))
结果:

['a', 'b', 'c', 'd', '"x,x,2"', '', 'hi']
只需跳过空格,遇到逗号时创建新元素,但遇到引号时有一个标志


最后,不要忘记遇到字符串结尾时累积的最后一个元素。

仅使用
拆分的解决方案。请注意,它使用f字符串(Python3.6+),但在旧版本中仍然可以实现相同的行为。
不使用正则表达式就可以实现这一点,如下所示:我将对代码进行注释以进行解释:

# First split by double quote
x = x.split('"')
final_x = []
for i in range(len(x)):
    # We know that if the list element is even then it must be outside double quotes
    if i%2 == 0:
        # Split the list by commas and strip any whitespace
        x_element = x[i].split(',')
        x_element = [el.strip() for el in x_element]
        # extend the list
        final_x.extend(x_element)
    else:
        # This is an odd element of the list, therefore inside quotation.
        # put the string back into quotations
        x_element = f'"{x[i]}"'
        #append this to the final list
        final_x.append(x_element)
# filter out any white spaces left from the various splits         
final_x = [el for el in final_x if el !=''] 
请注意附加奇数列表元素和扩展偶数列表元素的区别。这是因为您正在使用拆分创建一个新列表,我们希望扩展输出,而对于奇数元素,我们希望向列表中添加一个新元素,因此我们附加。

import shlex
lexer=shlex.shlex('a,b,c,d,“x,x,2”,hi')
lexer.whitespace+=','
打印(列表(lexer))
结果:

['a', 'b', 'c', 'd', '"x,x,2"', 'hi']
['Outward', 'Supply', '', 'Tax Invoice', 'IN9195212470', '31/12/2019', 'VPS AGRO & AUTO PVT LTD', '311954', '06AAACV9344F1ZA', '"VILLAGE KHANPUR KOLIAN, N.H. 1 "', '6 K.M. FRO', 'KURUKSHETRA', 'HARYANA', '136131', 'VPS AGRO & AUTO PVT LTD', '311954', '"VILLAGE KHANPUR KOLIAN, N.H. 1"', '6 K.M. FRO', 'KURUKSHETRA', 'HARYANA', '136131', '503675', 'SM VAL. GENUINE DIESEL ENG. OIL 1/9 L', '27101980', '360', 'LTR', '58204.04', '9', '5238.36', '9', '5238.36', '0', '0', '0', '0', '0', '0', '0', '68680.76', '', '', '', '', '', '', '', '06AAACW0287A1ZR', 'VALVOLINE CUMMINS PVT LTD-AMBALA', '"KHASHRA NO-108/1/2,                                         "', '', 'AMBALA', '133004', 'HARYANA', '', '', '', '']
以下是更新任务的更新解决方案:


x=出口、供应、税务发票,IN9195212470,2019年12月31日,VPS农业和汽车私人有限公司,311954,06AAACV9344F1ZA,“KHANPUR KOLIAN村,新罕布什尔州1号”,6 K.M.FRO,KURUKSHETRA,HARYANA,136131,VPS农业和汽车私人有限公司,311954,“KHANPUR KOLIAN村,新罕布什尔州1号”,6 K.M.FRO,KURUKSHETRA,HARYANA,136131503675,SM VAL.原装柴油发动机机油1/9升,27101980360,LTR,58204.04,95238.36,95238.36,0,0,0,0,0,0,068680.76,06AAACW0287A1ZR,VALVOLINE-CUMMINS PVT LTD-AMBALA,“第108/1/2号KHASHRA,”,安巴拉,133004,哈里亚纳邦
导入shlex
lexer=shlex.shlex(x)
lexer.whitespace=','
lexer.whitespace\u split=True
打印([cell.strip()用于lexer中的单元格])
结果:

['a', 'b', 'c', 'd', '"x,x,2"', 'hi']
['Outward', 'Supply', '', 'Tax Invoice', 'IN9195212470', '31/12/2019', 'VPS AGRO & AUTO PVT LTD', '311954', '06AAACV9344F1ZA', '"VILLAGE KHANPUR KOLIAN, N.H. 1 "', '6 K.M. FRO', 'KURUKSHETRA', 'HARYANA', '136131', 'VPS AGRO & AUTO PVT LTD', '311954', '"VILLAGE KHANPUR KOLIAN, N.H. 1"', '6 K.M. FRO', 'KURUKSHETRA', 'HARYANA', '136131', '503675', 'SM VAL. GENUINE DIESEL ENG. OIL 1/9 L', '27101980', '360', 'LTR', '58204.04', '9', '5238.36', '9', '5238.36', '0', '0', '0', '0', '0', '0', '0', '68680.76', '', '', '', '', '', '', '', '06AAACW0287A1ZR', 'VALVOLINE CUMMINS PVT LTD-AMBALA', '"KHASHRA NO-108/1/2,                                         "', '', 'AMBALA', '133004', 'HARYANA', '', '', '', '']

您可以使用正则表达式方法:

import regex as re

x = 'a, b, c , d , "x,x,2" , hi'

rx = re.compile(
    r"""
    "[^"]*"(*SKIP)(*FAIL)
    |
    \s*,\s*
    """, re.VERBOSE)
lst = rx.split(x)
print(lst)
这就产生了

['a', 'b', 'c', 'd', '"x,x,2"', 'hi']

很好的解决方案,它有点迂腐,但可能会添加一个最后的
条带
,因此它会提供所需的输出。@B.C:谢谢你发现它。最好在表达式中编译它,尽管在两侧都添加了
\s*
。大约55个条目将以dict形式出现,但它有99个条目。请检查我的问题“x”“contain real string您会收到一个错误,因为您在Jan使用pip提供的非标准“regex”库时导入了“re”。我已经发布了我的real string如果您用逗号替换空格,然后去掉应该是最好的项answer@Pythonlogix,这不是StackOverflow的工作方式。你不能只是改变任务,然后说前面的答案是错误的。通常一个人接受一个答案,然后问另一个问题。