[英]Python: regex condition to find lower case/digit before capital letter
我想在 python 中拆分一个字符串并将其放入字典中,这样一个键是两个大写字母之间的任何字符块,值应该是这些块在字符串中的出现次数。
例如: string = 'ABbACc1Dd2E'
应该返回: {'A': 2, 'Bb': 1, 'Cc1': 1, 'Dd2': 1, 'E': 1}
到目前为止,我已经找到了两个可行的解决方案(见下文),但我正在寻找一个更通用/更优雅的解决方案,可能是单行正则表达式条件。
谢谢
解决方案1
string = 'ABbACc1Dd2E'
string = ' '.join(string)
for ii in re.findall("([A-Z] [a-z])",string) + \
re.findall("([A-Z] [0-9])",string) + \
re.findall("([a-x] [0-9])",string):
new_ii = ii.replace(' ','')
string = string.replace(ii, new_ii)
string = string.split()
all_dict = {}
for elem in string:
all_dict[elem] = all_dict[elem] + 1 if elem in all_dict.keys() else 1
print(all_dict)
{'A': 2, 'Bb': 1, 'Cc1': 1, 'Dd2': 1, 'E': 1}
解决方案2
string = 'ABbACc1Dd2E'
all_upper = [ (pos,char) for (pos,char) in enumerate(string) if char.isupper() ]
all_dict = {}
for (pos,char) in enumerate(string):
if (pos,char) in all_upper:
new_elem = char
else:
new_elem += char
if pos < len(string) -1 :
if string[pos+1].isupper():
all_dict[new_elem] = all_dict[new_elem] + 1 if new_elem in all_dict.keys() else 1
else:
pass
else:
all_dict[new_elem] = all_dict[new_elem] + 1 if new_elem in all_dict.keys() else 1
print(all_dict)
{'A': 2, 'Bb': 1, 'Cc1': 1, 'Dd2': 1, 'E': 1}
感谢usr2564301提出这个建议:
正确的正则表达式是'[AZ][az]*\\d*'
import re
string = 'ABbACc1Dd2E'
print(re.findall(r'[A-Z][a-z]*\d*', string))
['A', 'Bb', 'A', 'Cc1', 'Dd2', 'E']
然后可以使用itertools.groupby制作一个迭代器,该迭代器从可迭代对象中返回连续的键和组。
from itertools import groupby
all_dict = {}
for i,j in groupby(re.findall(r'[A-Z][a-z]*\d*', string)):
all_dict[i] = all_dict[i] + 1 if i in all_dict.keys() else 1
print(all_dict)
{'A': 2, 'Bb': 1, 'Cc1': 1, 'Dd2': 1, 'E': 1}
最终,可以使用sorted()
将其与正确的计数合并为一行:
print({i:len(list(j)) for i,j in groupby(sorted(re.findall(r'[A-Z][a-z]*\d*', string))) })
{'A': 2, 'Bb': 1, 'Cc1': 1, 'Dd2': 1, 'E': 1}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.