前言
昨天写了从一个数字输入框开始入门正则,今天趁热打铁,也是一个大家常见的需求,实现一个密码输入框识别代码强度,来巩固一下我们的正则知识点
思路
遇到一个需求,我们还是老方法,先拆解,在分步解决
首先我们把密码复杂度分为简单 ,中等 ,安全三个等级,然后再对每个等级进行定义,通常我们的定义标准为
- 简单
纯数字 、纯英文、纯符号
- 中等
包含两种简单的组合(数字+英文、数字+符号、英文+符号)
- 安全
包含数字,英文,符号三种类型
把规则捋清楚后,我们就可以开始编码了,先来个输入框的简单代码模板(完整代码有需要可看文章最下面),借用一下 elementUI
的表单校验
xml
<template>
<div class="wrapper">
<el-form :model="formData" ref="ruleFormRef" :rules="rules">
<el-form-item prop="password">
<el-input type="text" v-model="formData.password" spellcheck="false"></el-input>
<div class="intensity">
<span class="pwdInfo">密码强度</span>
<span class="line" :class="[level.includes('low') ? 'low' : '']"></span>
<span class="line" :class="[level.includes('middle') ? 'middle' : '']"></span>
<span class="line" :class="[level.includes('high') ? 'high' : '']"></span>
</div>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref } from 'vue'
const formData = ref({
password: ''
})
const ruleFormRef = ref()
const rules = ref({
password: [
{
validator: checkPassword,
trigger: 'change'
}
]
})
const level = ref([])
function checkPassword(rule, value, callback) {
level.value = []
if (!value) {
return callback(new Error('请输入密码'))
}
callback()
}
</script>
实现
现在开始功能实现,我们按照简单,中等,安全的顺序来一步一步实现
简单
因为是全匹配,我们会用到 ^规则$
来进行从头到尾匹配,然后使用 +
对前面的规则进行多次匹配
- 全部为数字,规则
\d
javascript
const regNum = /^\d+$/
- 全部为字母,规则
[a-zA-Z]
巩固下,中括号
[规则]
用来匹配某一类型的字符
javascript
const regLetter = /^[a-zA-Z]+$/
- 全部为符号,这里用到了取反,整个需求的实现取反的应用非常多,这也是我们在使用正则匹配过程中需要注意的,有时会正向搞不定不妨试试逆向思维
这里匹配非数字和非字母,同样运用到了 []
中括号,里面的 ^
表示取反
javascript
const regSymbol = /^[^a-zA-Z0-9]+$/
初步结果
javascript
function checkPassword(rule, value, callback) {
level.value = []
if (!value) {
return callback(new Error('请输入密码'))
}
// 全部为数字
const regNum = /^\d+$/
// 全部为字母
const regLetter = /^[a-zA-Z]+$/
// 全部为符号
const regSymbol = /^[^a-zA-Z0-9]+$/
// 满足一种,为简单
if (regNum.test(value) || regLetter.test(value) || regSymbol.test(value)) {
level.value = ['low']
}
callback()
}
中等
接下来到了中等,实际上如果直接想判断是否包含两种是比较麻烦的,好在我们有上一步的基础,已经把只包含一种类型字符的情况过滤了出来,那剩下的就简单了,直接匹配两种类型规则的并集就可以了
主要思路还是使用 [ 规则 ]
来进行类型匹配
- 数字 + 英文
0-9
匹配数字,a-zA-Z
匹配英文
javascript
const regNumAndLetter = /^[0-9a-zA-Z]+$/
- 数字 + 符号
这里使用取反,不是英文那就是数字+符号,即 ^a-zA-Z
javascript
const regNumAndSymbol = /^[^a-zA-Z]+$/
- 英文 + 符号
还是利用取反,不是数字和就是英文+符号,即 ^a-zA-Z
javascript
const regLetterAndSymbol = /^[^0-9]$/
安全
都到这一步了,就将取反思维贯彻到底就好了,既然上边的校验都不通过,自然现在的密码就是安全等级最高的了
小结
本篇也算是对正则的简单应用,希望和昨天从一个数字输入框限制符号输入开始到正则入门 - 掘金 (juejin.cn)两个案例下来,大家对简单的需求都可以自己上手写正则了,本篇实现的也算是一个常用功能,源码附上,有需要的同学自取
代码
xml
<script setup>
import { ref } from 'vue'
const formData = ref({
password: ''
})
const ruleFormRef = ref()
const rules = ref({
password: [
{
validator: checkPassword,
trigger: 'change'
}
]
})
const level = ref([])
function checkPassword(rule, value, callback) {
level.value = []
if (!value) {
return callback(new Error('请输入密码'))
}
// 全部为数字
const regNum = /^\d+$/
// 全部为字母
const regLetter = /^[a-zA-Z]+$/
// 全部为符号
const regSymbol = /^[^a-zA-Z0-9]+$/
// 数字 + 英文
const regNumAndLetter = /^[0-9a-zA-Z]+$/
// 数字 + 符号
const regNumAndSymbol = /^[^a-zA-Z]+$/
// 英文 + 符号
const regLetterAndSymbol = /^[^0-9]$/
// 满足一种,为简单
if (regNum.test(value) || regLetter.test(value) || regSymbol.test(value)) {
level.value = ['low']
} else if (regNumAndLetter.test(value)) {
// 数字 + 英文
level.value = ['low', 'middle']
} else if (regNumAndSymbol.test(value)) {
// 数字 + 符号
level.value = ['low', 'middle']
} else if (regLetterAndSymbol.test(value)) {
// 英文 + 符号
level.value = ['low', 'middle']
} else {
level.value = ['low', 'middle', 'high']
}
callback()
}
</script>
<template>
<div class="wrapper">
<el-form :model="formData" ref="ruleFormRef" :rules="rules">
<el-form-item prop="password">
<el-input type="text" v-model="formData.password" spellcheck="false"></el-input>
<div class="intensity">
<span class="pwdInfo">密码强度</span>
<span class="line" :class="[level.includes('low') ? 'low' : '']"></span>
<span class="line" :class="[level.includes('middle') ? 'middle' : '']"></span>
<span class="line" :class="[level.includes('high') ? 'high' : '']"></span>
</div>
</el-form-item>
</el-form>
</div>
</template>
<style scoped>
.intensity {
display: flex;
align-items: center;
}
.intensity .pwdInfo {
font-size: 14px;
margin-right: 10px;
}
.intensity .line {
display: inline-block;
width: 48px;
height: 4px;
background: #d8d8d8;
border-radius: 3px;
margin-right: 8px;
}
.intensity .low {
background: #f4664a;
}
.intensity .middle {
background: #ffb700;
}
.intensity .high {
background: #2cbb79;
}
</style>