例如:
123我的00.1 错误
123我的0.1 正确
123我的00002 错误
123我的2 正确
例如:
123我的00.1 错误
123我的0.1 正确
123我的00002 错误
123我的2 正确
可以先匹配非法的再取反((?<!regex)
用法见 正则表达式预查的解释与应用)
!/(^|[^\d.])0\d/.test(s)
// 使用预查
!/(?<![\d.])0\d/.test(s)
不取反,可改为
/^(?!.*(?<![\d.])0\d).*$/.test(s)
不使用预查,可分步匹配
// 匹配合法的
s.match(/\d+(?:\.\d+)?/g)?.every(d => /^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(d)) ?? true
// 匹配非法的
!s.match(/\d+(?:\.\d+)?/g)?.some(d => /^0\d/.test(d))
非要写成一个正则且匹配合法的,要防止一个数字被分成多段匹配,如 00
是非法的,但分成 0 0
会变成合法的,1.01
是合法的,但分成 1 . 01
会变成非法的
几个正确写法参考:
// (?!\d) 使得下次不匹配数字,防止了连续两次匹配数字
/^(?:(?:0|[1-9]\d*)(?:\.\d+)?(?!\d)|\D+)*$/.test(s)
// 不使用预查,修改字符串总以非数字开头,使得正则容易编写
/^(?:\D+(?:(?:0|[1-9]\d*)(?:\.\d+)?)?)*$/.test('a' + s)
// 不使用预查,不修改字符串
/^(?:(?:^|(?:0|[1-9]\d*)(?:\.\d+)?)(?:\D+|$))*$/.test(s)
测试用例
[
// true
'0',
'1',
'10',
'0.1',
'0.01',
'1.01',
'100.00',
'',
'我',
'1.0我0.1a1.01',
// false
'00',
'01',
'010',
'00.1',
'00.01',
'01.01',
'00.00',
'10我01a101',
].forEach(s => console.log(s,
/^(?:(?:0|[1-9]\d*)(?:\.\d+)?(?!\d)|\D+)*$/.test(s)
))
13 回答12.7k 阅读
7 回答1.8k 阅读
3 回答1k 阅读✓ 已解决
3 回答1.2k 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
2 回答1.8k 阅读
2 回答1.1k 阅读✓ 已解决
这样?
不支持
(?>...)
的话,(?:...)
应该也可以,就是慢些