概览
在前端开发中,经常需要进行表单校验,尤其是对于复杂的校验,正则的应用更是个绕不开的话。下面主要从开头和结尾条件如何限制、匹配符合条件的长度限制、至少包含一个符合条件、校验提示精确到具体的校验 四种场景去展开梳理。
一. 开头和结尾条件限制
需满足的条件如下:
- 以a开始;
- 以6结束
示例代码
const data = 'a1131313r316'
const reg = /^a.*6$/
const isRegTest = reg.test(data);
console.log(isRegTest,'isRegTest') // true
注意点:
(1) 如果开始和结束的字符不只一个的话或者是一个集合的话,就需要不同的写法
- 开始和结束的字符不只一个。
比如希望以a2开始,以6结束‘’
const reg = /^(a2).*6$/
()包裹的是具体的内容
- 开始和结束的字符只有一个,但是可能的值有很多,比如
const reg = /^[a2].*6$/
这个正则说明:可以以a开头,也可以以2开头。
拓展:
[]前面如果加上^,指的是排除 ^后面的值,例如
const reg = /^[^a2].*6$/
开头条件:不以a或者2开头的值都可以满足开头条件。
结束相关约束同开始条件。
(2) 关于 开始(^)和结束($)
- ^和$都没有
const data = '99aaaA1233@60';
const reg= /aa/;
const isTestMatch = reg.test(data);
console.log(isTestMatch,'isTestMatch') // true
指的是字符串中包含aa就行,不检验aa出现的位置
- 只加^
const data = '99aaaA1233@70';const reg= /a0$/;const isTestMatch = reg.test(data);console.log(isTestMatch,'isTestMatch') // false
虽然满足了以0结束的条件,但是字符串0前面没有a,所以正则打印为false。
比如修改如下,就可以打印为true
const data = '99aaaA1233@70';const reg= /70$/;const isTestMatch = reg.test(data);console.log(isTestMatch,'isTestMatch') // true
二. 匹配符合条件的长度限制
(1). 基础示例
const data = '99aaaA1233@70';
console.log(data.length) //13
const reg= /.{13,15}/;const isTestMatch = reg.test(data);console.log(isTestMatch,'isTestMatch') // true
{ minLength, maxLength};
{}前面是匹配查找的条件,比如.{13,15}指的是查找data所有类型字符串的长度。
.后面的是匹配的个数
举例如下:
a*: 匹配任意多个a;
a+: 匹配至少一个a;
a?: 匹配0或1个a;
a{1,8}: 匹配1到8个a
相关知识具体可以查看正则表达式系列(贪婪和非贪婪模式),在此就不赘述。
(2). 匹配到的个数和匹配条件相关联
const data = '99aaaA1233@70';
console.log(data.length) //13
const reg= /99.{13,15}/;const isTestMatch = reg.test(data);console.log(isTestMatch,'isTestMatch') // false
修改正则之后,会打印false,是因为99后面的所有类型的字符串的个数只有11个了,所以{13,15}的条件是不满足的。
三. 至少包含一个符合条件
其中,主要用到正向肯定预查,可查阅往期文章正则表达式系列(模板替换,预查,不捕获),
举个例子:
比如需要满足如下条件;
- 至少包含一个数字;
- 至少包含一个小写英文字母;
- 至少包含一个英文字母
代码示例
const data = '99aaaA1233@70';
// 至少包含一个数字
const hasDigit = '(?=.*[0-9])'// 至少包含一个小写英文字母
const hasLower = '(?=.*[a-z])'// 至少包含一个大写英文字母
const hasUpper = '(?=.*[A-Z])'const reg = new RegExp(`${hasDigit}${hasLower}${hasUpper}`);const isMatchData = reg.test(data);console.log(isMatchData,'isMatchData') // true
正向肯定预查符合我们输入的规律,从左往右进行查询。
四. 校验提示精确到具体的校验
const vaildatePassword = (rule, value, callback) => {// 匹配至少一个数字const hasDigit = '(?=.*\\d)';// 匹配至少一个小写字母const hasLowercase = '(?=.*[a-z])';// 匹配至少一个大写字母const hasUppercase = '(?=.*[A-Z])';// 匹配至少一个特殊字符const hasSpecialChar = '(?=.*[!@#$%^&*()_+])';// 匹配长度为8到16位的数字、大小写字母和特殊字符const pattern = '[0-9a-zA-Z!@#$%^&*()_+]{8,16}';const reg = new RegExp(`^${hasDigit}${hasLowercase}${hasUppercase}${hasSpecialChar}${pattern}$`);if (!reg.test(value)) {callback(new Error('请输入包含数字、大小写字母和特殊字符及长度为8到16位的密码'));} else {callback();}
};
这个验证校验时可以提示其应该具备的校验条件,但是没有精确支出输入的内容不符合什么校验条件,不利于引导用户正确输入。
可以修改如下:
const vaildatePassword = (rule, value, callback) => {// 匹配至少一个数字const hasDigit = /(?=.*\d)/;// 匹配至少一个小写字母const hasLowercase = /(?=.*[a-z])/;// 匹配至少一个大写字母const hasUppercase = /(?=.*[A-Z])/;// 匹配至少一个特殊字符const hasSpecialChar = /(?=.*[!@#$%^&*()_+])/;// 匹配长度为8到16位的数字、大小写字母和特殊字符const pattern = /[0-9a-zA-Z!@#$%^&*()_+]{8,16}/;if(!hasDigit.test(value)) {callback(new Error('至少一个数字'))} else if(!hasLowercase.test(value)) {callback(new Error('至少一个小写字母'))} else if(!hasUppercase.test(value)) {callback(new Error('至少一个大写字母'))} else if(!hasSpecialChar.test(value)) {callback(new Error('至少一个特殊字符'))} else if(!pattern.test(value)) {callback(new Error('匹配长度为8到16位的数字、大小写字母和特殊字符'));}};
代码优化:
- if判断等优化
const vaildatePassword = (rule, value, callback) => { // 使用一个正则表达式来匹配密码的复杂性要求 // 密码需包含至少一个数字、一个小写字母、一个大写字母和一个特殊字符,且长度为8到16位 const pattern = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+])[0-9a-zA-Z!@#$%^&*()_+]{8,16}$/; if (!pattern.test(value)) { // 根据不同的失败情况返回不同的错误信息 if (!/\d/.test(value)) { callback(new Error('至少一个数字')); } else if (!/[a-z]/.test(value)) { callback(new Error('至少一个小写字母')); } else if (!/[A-Z]/.test(value)) { callback(new Error('至少一个大写字母')); } else if (!/[!@#$%^&*()_+]/.test(value)) { callback(new Error('至少一个特殊字符')); } else { callback(new Error('密码必须为8到16位,且包含数字、小写字母、大写字母和特殊字符')); } } else { callback(); }
};
主要优化点如下:
将所有的正则表达式要求合并到一个正则表达式中,减少了多次调用test方法。