在具有不同分隔符和值内容的标签/值列表中拆分字符串

时间:2019-04-04 09:03:40

标签: python regex

我有一个带有变量/值列表的字符串,例如。

string = " var1 = 20, var2  = hello    var3 =345.34  var4 = I have lost 
2,5 billions, var5 = Bill"

元组的分隔可以是“,”或任意数量的空格,元组的标识始终为“ =” 面临的挑战是某些值包含描述性字符串,其中逗号作为分隔符,千位分隔符,或者最差的是数字分隔符。

我用python regex尝试了一系列re.sub和re.findall,但是我无法在代码下面正确分割var4元组:

import re
string = " var1 = 20, var2  = hello    var3 =345.34  var4 = I lost 2,5 
billions, var5 = Bill"

t = re.sub('(\=\s+)', '=', string)
t = re.sub('(\s+\=)', '=', t)
result = re.findall("[A-Za-z0-9(,)\=\.]+", t)

print(result)
['var1=20,', 'var2=hello', 'var3=345.34', 'var4=I', 'lost', '2,5', 
'billions,', 'var5=Bill']

我的预期结果是

['var1=20', 'var2=hello', 'var3=345.34', 'var4=I lost 2,5 billions', 'var5=Bill']

2 个答案:

答案 0 :(得分:3)

您可以使用

re.split(r',?\s+(?=\w+=)', re.sub(r'\s*=\s*', '=', s.strip()))

在剥离字符串中的前导/尾随空格之后,re.sub(r'\s*=\s*', '=', s.strip())将删除=周围的空格,而r',?\s+(?=\w+=)'re.split的字符串将以可选的逗号分隔,然后是1或更多空格,后跟1+个单词字符,然后是=

请参见Python demo

import re
s = " var1 = 20, var2  = hello    var3 =345.34  var4 = I lost 2,5 billions, var5 = Bill"
result = re.split(r",?\s+(?=\w+=)", re.sub(r'\s*=\s*', '=', s.strip()))
print(result)
# => ['var1=20', 'var2=hello', 'var3=345.34', 'var4=I lost 2,5 billions', 'var5=Bill']

答案 1 :(得分:3)

如果要提取的每个元素都以var开头,则可以按照以下方式使用该事实:

import re
string = " var1 = 20, var2  = hello    var3 =345.34  var4 = I have lost 2,5 billions, var5 = Bill"
vars = re.findall(r'var.*?(?=var|$)',string)
print(vars) # ['var1 = 20, ', 'var2  = hello    ', 'var3 =345.34  ', 'var4 = I have lost 2,5 billions, ', 'var5 = Bill']

我使用了正向超前(零长度断言的种类),因此findall在寻找子串,其后跟varstr的末尾($) 。如您所见,str中的vars仍需要清洁。首先删除尾随空格:

vars = [i.strip(' ') for i in vars]
print(vars) # ['var1 = 20,', 'var2  = hello', 'var3 =345.34', 'var4 = I have lost 2,5 billions,', 'var5 = Bill']

现在我不清楚您的示例-我不知道您是否要像,那样保留尾随var1 = 20,,还是像var4=I lost 2,5 billions一样删除它,所以我要保留{ {1}},但要注意它们可能会以与空格所示相同的方式被删除。 最后,要删除,周围的空格,您可以按以下方式使用=

re.sub

请注意,vars = [re.sub(r' *= *','=',i,1) for i in vars] print(vars) #['var1=20,', 'var2=hello', 'var3=345.34', 'var4=I have lost 2,5 billions,', 'var5=Bill'] 中的1是有意的,因此仅会发生re.sub替换-因此它将仅抛弃{{1}的每个元素中第一个1周围的空格}}。如果您确定每个元素中的个数不超过1个=,则可以删除该vars