整数或小数价格,小数点前保留8位,小数点后保留2位,且不可为0
/(^[1-9][0-9]{0,7}$)|(^((0\.0[1-9]$)|(^0\.[1-9]\d?)$)|(^[1-9][0-9]{0,7}\.\d{1,2})$)/
场景
价格验证,可以输入整数或小数,小数点前保留8位,小数点后保留2位,且不可为0
测试
/**
* @typedef {Array} TestObject - 测试单元
* @type {string} TestObject[0] - 用户输入的要测试的价格
* @type {boolean} TestObject[1] - 预期测试结果
*/
/**
* @type {Array<TestObject>} - 测试单元集合
*/
const test = [
['a', false],
['a1', false],
['1a', false],
['1a1', false],
['a1a', false],
['0', false],
['0.', false],
['0.00', false],
['0.0', false],
['000000', false],
['00000000000', false],
['-1', false],
['-0', false],
['1', true],
['1.', false],
['+1', false],
['98764609', true],
['987646090', false],
['9876546.', false],
['98765412.123', false],
['1.000', false],
['1.001', false],
['1.01', true],
['1.10', true],
['1.1', true],
['0.01', true],
['0.10', true],
['0.001', false],
['0.30', true],
['0.1.0', false],
['', false],
[' ', false],
['22.22', true],
['22.02', true],
['22.0002', false],
['00222.222', false],
['222.22200', false],
['2220.2220', false],
['2e223.22', false],
['e222.22', false],
['22.22e', false],
['22.22', true],
['22.2e', false],
['022.22', false],
['123456789.12345678', false],
['123456789.12', false],
['345678.12345678', false],
['123456', true],
['1234567.1234567', false],
['123456.123456', false],
['123456.123', false],
['123456.12', true],
['12345.1234', false],
['12345.123', false],
['1234.1234', false],
['1234.12', true],
['123456789', false],
['123456.78', true],
['12345678', true],
['123456.7', true],
['123456', true],
['1234.56', true],
['12345', true],
['12.345', false],
['123.45', true],
['0.5', true],
['0.45', true],
['0.445', false],
['0.4445', false],
]
function runTest(regExp) {
let reg = regExp instanceof RegExp ? regExp : new RegExp(regExp);
let c = {
r: 'color: red;',
g: 'color: green;',
d: 'color: auto;'
}
console.log('-----------------------------------------');
console.log('开始测试', regExp);
let success = test
.filter(([value, result]) => regExp.test(value) !== result)
.map(([value, result]) => console.log(`%c${ value }%c 的预期值是 %c${ result }%c, 测试结果是 %c${ !result }`, c.r, c.a, c.g, c.a, c.r))
.length === 0;
console.log(`测试结果 %c${ success ? '成功' : '失败' }`, success ? c.g : c.r);
console.log('-----------------------------------------');
}
正则测试
测试写好, 从网上找合适的轮子,感谢度娘
先找了一个
/^(?:0\.\d{0,1}[1-9]|(?!0)\d{1,6}(?:\.\d{0,1}[1-9])?)$/
原文章地址:
正则表达式 (价格、金钱、费用等格式验证)
https://segmentfault.com/a/1190000020359329?utm_source=tag-newest
这个是保留小数点前6位, 如果其他测试正常,可以略作修改使用
测试结果
发现如果输入 1.10 这种就会识别失败, 所以不能用
继续找轮子
/**
* 来源 https://segmentfault.com/a/1190000020359329?utm_source=tag-newest
* 验证失败
* 1.10
* 0.10
* 小数点前位数验证为6位
*/
runTest(/^(?:0\.\d{0,1}[1-9]|(?!0)\d{1,6}(?:\.\d{0,1}[1-9])?)$/)
/**
* 来源 https://blog.youkuaiyun.com/madril/article/details/78594640
* 验证失败
* 0.0
* 1.
* 没有小数点前位数验证
*/
runTest(/(^0\.[1-9]\d?$)|(^0\.\d[1-9]?$)|(^[1-9]\d{0,7}(\.\d{0,2})?$)/)
/**
* 来源 https://www.cnblogs.com/qq1141100952com/p/10341319.html
* 验证失败
* 0
* 0.0
* 0.00
* 没有小数点前位数验证
*/
runTest(/(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/);
/**
* 来源 https://www.oschina.net/question/872287_155849
* 验证失败
* 0
* 0.0
* 0.00
* 没有小数点前位数验证
*/
runTest(/(^[1-9]\d*(\.\d{1,2})?$)|(^[0]{1}(\.\d{1,2})?$)/);
/**
* 来源 https://www.jb51.net/article/31184.htm
* 验证失败的太多
* ...
*/
runTest(/^(d*.d{0,2}|d+).*$/ );
/**
* 来源 https://download.youkuaiyun.com/download/qq_22005293/9651705
* 验证失败
* 0
* 0.0
* 0.00
* 没有小数点前位数验证
*/
runTest(/^(0|([1-9]\d*))(\.\d{1,2})?$/);
又找了几个发现都不行,要么没有验证0,要么其他问题,看来只能自己造轮子了
自己写正则
既然网上的都不行,那就自己写吧,先捋一下思路
最终得到
/(^[1-9][0-9]{0,7}$)|(^((0\.0[1-9]$)|(^0\.[1-9]\d?)$)|(^[1-9][0-9]{0,7}\.\d{1,2})$)/
有点长,应该可以简化,先试试能不能用
测试
简化
[待更新]
总结
/(^[1-9][0-9]{0,7}$)|(^((0\.0[1-9]$)|(^0\.[1-9]\d?)$)|(^[1-9][0-9]{0,7}\.\d{1,2})$)/