Skip to content

正则表达式应用“如何判断字符串中不包含连续重复的数字或者字母”

正则表达式是用来查找、判断、替换字符串的一类工具。是很有意思的内容。很多编程语言都支持正则表达式,而且使用形式都大同小异。

今天来判断的情况是字符串中不包含连续重复的数字或者字母,比如:

aaaa,1111,abcccc111,qqqwww,qweeeeerty,等等。

前置知识:如何学习正则

这篇文章的内容需要有正则表达式的知识,如果没学过正则表达式的同学,可以看一下这个教程,我觉得写的很好:

《正则表达式30分钟入门教程》

正则表达式用来测试也非常简单,直接打开浏览器的console界面,用Javascript测试即可: ​​

用Javascript测试只需要掌握几个函数的用法,看这个教程就可以:

https://www.runoob.com/js/js-regexp.html

下面,我们从零开始,一步一步实现我们的目标“判断字符串中不包含连续的数字或者字母”。

如何判断字符串中包含连续重复的数字或者字母?

首先是表示出任意一个数字或者字母:

reg
[a-zA-Z0-9]

或者直接\w也可以。

然后用括号括起来,让它成为一个分组:

reg
([a-zA-Z0-9])

然后再把这个分组重复3次(加上原来的一共四次):

reg
([a-zA-Z0-9])\1{3}

现在就可以检测重复4次的数字或者字母了:

​​

上面的正则中。\1表示第一个分组。但是之后正则表达式会越来越长,还会有嵌套的分组,到时候找到分组的序号可能比较困难,因此我们改为了命名分组:

reg
(?<re1>[a-zA-Z0-9])\k<re1>{3}

现在,我们就实现了判断字符串中包含连续的数字或者字母这个功能了。

如何判断字符串中不包含连续重复的数字或者字母?

上面说了包含,那么怎么判断不包含呢?

最简单的方法当然是:

reg
!(/(?<re1>[a-zA-Z0-9])\k<re1>{3}/.test('aacccaaa'))

先用上一节的方法判断包含,然后再取反就好了。

简单的应用当然可以这样做,但是如果这部分正则表达式是一个大的正则表达式的一部分呢?比如要给一个判断密码是否符合规范的正则表达式中添加”判断不包含连续重复的数字或者字母”功能呢?这时候就没办法用取反了,毕竟正则表达式基本不支持逻辑运算。因此,我们还是用正则来实现这个功能。

实现这个功能,而且还不影响正则表达式其他部分的匹配,我们要用到负向零宽断言。

首先来加一个负向零宽先行断言:

reg
(?!(?<re1>[a-zA-Z0-9])\k<re1>{3})

测试一下效果: ​​

不管用了!不管有没有重复的字符,都显示true。

再试试负向零宽后行断言:

reg
(?<!(?<re1>[a-zA-Z0-9])\k<re1>{3})

经过测试也不行。

一个先行,一个后行,是不是需要组合起来?

reg
(?!(?<re1>[a-zA-Z0-9])\k<re1>{3})(?<!(?<re2>[a-zA-Z0-9])\k<re2>{3})

(注意不同的分组名称不一样哦)

可以了? ​​

从这个结果来看,看起来只能判断字符串开头是重复的情况。

如果要任意位置都能判断呢?加入标识任意位置符号“.*”就好了。

reg
(?!.*(?<re1>[a-zA-Z0-9])\k<re1>{3})(?<!.*(?<re2>[a-zA-Z0-9])\k<re2>{3})

测试结果如下: ​​ 看来是正确的。

这样就实现了,不管在任意的位置,前面和后面都不能出现连续重复至少4个的字母或者数字。

扩展,可继续包含其他条件

在这个正则中我们还可以继续包含其他的判断条件,比如必须包含abc: ​​ 还可以把这个”必须包含abc”的条件写成零宽断言的形式,同学们可以自己试一试。