Python3.8如何简洁解析数字开头、下一个数字前空格结尾的字符串为元组列表
解决方案
可直接运行的代码
import re raw_str = '1-New Bathroom 2-New Kitchen 3-New Garden 4-Caribbean Holiday' # 核心匹配逻辑 res = [(int(num), desc.strip()) for num, desc in re.findall(r'(\d+)-([^\d]+)', raw_str)] print(res)
运行后输出的结果和要求的格式完全一致:
[(1, 'New Bathroom'), (2, 'New Kitchen'), (3, 'New Garden'), (4, 'Caribbean Holiday')]
优化逻辑说明
原有正则的问题
你原来的写法存在几个明显缺陷:
- 开头的
^锚点只能匹配整个字符串的起始位置,完全无法捕获第2、3、4条的内容 [aA-zZ]是错误写法,ASCII编码中A到z之间包含[、\、]、^、_、```等非字母字符,匹配范围不符合预期{1}属于完全冗余的量词,正则默认匹配次数就是1次- 仅设置了一个捕获组,只能拿到编号,拿不到后面的描述内容,需要二次处理
优化后正则的匹配逻辑
我们用re.findall直接批量提取所有符合规则的分组,无需额外遍历:
(\d+):第一个捕获组,匹配1个及以上的数字,对应条目编号,写法比原来的[0-9]{1,2}更简洁,同时支持超过2位的大编号-:匹配条目中的连接短横线([^\d]+):第二个捕获组,匹配所有非数字字符,直接拿到完整的条目描述,因为下一个数字天然就是下一个条目的起始,自动分割不同条目- 最后通过列表推导式把编号转int类型,同时给描述内容做去首尾空格处理,直接生成目标格式的元组列表
扩展适配方案(支持描述内容带数字的场景)
如果后续你的条目描述里可能出现数字,用下面的普适性更强的正则即可,核心是通过正向预查判断条目边界:
res = [(int(num), desc.strip()) for num, desc in re.findall(r'(\d+)-(.*?)(?=\s*\d+-|$)', raw_str)]
(?=\s*\d+-|$)是零宽正向预查,判定当前内容的边界是「下一个条目的起始(空格+数字+短横线)」或者「字符串结尾」,不会误吞描述里的数字内容。
内容的提问来源于stack exchange,提问作者Homunculus Reticulli
相关产品推荐
相关产品推荐

