【问题标题】:Python: regex condition to find lower case/digit before capital letterPython:正则表达式条件在大写字母之前找到小写/数字
【发布时间】:2020-02-25 14:34:19
【问题描述】:

我想在 python 中拆分一个字符串并将其放入字典中,这样键是两个大写字母之间的任何字符块,值应该是这些块在字符串中出现的次数。

例如:string = 'ABbACc1Dd2E' 应该返回这个:{'A': 2, 'Bb': 1, 'Cc1': 1, 'Dd2': 1, 'E': 1}

到目前为止,我已经找到了两个可行的解决方案(见下文),但我正在寻找一个更通用/优雅的解决方案,可能是单行正则表达式条件。

谢谢

【问题讨论】:

  • print ({i:len(list(j)) for i,j in groupby (sorted(re.findall (r'[A-Z][a-z]*\d*', string)))})
  • 随意添加它作为单独的答案(你可以标记它Community wiki) - 如果你也可以解释它!找出这个表达式是如何工作的应该是一个值得练习的练习。

标签: python regex string


【解决方案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}

【讨论】:

    【解决方案2】:

    感谢usr2564301 的建议:

    正确的正则表达式是'[A-Z][a-z]*\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}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-04
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多