当我尝试将字符串转换为类似dict的形式时,我遇到了这个问题
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')]
这次,我的钥匙和物品分别存储在元组中。
我唯一的区别是(。(,进入[^,]
我想的第一个是找到任何东西,直到它与逗号相匹配我想的第二个是除了逗号
以外的任何东西有什么区别?
在第一例中:
dict_form = re.compile(r'(&[a-zA-Z]*:)(.*),')
(.*)
操作员是贪婪。这意味着它将与最后一个逗号匹配,这就是为什么您看到比赛扩展到&c:14
。
在第二个实例中,通过排除逗号,您将强迫匹配受逗号的束缚 - 就像在说"匹配所有内容直到我们达到逗号"。这将导致您首先期望的匹配行为。
正如据说.*
将是贪婪的,并尝试尽可能匹配,以使其非怪兽使用问号(?
(,如.*?
所示。在您的代码中:
dict_form = re.compile(r'(&[a-zA-Z]*:)(.*?),')
result = dict_form.findall(s)
print(result)
另一个更容易的解决方案是只使用字符串拆分而不是正则表达式:
result = [_s.split(':') for _s in s.split(',')]