相关文章推荐
率性的山楂  ·  debian开启tun·  7 月前    · 
高大的日光灯  ·  com.fasterxml.jackson. ...·  1 年前    · 
Python知友问答:正则表达式实战——大小写字母、数字、括号混合字符串计数

Python知友问答:正则表达式实战——大小写字母、数字、括号混合字符串计数

问题

有如下字符串 src

src = 'Ab2(CDe)4(FAb)2De'
  1. 将字符串分割为 大写字母起始 + 0~若干小写字母 + 0~若干数字 的子串
  2. 上述子串若包含数字结尾,则计数以该数字为倍率计算,否则计数为1
  3. 子串或若干子串可以被括号包裹
  4. 上述括号后的数字作为括号内所有子串的倍率予以计数
  5. 参照前述规则,样本字符串 src 分割计数结果为 {'Ab': 4, 'C': 4, 'De': 5, 'F': 2}
  6. 扩展一下:数字可能是多位并且允许括号嵌套

解法

对于这一类规则较复杂的字符串分割最好的工具还是正则表达式,先看下面的实现代码:

import re
src = 'Ab12(C(Ab)5DeF5)4A(G(Hi)2FAb)2De'
# src = 'Ab2(CDe)4(FAb)2De'
pattLettersNumbers = re.compile('([A-Z][a-z]*)(\d*)') # 解析 大写小写数字 子字符串
pattBrackets = re.compile('(\((\w+)\)(\d*))')  # 解析括号对
while '(' in src and ')' in src:
    src = pattBrackets.sub(lambda x: x.group(2) * (int(x.group(3)) if x.group(3) else 1),
                           src)
    print(src)
counter = {}
for subS, cnt in pattLettersNumbers.findall(src):
    cnt = int(cnt) if cnt else 1