当我尝试将字符串转换为类似字典的形式时,我遇到了这个问题
s = '&a: 12, &b:13, &c:14, &d: 15' # the string I want to convert
在转换之前,我首先尝试找到所有匹配的结果,所以我使用了
dict_form = re.compile(r'(&[a-zA-Z]*:)(.*),')
result = dict_form.findall(s)
print(result) # [('&a:', ' 12, &b:13, &c:14')]
这是非常意外的,而且有点凌乱
但是当我尝试另一种匹配字符串的方式时:
dict_form1 = re.compile(r'(&[a-zA-Z]*:)([^,]*)')
result = dict_form1.findall(s)
print(result) # [('&a:', ' 12'), ('&b:', '13'), ('&c:', '14'), ('&d:', ' 15')]
这一次,我得到了一个更好的密钥和项目分别存储在元组中。
我唯一的区别是(。),进入[^,]
我认为第一个是找到任何东西,直到它与逗号匹配 我认为第二个是找到除逗号以外的任何东西
有什么区别?
答案 0 :(得分:2)
首先:
dict_form = re.compile(r'(&[a-zA-Z]*:)(.*),')
(.*)
运算符 greedy 。这意味着它会匹配最后一个逗号的所有内容,这就是为什么您看到匹配延伸到&c:14
。
在第二个例子中,通过排除逗号,你强迫匹配被逗号绑定 - 就像说“匹配所有内容,直到我们点击逗号”。这将导致您首先想到的匹配行为。
答案 1 :(得分:1)
如前所述,.*
会贪婪并尝试尽可能地匹配,以使其非贪婪地使用?
中的问号(.*?
)。在您的代码中:
dict_form = re.compile(r'(&[a-zA-Z]*:)(.*?),')
result = dict_form.findall(s)
print(result)
另一个更简单的解决方案是使用字符串拆分而不是正则表达式:
result = [_s.split(':') for _s in s.split(',')]