从一个数字输入框限制符号输入开始到正则入门

背景

数字输入框限制其它符号的输入是一个很常见的需求,但是网上的实现方案始终离理想状态差那么一丢丢,大多会遇到两个坑,一个是 type=number不能过滤加减符号 ,另外一个点就是如果需要能够输入小数时时,如何限制首位禁止输入多个0,并且能够正确的过滤保留位数

本篇就带大家一起一步一步,通过实现这个需求,到最终掌握各项基础的正则小知识

思路

首先我们来对两个难点进行分析看看如何解决

能不能使用 type = number

如果你的需求要求输入时限制用户把加减符号输入进去,那么答案是肯定的,不能

通常我们在实现输入限制时会配合 input 事件对输入进行实时处理,如果使用 type=number ,那么遇到诸如 +,- 之类的运算符号时,事件结果会直接返回空,这样会导致我们的正则匹配失效 ,所以实现这个需求的第一步,我们需要把 input 上的类型属性设置为 text,以 element-ui 为例

lua 复制代码
<el-input v-model="number" type="text"></el-input>

各种需求情况下正则怎么写

这里可以先按几种简单的类型来实现,最后组装为我们想要的结果,大家也可以按自己的需求进行魔改,我们的代码逻辑大概是这个样子

typescript 复制代码
<el-input v-model="number" type="text" @input="handleInput"></el-input>
​
const number = ref()
​
const handleInput = (value) => {
    // 用来匹配的正则
    const reg = /{期望正则}/g
    // input 变量保存替换结果
    let input = value.replace(reg,'')
    // 将替换结果赋值给绑定对象
    number.value = input
}

只允许输入正整数

不允许输入0以及运算符号,eg: +,-,.

使用 \D 匹配非数字

使用 ^0 匹配首位的0

ini 复制代码
const handleInput = (value) => {
    // 匹配非数字清除
    const reg = /\D|^0/g
    let input = value.replace(reg,'')
    number.value = input
}

只允许输入整数

允许输入0,但开头不可以输入连续0,eg: 012

使用 \D 匹配非数字

使用 /^0+(\d)/ 匹配开头的连续0,并获取0后第一个数字用于替换0

ini 复制代码
const handleInput = (value) => {
    // 匹配非数字清除
    const reg = /\D/g
    let input = value.replace(reg,'')
    // 匹配开头的连续0,用第一个数字替换
    const reg1 = /^0+(\d)/
    input = input.replace(reg1, '$1')
    number.value = input
}

允许输入小数

同样不允许输入各种加减号,这里主要是首位和连续的小数点需要处理

  • 使用 [^\d.]|^. 匹配非数字和小数点之外的输入,并且首位不能是小数点

\[\] 中括号表示匹配字符类

^ 在字符类中表示取反(注意这里第一个^就不是取首位了)

\d. 表示匹配数字和小数点

ini 复制代码
const reg = /[^\d.]|^./g
let input = value.replace(reg,'')
  • 如果输入多个小数点,只保留第一个

这里借鉴一下网上的一些思路,总结来说就3步

第一步,匹配到第一个小数点,进行特殊字符的替换(这里用 $#$

ini 复制代码
input = input.replace('.', '$#$')

第二步,匹配其余所有小数点,进行删除

ini 复制代码
input = input.replace(/./g, '')

第三步,把第一步的$#$还原成小数点

ini 复制代码
input = input.replace('$#$', '.')

三步合并下

ini 复制代码
input = input.replace('.', '$#$').replace(/./g, '').replace('$#$', '.')

最终结果(加上之前的不可输入连续0)

ini 复制代码
const handleInput = (value: any) => {
    const reg = /[^\d.]|^./g
    let input = value.replace(reg,'')
    input = input.replace('.', '$#$').replace(/./g, '').replace('$#$', '.')
    const reg1 = /^0+(\d)/
    input = input.replace(reg1, '$1')
    number.value = input
}

只允许输入指定精度的数字(这里以2位为例)

到这里已经很明朗了,只需要在上面的基础上稍加修改即可

思路是对小数点两侧进行分组匹配在将结果返回

第一步,匹配小数点左侧 ^(\d+)

第二步,匹配小数点 .

第三步,匹配小数点右侧 (\d\d) (如果更多位,增加\d即可)

第四步,.*$对余下字符进行匹配,最后使用 1 , 1, 1,2 取到分组结果进行组合替换

合并下

ini 复制代码
const reg3 = /^(\d+).(\d\d).*$/
input = input.replace(reg3, '$1.$2')

最终结果

ini 复制代码
const handleInput = (value: any) => {
    const reg = /[^\d.]|^./g
    let input = value.replace(reg,'')
    input = input.replace('.', '$#$').replace(/./g, '').replace('$#$', '.')
    const reg2 = /^0+(\d)/
    input = input.replace(reg2, '$1')
    const reg3 = /^(\d+).(\d\d).*$/
    input = input.replace(reg3, '$1.$2')
    number.value = input
}

小结

看到这,相信你对输入框的限制输入需求如何实现已经有了大体的思路,也对各种常见的正则匹配小技巧有所了解了,简单梳理下

  • \d 匹配数字
  • \D 匹配非数字
  • ^ 标记第一个
  • + 匹配多个
  • [] 匹配字符串中的某一类字符
  • () 对匹配结果分组,可以使用 $ 符号获取匹配结果
  • .*$ 匹配余下所有

希望大家看完都能好好消化消化,相信不管对完成这个需求,还是加深对正则的理解,都会有所帮助的^_^

相关推荐
丑过三八线几秒前
npm 私有仓库找不到包的解决方案
前端·npm·node.js
越努力越幸运662 分钟前
Solon Flow 实战:用 50 行 YAML 实现一个请假审批流
javascript
lichenyang45314 分钟前
鸿蒙 ArkTS 电商 Demo 闭环复盘:商品列表 → 详情加购 → 全局购物车持久化
前端
甲维斯24 分钟前
Opus4.8 才是真的夯爆了!实测 9个例子表现出众!
前端·人工智能
Doris_20231 小时前
eslint
前端·架构·前端框架
_喆2 小时前
视频切片上传
前端
前端拷贝猿2 小时前
微信绑定流程
前端
ZC跨境爬虫2 小时前
跟着 MDN 学CSS day_51:支持旧浏览器的布局策略
前端·css·html·tensorflow·媒体
Larcher2 小时前
从 0 到 1:Node.js 调用 AI API 的完整避坑指南
前端·javascript·css