代码来自文章: react中使用antDesign的Input/InputNumber最多保留两位小数,多的小数位禁止输入,且实现输入实时校验并添加千位分隔符, 正则忘了很多, 我主要做个笔记.
//定义InputNumber的参数
const NumberProps = {
min: '0',//最小值
max: '999999999999999.99',//最大值
stringMode: true,//字符值模式,开启后支持高精度小数
step: '0.01',//小数位数
formatter: (value: any) => {//指定输入框展示值的格式
const reg1 = `${value}`.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');
return reg1.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
//如果不需要添加千位分隔符可以直接返回return reg1
},
};
//在InputNumber中使用NumberProps
<Col span={10}>
<Form.Item
label="金额"
name="amount"
rules={[
{
required: true,
message: '请输入金额',
},
]}
>
<InputNumber {...NumberProps} style={{ width: '100%' }} />
</Form.Item>
</Col>
这里主要涉及到了两个正则表达式:
value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');
value1.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- 第一个表达式的作用是: 保证在 inputNumber 的框中的数字, 小数点后只能保留两位, 第三位就输不进去了.
正则表达式详解:
^
行开头$
行结尾- 点号
.
可以匹配一个任意字符,仅1次。 - 星号
*
可以复制它之前那个字符任意次数,包括0次,即[0, +∞]次。 +
表示0个以上个; + 号前面的字符必须至少出现一次(1次或多次), 即[1, +∞]次。?
表示0个或者1个
例:colou?r 可以匹配 color 或者 colour,
? 问号代表前面的字符最多只可以出现一次(0次、或1次)。
value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');
(\-)*
表示存在负数的情况, *
也可以是0次, 所以正负数都会被匹配进去。但是有个问题 , --121215644.061245
这种数字也是满足匹配条件的, 所以可以改成 (\-)?
, ?
表示0个或者1个 -
, 避免特殊情况
(\d+)
表示匹配一个或多个数字
\.
中 \
是转义符, 意思是匹配.
(小数点)
(\d\d).*
也是匹配数字, 不过这里匹配的是小数点后的数字, 有两个 \d
是因为小数点后保留两位小数(第三位是输不了的)
$1$2$3
是匹配符(占位符), 每个对应一个 ()
分组.
这里原先有个疑问, 前面不是已经设置了 stringMode: true, step: '0.01'
开启了支持高精度小数的模式, 并且把精度设置为小数点后两位了吗, 为什么还要设置这个正则?
测试后发现, stringMode: true, step: '0.01'
并不能限制小数点后只保留两位,小数点后仍然可以输入任意位数的数字。这两句只能保证在点击右边的上下两个按钮时,小数点后的第二位发生变化。比如点击增加按钮,小数点后变成 .0912
- 第二个表达式的作用是: 使用千分符进行分隔. 这个正则表达式在antd示例中就已经给出了.
value1.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
\b 是正则表达式规定的一个特殊代码(好吧,某些人叫它元字符,metacharacter),代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是 \b 并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置。
如果需要更精确的说法,\b 匹配这样的位置:它的前一个字符和后一个字符必须是\w (字母数字)和 \W (非字母数字),即匹配必须出现在 \w (字母数字)和 \W (非字母数字)字符之间的边界上。
\b属于匹配位置的元字符,一般作占位作用,而不被捕获,同属于匹配位置的还有匹配行起始位^和行结束位$