Python3.11正则表达式:如何让值匹配停在下一个键前?
Python正则匹配键值对:精准终止值的匹配边界
问题场景
需要将以下字符串转换为字典:
string = '''Latitude (degrees): 4010.44 Longitude (degrees): 58.000 Radiation database: year month H(h)_m 2005 Jan 57.77 2005 Feb 77.76 2005 Mar 120.58 H(h)_m: Irradiation plane (kWh/m2/mo)'''
预期提取的键值对为:
Latitude (degrees): 4010.44 Longitude (degrees): 58.000 Radiation database: year month H(h)_m 2005 Jan 57.77 2005 Feb 77.76 2005 Mar 120.58 H(h)_m: Irradiation plane (kWh/m2/mo)
当前使用的正则r'(?P<key>(?>[A-Z][ a-z\_(\)]*))\: *(?P<value>.+?)(?: |$)'无法满足需求:
- 非贪婪模式
(?P<value>.+?)会因终止条件为空格,导致值被提前截断(比如Radiation database的值只能匹配到year) - 改为贪婪匹配后,值会意外捕获后续的键内容
解决方案:用正向预查界定值的终止边界
核心思路是让值的匹配在遇到下一个符合键模式的内容时停止,而非简单的空格或字符串结尾。结合Python 3.11支持的原子组,调整后的正则如下:
pattern = r'(?P<key>(?>[A-Z][\w ()_-]*)): *(?P<value>.+?)(?=(?: [A-Z][\w ()_-]*:)|$)'
正则各部分解释
(?P<key>(?>[A-Z][\w ()_-]*)): 匹配键,原子组提升匹配效率;键以大写字母开头,后续可包含字母、数字、空格、括号、下划线、连字符: *: 匹配冒号及后续任意数量的空格(?P<value>.+?): 非贪婪匹配值内容,避免过度捕获(?=(?: [A-Z][\w ()_-]*:)|$): 正向预查,当检测到下一个键的起始(空格+大写字母开头的键+冒号)或字符串结尾时,终止值的匹配
代码示例
import re string = '''Latitude (degrees): 4010.44 Longitude (degrees): 58.000 Radiation database: year month H(h)_m 2005 Jan 57.77 2005 Feb 77.76 2005 Mar 120.58 H(h)_m: Irradiation plane (kWh/m2/mo)''' pattern = r'(?P<key>(?>[A-Z][\w ()_-]*)): *(?P<value>.+?)(?=(?: [A-Z][\w ()_-]*:)|$)' matches = re.finditer(pattern, string) result_dict = {match.group('key').strip(): match.group('value').strip() for match in matches} # 输出结果 for k, v in result_dict.items(): print(f"{k}: {v}")
运行结果
Latitude (degrees): 4010.44 Longitude (degrees): 58.000 Radiation database: year month H(h)_m 2005 Jan 57.77 2005 Feb 77.76 2005 Mar 120.58 H(h)_m: Irradiation plane (kWh/m2/mo)
补充说明
正则中预查的 [A-Z]确保下一个键前有空格,避免误匹配值内的大写字母(比如Jan不会被识别为键的起始);同时通过|$兼容字符串末尾的键值对。
内容的提问来源于stack exchange,提问作者hildogjr
相关产品推荐
相关产品推荐

