正则表达式提取数字_从文本中提取各类数字的正则方案

推荐用\b-?\d+\b提取整数,避免误匹配;浮点数用(?

匹配整数(含负号)

最常见需求是提取像 -123456 这样的纯整数,但要注意避免匹配到小数点前后的部分(比如 1.23 中的 123)。

推荐用单词边界 + 可选负号:\b-?\d+\b

  • \b 防止从 abc123def 中误抓 123;若需允许这种场景,改用 (?
  • -? 仅匹配一个负号,不支持 --123+-45;如需支持,得扩展为 [+-]?\d+ 并加前后断言
  • JavaScript 中全局匹配要加 g 标志:/\\b-?\\d+\\b/g;Python 的 re.findall() 默认行为一致

提取浮点数(含科学计数法)

真正兼容现实文本的浮点数正则不能只写 -?\d+\.\d+,它漏掉 .5123.-1.2e-3 等合法形式。

较稳妥的写法是:-?\d*\.?\d+(?:[eE][+-]?\d+)?,但必须配合前后非数字断言,否则会把 123.456.789 拆成两段或吞掉小数点。

  • 更安全的版本:(?
  • \d* 允许 .5\.? 让小数点可选;\d+ 保证至少一位数字主体
  • 注意:该模式仍会匹配 123.(末尾带点),如需排除,改成 -?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?,但会丢掉 .5
  • Python 示例:
    import re
    text = "温度-23.5°C,误差±1.2e-4,ID:999."
    nums = re.findall(r'(?

区分「金额」「电话」「ID」等语义化数字

同一串数字在不同上下文含义不同,正则无法“理解”语义,但可通过上下文锚定提升准确率。

  • 金额常带货币符号或逗号分隔:¥\s*(\d{1,3}(?:,\d{3})*\.\d{2})\$\s*(\d+(?:,\d{3})*(?:\.\d{2})?)
  • 中国大陆手机号固定 11 位且以 1 开头:1[3-9]\d{9}(注意别被 123456789012 这种长串干扰,加 \b(?)
  • ID 类字段常紧跟冒号或等号:ID[::]\s*(\d+)user_id\s*=\s*(\d+)
  • 避免过度设计:先用宽泛模式提取所有候选,再用业务逻辑二次过滤,比一个巨长正则更易维护

JavaScript 中 match()exec() 的差异陷阱

在 JS 里用正则提取数字,String.prototype.match() 和循环调用 RegExp.prototype.exec() 行为不同,容易漏数据。

  • str.match(/-?\d+/g) 返回字符串数组,简单直接;但若正则含捕获组(如 /(-?\d+)/),返回结果结构突变——首项是完整匹配,后续才是分组,极易出错
  • exec() 在全局模式下需手动循环,且正则实例必须保持状态(不能每次新建),否则永远只返回第一个:
    const re = /(?
  • Chrome/Edge 已支持 matchAll(),更推荐:[...text.matchAll(/(? m[0])

正则提数字看似简单,真正难的是平衡“不漏”和“不错”——越宽松越容易连带抓出不该要的部分,越严格越可能因格式变体而失效。实际项目中,建议先用最简模式跑一遍样本,再根据误匹配/漏匹配案例逐步收紧断言,而不是一上来就堆砌复杂表达式。