如何用正则表达式匹配单行中两组被空白包围的可变长度数字
问题原因
你当前写的正则\b(?:Ox)\s+(\d*\.*?\d+)把Ox作为固定匹配前缀,规则只会匹配Ox后紧跟的第一组数字,自然无法识别第二组和Ox无直接关联的数字。另外你写的数字匹配逻辑\d*\.*?\d+存在漏洞,可能匹配到多小数点、首尾单独带小数点的非法数字格式。
可直接复用的实现方案
根据你的需求(目标数字长度可变、前后均被空白包围、提取示例中2.66和34.3两组值),分两种场景选正则即可:
- 不需要绑定Ox前缀,提取文本中所有符合要求的数字
用正则:(?<!\S)\d+(?:\.\d+)?(?!\S),开启全局匹配模式
规则说明:(?<!\S):负向后行断言,限定数字前不能是非空白字符,即数字前要么是空白,要么在字符串开头,满足前置空白要求\d+(?:\.\d+)?:严谨匹配整数/小数,先匹配整数部分,小数点+小数部分为可选匹配项,不会匹配非法数字格式(?!\S):负向先行断言,限定数字后不能是非空白字符,即数字后要么是空白,要么在字符串结尾,满足后置空白要求
用你提供的示例文本Ox 2.66 abcda 34.3 abfdasd测试,匹配结果直接返回2.66、34.3两个值。
- 需要锚定Ox前缀,按顺序提取Ox后的两组目标数字
用正则:\bOx\s+(\d+(?:\.\d+)?)\S*\s+(\d+(?:\.\d+)?)(?!\S)
规则说明:第一捕获组提取Ox后第一组数字,中间\S*\s+匹配两组数字之间的非空白内容+间隔空白,第二捕获组直接提取第二组符合要求的数字,执行匹配后两个捕获组分别对应2.66和34.3。
核心学习指引
- 零宽断言:适合做「匹配内容需要满足前后文规则,但不需要把前后文纳入提取结果」的场景,不会占用匹配字符,比直接写
\s+数字\s+更精准,不会把数字前后的空格带入结果。 - 全局匹配开关:正则默认匹配到第一个符合规则的内容就会终止,开启全局匹配(不同编程语言写法有区别,比如JavaScript加
g标识,Python用re.findall方法)才能遍历拿到所有符合规则的结果。 - 通用数字匹配:不要用
\d*\.*?\d+这类松散写法,\d+(?:\.\d+)?是匹配普通整数、小数的通用严谨写法,后续如果需要兼容负数、千分位、科学计数法可以在这个基础上扩展。
内容的提问来源于stack exchange,提问作者Murdoch Quill
相关产品推荐
相关产品推荐

