正则表达式判断数字范围
约 1736 字大约 6 分钟
2026-05-03
正则表达式与数字区间判断,这个我是真没想到还能结合在一起。背景就是一个低代码平台里面,针对数字类型的表单组件的校验里面,没有最大、最小值的限制,只给出了几个正则表达式规则和自定义规则。虽然可以用自定义的规则,但这里也在思考,为啥不直接用最小值最大值的配置呢,正则表达式难道也能用来判断区间?从这里就开始往下探索了。
正则表达式能实现数字区级判断?
正则表达式的核心优势就是精准匹配字符串的固定模式。
数字的区间判断,本质上可以拆解为「数字格式的合法性」+「数字分段的特征匹配」。比如要判断数字是否在 0.2~1.5 之间,我们可以将其拆分为多个具有明显字符串特征的子区间,再通过正则的分支匹配(|)整合,最终实现完整的区间校验。
核心实战:数字区间正则的设计思路与实现
正则实现数字区间判断的核心方法论是:拆解区间、化整为零,分支匹配、锚定首尾。下面我们从简单到复杂,逐步讲解实现过程。
1. 基础原则:明确数字的合法格式
首先,我们定义表单中数字的常见合法格式(避免匹配无效格式):
- 整数:如
0、1(排除前导零,如001无效) - 标准小数:如
0.2、1.49(排除0.、1.这类不完整小数) - 可选无前置 0 小数:如
.2(等价于0.2,部分场景用户可能这样输入,可选择支持或禁用)
同时,用 ^(字符串开头)和 $(字符串结尾)锚定整个字符串,避免部分匹配(比如避免 12.3 中的 2.3 被误判为合法)。
2. 步骤拆解:以「0.2~1.5」区间为例
我们以这个高频区间为例,完整讲解正则的设计过程。
步骤 1:拆分子区间
将 0.2~1.5 拆分为 3 个具有明显字符串特征的子区间,覆盖所有合法情况:
- 子区间 1:
0.2~0.9(小数,整数部分为 0,小数部分第一位 ≥2) - 子区间 2:
1(整数,单独匹配,避免被小数规则遗漏) - 子区间 3:
1.0~1.5(小数,整数部分为 1,小数部分 ≤5)
步骤 2:为每个子区间编写正则分支
每个子区间对应一个正则分支,匹配其字符串特征:
- 子区间 1(
0.2~0.9):0\.(2|3|4|5|6|7|8|9)\d*- 解析:
0\.匹配0.,(2|3|...|9)限制小数第一位为 2-9,\d*匹配后续 0 个或多个数字(支持0.2、0.23、0.999等)
- 解析:
- 子区间 2(
1):1(直接精确匹配整数 1) - 子区间 3(
1.0~1.5):拆分为两个更小分支,1\.[0-4]\d*+1\.5- 解析:
1\.[0-4]\d*匹配1.0~1.499...,1\.5精确匹配边界值1.5(避免1.51等超界值)
- 解析:
步骤 3:整合分支,支持可选格式(无前置 0 小数)
如果需要支持 .2 这类无前置 0 格式,补充对应的分支,最终整合为完整正则:
/^(0\.(2|3|4|5|6|7|8|9)\d*|1|1\.[0-4]\d*|1\.5|\.(2|3|4|5|6|7|8|9)\d*)$/3. 通用化:其他区间的推导规律
掌握了上述思路,其他区间可以快速推导:
- 区间
0~1.5:在0.2~1.5基础上,补充0、0\.[0-1]\d*(匹配0~0.199...) - 区间
0.2~0.5:正则为/^(0\.(2|3|4)\d*|0\.5|\.(2|3|4)\d*|\.5)$/ - 区间
1~10:正则为/^(1|2|...|9|10)$/(整数区间,直接枚举或优化为/^([1-9]|10)$/)
扩展用法:正则在数字处理中的其他实用场景
除了区间判断,正则表达式在数字的「格式校验」「数据提取」「格式格式化」等场景中也有广泛应用
1. 场景 1:数字格式合法性校验
这是表单校验的基础需求,用于确保用户输入的是合法数字。
(1)校验纯非负整数(无小数、≥0)
/^\d+$/- 适用场景:年龄、数量、序号等输入项
- 解析:
\d+匹配 1 个或多个数字,排除空值、小数、负数
(2)校验保留 2 位小数的非负数字(金额常用)
/^\d+(\.\d{2})?$/- 适用场景:商品金额、运费、总价等
- 解析:
\d+匹配整数部分,(\.\d{2})?匹配可选的 2 位小数(.后必须跟 2 个数字,避免0.1、0.123等格式)
(3)校验带负号的合法数字(支持整数、小数)
/^-?\d+(\.\d+)?$/- 适用场景:温度、盈亏金额、坐标等可能为负数的场景
- 解析:
-?匹配可选的负号,(\.\d+)?匹配可选的任意位小数
2. 场景 2:从字符串中提取所有数字
在低代码平台中,有时需要从用户输入的文案中提取数字(如从「订单金额:99.99 元,运费:10 元」中提取金额数据),正则可以快速实现。
// 提取所有数字(支持整数、小数)
const str = '订单金额:99.99元,运费:10元,优惠:-5.8元';
const numReg = /-?\d+(\.\d+)?/g;
const numList = str.match(numReg);
console.log(numList); // ["99.99", "10", "-5.8"]3. 场景 3:数字格式格式化(配合 JS replace())
正则可以配合 JavaScript 的 replace() 方法,实现数字的快速格式化,提升表单数据的可读性。
(1)数字补前导零(如将 1 转为 001,适配编号格式)
// 补为3位数字,不足前面补0
const formatNum = num => {
return String(num)
.replace(/^(\d)$/, '00$1')
.replace(/^(\d{2})$/, '0$1');
};
console.log(formatNum(1)); // "001"
console.log(formatNum(12)); // "012"
console.log(formatNum(123)); // "123"(2)给大数字添加千分位(如 1234567 转为 1,234,567)
// 给非负数字添加千分位
const addThousandSeparator = num => {
return String(num).replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,');
};
console.log(addThousandSeparator(1234567)); // "1,234,567"
console.log(addThousandSeparator(1234.567)); // "1,234.567"4. 场景 4:清洗输入内容,排除非数字字符
用户输入时可能误输入非数字字符(如 a123b45.6c),正则可以快速清洗,只保留数字和小数点(或负号)。
// 清洗非数字字符,保留数字、小数点、负号(仅保留第一个小数点和开头的负号)
const cleanNumStr = str => {
// 第一步:只保留数字、小数点、负号
let cleanStr = str.replace(/[^0-9.-]/g, '');
// 第二步:处理多余的小数点和负号
cleanStr = cleanStr.replace(/^-/, '').replace(/\./, '$#$').replace(/\./g, '').replace(/\$#\$/, '.');
// 第三步:恢复开头的负号(如果有)
return str.startsWith('-') ? `-${cleanStr}` : cleanStr;
};
console.log(cleanNumStr('a123b45.6c78')); // "12345.678"
console.log(cleanNumStr('-x98.7y65.4z')); // "-98.7654"