在介绍正则表达式零宽断言这个概念之前,先看一下以下这道有关javascript
正则表达式的题目:
登录注册流程是前端最常见的业务流程之一,注册流程少不了密码强弱度校验,请实现对密码的校验,要求满足:
包含大小写字母、数字、特殊字符中的至少任意两种,长度8-32位。
什么是零宽断言
零宽断言匹配字符串而不消耗任何内容。ECMAScript
具有向前执行此操作的前向断言,但该语言缺少向后执行断言所提供的向后执行此操作的方法。通过lookbehind
断言,人们可以确保一个模式是否在另一个模式之前,例如匹配美元金额而不捕获美元符号。零宽断言是正则表达式中的难点,所以本章节重点从匹配原理方面进行一下分析。零宽断言还有其他的名称,例如”环视”或者”预搜索”等等。
匹配字符串而不消耗任何内容这句话怎么理解?来看以下两个例子:
- 正则匹配abc后面的大写字母:
const str="abcDEF"; const reg=/abc([A-Z])/; console.log(str.match(reg)[1]); // D, 最终匹配结果(match[0])是"abcD" /abc([A-Z])/.test('abcD'); // true /abc([A-Z])/.test('abcd') // false
- 使用正向肯定预查匹配abc后面的大写字母:
const str="abcDEF"; const reg=/abc(?=[A-Z])/; console.log(str.match(reg)[1]); // undefined, 最终匹配结果(match[0])是"abc",因为零宽断言"(?=[A-Z])"并不匹配任何字符,只是用来规定当前位置的后面必须是一个大写字母。 /abc(?=[A-Z])/.test('abcD'); // true /abc(?=[A-Z])/.test('abcd'); // false
正向肯定预查 x(?=y)
表示x只有在y前面的情况才匹配成功,它匹配后面紧跟着指定模式的位置,但不包含该模式,表达式foo(?=bar)
匹配在”foobar”中的”foo”,但不匹配服务器托管网“foobar”中的”bar”。例如,
/d+(?=%)/.test('100% of US presidents have been male'); // true
这里d+只在百分号%前匹配数字,所服务器托管网以成功匹配到100。
正向否定预查 x(?!y)
表示x只有在y后面的情况才匹配成功,它匹配后面紧跟着不是指定模式的位置,表达式foo(?!bar)
匹配在”foobaz”中的”foo”,但不匹配”foobar”中的”foo”。例如:
/d+(?!%)/.test('that’s all 44 of them'); // true
这里d+只在不在%前匹配数字,所以成功匹配到44。
反向肯定预查 (?
表示x只有不在y前面的情况才匹配成功,它匹配前面紧跟着指定模式的位置,但不包含该模式,表达式(?匹配在"foobar"中的"bar",但不匹配"foobar"中的"foo"。例如:
/(?这里d只在Python后匹配数字,所以成功匹配到2。
反向否定预查 (?
表示x只有不在y后面的情况才匹配成功,它匹配前面紧跟着不是指定模式的位置,表达式
(?匹配在"bazbar"中的"bar",但不匹配"foobar"中的"bar"。例如:
/(?这里d+只在不在Java后匹配数字,所以成功匹配到2和3。
校验密码格式
回顾开头的校验密码格式的问题,可以拆解成两步:1. 包含大小写字母、数字、特殊字符中的至少任意两种;2. 满足长度8-32位;
其中第二步的要求很容易得到:
const PASSWORD_LENGTH_EXP = /^.{8,32}$/ /^.{8,32}$/.test('123456781234567812345678123456781') // false /^.{8,32}$/.test('12345678') // true /^.{8,32}$/.test('1234567') // false解释:
/^.{8,32}$/
用于匹配一个长度在8到32之间的任意字符序列。
-
^
表示匹配字符串的开始位置。 -
.
表示匹配除了换行符之外的任意字符。 -
{8,32}
表示前面的模式(.
)要重复出现8到32次。 -
$
表示匹配字符串的结束位置。
那么如何用正则表示大小写字母、数字、特殊字符中的至少任意两种搭配组合呢?其实换个思路来想这个问题就比较好解了,
大小写字母、数字、特殊字符中的至少任意两种搭配可以是:
- 字符串结尾不包含除了字母、数字和特定符号之外的字符。
(?!.[^A-Za-z0-9#?!@$%^&-.]$) 使用正向否定预查,断言字符串结尾不包含除了字母、数字和特定符号之外的字符。
- 字符串不仅由小写字母组成
(?![a-z]$) 使用正向否定预查,确保字符串不仅由小写字母组成。
- 字符串不仅由大写字母组成。
(?![A-Z]$) 使用正向否定预查,确保字符串不仅由大写字母组成。
- 字符串不仅由数字组成。
(?![0-9]$) 使用正向否定预查,确保字符串不仅由数字组成。
- 字符串不仅由特定符号组成。
(?![#?!@$%^&-.]*$) 使用正向否定预查,确保字符串不仅由特定符号组成。
因此,最终的表达式可以是:
const PASSWORD_REG = /^(?!.*[^A-Za-z0-9#?!@$%^&*-.]$)(?![a-z]*$)(?![A-Z]*$)(?![0-9]*$)(?![#?!@$%^&*-.]*$).{8,32}$/
可以优化的一个点是可以丰富一下特殊字符的限定范围。
总结
四种零宽断言在处理一些匹配规则时非常有用,可以让正则表达式的匹配更加精确。当需要进行复杂的文本解析处理时,熟练运用零宽断言可以大大提高工作效率。
技术前沿拓展
前端开发,你的认知不能仅局限于技术内,需要发散思维了解技术圈的前沿知识。细心的人会发现,开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。
介绍一款程序员都应该知道的软件JNPF 快速开发平台,很多人都尝试用过它,它是功能的集大成者,任何信息化系统都可以基于它开发出来。 这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,实现快速开发,提升工作效率;框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用;后端框架支持 Vue2、Vue3。
如果你有闲暇时间,可以做个知识拓展。 看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
相关推荐: [office] Excel中表格联系方式导入手机的操作方法
将excel或者电子表格服务器托管网中的通讯录或者是其它数据批量的导入到手机通讯录当中。具体该怎么去操作的呢?今天,小编就教大家在Excel中表格联系方式导入手机的操作方法。 Excel中表格联系方式导入手机的操作步骤如下: 用Excel编辑好联系…