Python中如何用正则同时匹配单个字符串的两种模式提取数字
问题原因
你当前使用的正则两个分支各对应独立的捕获组,匹配方括号格式时只有group(1)有值,匹配百分号格式时只有group(2)有值,所以单独调用任意一个group都会出现另一种格式返回空的情况。
解决方法
有两种常用实现方案:
方案1:代码层过滤非空捕获组(兼容所有Python版本)
匹配后直接从返回的所有捕获组中取非空的结果即可,无需修改正则:
import re string_list = ['73 (1.40%)', '38 (1.55%)', '27 (2.17%)', '32 (1.46%)', '10 (1.46%)', '11 (1.04%)', '11 (1.41%)', '7 (1.34%)', '4 (1.24%)', '28 (1.27%)', '750 (14.41%)', '381 (15.54%)', '182 (14.60%)', '313 (14.27%)', '4.10 [3.73 - 4.45]', '4.08 [3.70 - 4.42]', '4.13 [3.77 - 4.47]', '4.13 [3.78 - 4.47]', '4.07 [3.70 - 4.42]', '4.07 [3.70 - 4.43]', '4.07 [3.70 - 4.40]', '4.09 [3.73 - 4.42]', '4.03 [3.63 - 4.40]', '4.10 [3.70 - 4.47]'] pattern = r'^(\S+)\s\[.*|.*?\((.*)%\)' for val in string_list: match = re.search(pattern, val) if match: # 提取所有非空捕获组的第一个(也是唯一的)结果 target_num = [g for g in match.groups() if g is not None][0] # 如需数值类型直接转float即可:float(target_num) print(target_num)
方案2:使用分支重置语法统一捕获组(Python 3.10+支持)
修改正则使用(?|...)分支重置结构,让两个分支的捕获组共用同一个编号,直接调用group(1)即可拿到所有格式的结果:
import re string_list = ['73 (1.40%)', '38 (1.55%)', '27 (2.17%)', '32 (1.46%)', '10 (1.46%)', '11 (1.04%)', '11 (1.41%)', '7 (1.34%)', '4 (1.24%)', '28 (1.27%)', '750 (14.41%)', '381 (15.54%)', '182 (14.60%)', '313 (14.27%)', '4.10 [3.73 - 4.45]', '4.08 [3.70 - 4.42]', '4.13 [3.77 - 4.47]', '4.13 [3.78 - 4.47]', '4.07 [3.70 - 4.42]', '4.07 [3.70 - 4.43]', '4.07 [3.70 - 4.40]', '4.09 [3.73 - 4.42]', '4.03 [3.63 - 4.40]', '4.10 [3.70 - 4.47]'] # 分支重置结构下两个分支的捕获组都对应group(1) pattern = r'(?|^(\S+)\s\[.*|.*?\((.*)%\))' for val in string_list: match = re.search(pattern, val) if match: target_num = match.group(1) print(target_num)
两种方案输出结果完全一致,可根据你的Python版本选择即可。
内容的提问来源于stack exchange,提问作者Kuni
相关产品推荐
相关产品推荐

