正则如何匹配负号与数字间带空格的负值并去除中间空格
解答
仅用正则完全可以覆盖这个场景,不需要调整整体实现方案。
问题根源
你之前写的正则匹配失败,核心是没有考虑到这款天平输出格式里,负号和数值之间存在不定数量空格的情况:原正则把负号和数字放在同一个连续匹配的字符集里,遇到负号后的空格就会终止Value分组的匹配,自然抓不到后面的数字部分;后来加\s的版本会把空格也带进捕获结果,是因为你直接把空格划成了Value的有效匹配字符。
推荐实现方案
不要硬写复杂正则追求一步到位,用「正则提取完整数值片段+单步字符串清洗」的方式是最稳妥、可维护性最高的,适配正则如下:
(?<=\s)(?<Value>-?\s*\d+(?:\.\d+)?)\s*(?<Unit>[a-zA-Z]+)\s*$
针对你给出的示例串G - 3.56436 mg:
- Value分组会捕获到完整的数值片段
- 3.56436 - 对捕获到的Value结果做一次删除所有空白字符的处理,就能直接得到你需要的
-3.56436 - Unit分组会直接捕获到单位
mg
这个正则完全兼容你之前其他型号天平的输出格式,不管负号和数字之间有没有空格、有多少空格都能正常匹配;而删除字符串空白是所有编程语言都自带的基础方法,实现成本为零,比堆复杂环视、分支逻辑的正则靠谱得多,后续如果天平输出格式有小调整也方便修改。
正则一步到位方案(有引擎要求)
如果你必须让Value分组直接输出无空格的结果,且你使用的正则引擎支持同名分组重复捕获(比如.NET、PCRE2),可以用下面的写法:
^\S+\s+(?:(?<Value>-)\s+)?(?<Value>\d+(?:\.\d+)?)\s*(?<Unit>\w+)\s*$
这个正则会把负号、数字部分分别捕获到同名的Value分组下,支持的引擎会自动拼接两部分内容,直接返回-3.56436,不会包含中间的空格。但这个方案对正则引擎版本有要求,兼容性不如第一个方案。
内容的提问来源于stack exchange,提问作者Marcelo Soares
相关产品推荐
相关产品推荐

