在Python中分隔字符串,排除一些包含分隔符

时间:2016-03-04 14:29:12

标签: python regex python-3.x

我有一个非常难看的字符串:

# ugly string follows:
ugly_string1 = SVEF/XX:1/60/24.02.16 07:30:00/"isk/kWh"/0/ENDTIME
# which also may look like this (part within quotes is different):
ugly_string2 = SVEF/XX:1/60/24.02.16 07:30:00/"kWh"/0/ENDTIME

我希望将其分开,以便在Python中获取此列表:

['SVEF/XX:1', '60', '24.02.16 07:30:00', '"isk/kWh"', '0', 'ENDTIME']
# or from the second string:
['SVEF/XX:1', '60', '24.02.16 07:30:00', '"kWh"', '0', 'ENDTIME']

第一个元素(SVEF/XX:1)将始终相同,但第四个元素可能包含也可能不包含分隔符(/)。

我想出了正则表达式,它隔离了第一和第四个元素(example here):

(?=(SVEF/XX:1))|(?=("(.*?)"))

但我无法弄清楚如何用/字符分隔字符串的其余部分,同时排除这两个孤立的元素?

我可以用更多"手册"方法,像这样的正则表达式(example here):

([^/]+/[^/]+)/([^/]+)/([^/]+)/("[^"]+")/([^/]+)/([^/]+)

但是当我在Python中尝试这个时,出于某种原因我得到了额外的空元素:

['', 'SVEF/XX:1', '60', '24.02.16 07:30:00', '"isk/kWh"', '0', 'ENDTIME', '']

之后我可以对这个结果进行消毒,但如果我在没有额外干预的情况下将这些字符串分开,那将会很棒。

4 个答案:

答案 0 :(得分:4)

在python中,随着split()rsplit()的连续使用,这可以更容易地完成(并且有更多空间来概括或调整未来的方法)。

ugly_string = 'SVEF/XX:1/60/24.02.16 07:30:00/"isk/kWh"/0/ENDTIME'
temp = ugly_string.split("/", maxsplit=4)
result = [ temp[0]+"/"+temp[1] ] + temp[2:-1] + temp[-1].rsplit("/", maxsplit=2)
print(result)

打印:

['SVEF/XX:1', '60', '24.02.16 07:30:00', '"isk/kWh"', '0', 'ENDTIME']

我使用split/rsplit的第二个参数来限制分割的斜杠数量; 我首先将尽可能多的部分从左侧分开(即4),然后重新加入第0和第1部分 (SVEFXX)。然后我使用rsplit()从右边开始分割的其余部分。中间留下的是引用的单词,无论它包含什么。

重新加入前两个部分并不太优雅,但两种格式都不允许/同时作为字段分隔符出现在未加引号的字段中。

答案 1 :(得分:3)

您可以先使用re.findall测试引用的部分,然后在第二个分支中选择开头:

re.findall(r'(?:^|/)("[^"]*"|(?:^[^/]*/)?[^/"]*)', s)

答案 2 :(得分:2)

Python的csv模块可以处理多个不同的分隔符,如果您可以将"重新插入到似乎始终存在的字段中,并重新组合第一个字段。

如果你有一个字符串,并希望将其视为csv文件,你可以这样做准备:

>>> import StringIO
>>> import csv
>>> ugly_string1 = 'SVEF/XX:1/60/24.02.16 07:30:00/"isk/kWh"/0/ENDTIME'
>>> f = StringIO.StringIO(ugly_string1)

否则,假设f是一个打开的文件,或者我们刚才创建的对象:

>>> reader = csv.reader(f, delimiter='/')
>>> for row in reader:
>>>    print(row)
['SVEF', 'XX:1', '60', '24.02.16 07:30:00', 'isk/kWh', '0', 'ENDTIME']
>>> first = "/".join(row[0:2])

答案 3 :(得分:0)

谢谢大家的回答,他们都很好,非常乐于助人!然而,在尝试测试每个人的表现之后,我想出了令人惊讶的结果。你可以看看here, 但基本上,timit模块每次都会结束,结果与此相似:

============================================================
example from my question:
0.21345195919275284
============================================================
Tushar's comment on my question:
0.21896087005734444
============================================================
alexis' answer (although not completely correct answer):
0.2645496800541878
============================================================
Casimir et Hippolyte's answer:
0.3663317859172821
============================================================
Simon Fraser's csv answer:
1.398559506982565

所以,我决定坚持自己的榜样:

([^/]+/[^/]+)/([^/]+)/([^/]+)/("[^"]+")/([^/]+)/([^/]+)`)

但是我会奖励你的努力!