正则表达式中([^,] *)和(。*,)之间的区别?使用python

时间:2018-02-14 22:39:50

标签: python regex

当我尝试将字符串转换为类似字典的形式时,我遇到了这个问题

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')]

这一次,我得到了一个更好的密钥和项目分别存储在元组中。

我唯一的区别是(。),进入[^,]

我认为第一个是找到任何东西,直到它与逗号匹配 我认为第二个是找到除逗号以外的任何东西

有什么区别?

2 个答案:

答案 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(',')]