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

背景

数字输入框限制其它符号的输入是一个很常见的需求,但是网上的实现方案始终离理想状态差那么一丢丢,大多会遇到两个坑,一个是 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 匹配非数字
  • ^ 标记第一个
  • + 匹配多个
  • [] 匹配字符串中的某一类字符
  • () 对匹配结果分组,可以使用 $ 符号获取匹配结果
  • .*$ 匹配余下所有

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

相关推荐
小poop4 小时前
CSS 基础与实战:从入门到精通网页美化
前端
Csvn5 小时前
运行时性能
前端
Never_every996 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck6 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
空中湖7 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了8 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒8 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师9 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端
特立独行的猫A9 小时前
10 MB 的桌面 AI 客户端:用仓颉 + 系统 WebView 替代 Electron
前端·harmonyos
修炼的dance10 小时前
白底图存JPG,sharp开mozjpeg背景杂点少近三成
前端