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

背景

数字输入框限制其它符号的输入是一个很常见的需求,但是网上的实现方案始终离理想状态差那么一丢丢,大多会遇到两个坑,一个是 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即可)

第四步,.*$对余下字符进行匹配,最后使用 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 , 1, </math>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 匹配非数字
  • ^ 标记第一个
  • + 匹配多个
  • [] 匹配字符串中的某一类字符
  • () 对匹配结果分组,可以使用 $ 符号获取匹配结果
  • .*$ 匹配余下所有

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

相关推荐
快乐点吧6 分钟前
【前端】异步任务风控验证与轮询机制技术方案(通用笔记版)
前端·笔记
pe7er33 分钟前
nuxtjs+git submodule的微前端有没有搞头
前端·设计模式·前端框架
七月的冰红茶41 分钟前
【threejs】第一人称视角之八叉树碰撞检测
前端·threejs
爱掉发的小李1 小时前
前端开发中的输出问题
开发语言·前端·javascript
Dolphin_海豚1 小时前
一文理清 node.js 模块查找策略
javascript·后端·前端工程化
祝余呀1 小时前
HTML初学者第四天
前端·html
浮桥3 小时前
vue3实现pdf文件预览 - vue-pdf-embed
前端·vue.js·pdf
七夜zippoe3 小时前
前端开发中的难题及解决方案
前端·问题
晓13134 小时前
JavaScript加强篇——第七章 浏览器对象与存储要点
开发语言·javascript·ecmascript
Hockor4 小时前
用 Kimi K2 写前端是一种什么体验?还支持 Claude Code 接入?
前端