两条与密码验证相关的正则表达式问题
Oct 16th
- 问题1: 密码验证:由且仅由数字、字母(大小写)、特殊符号(@ % &…)组成,三者缺一不可,密码不少于8位。
- 问题2: 十位的数字、字母组合密码,其中包含4位数字和6位字母。
感兴趣的话,建议您在读下文之前,自己思考一下解法,以免被我的思路干扰。
Stage0
对于问题1,它需要满足的条件如下:
- 8位以上;
- 必须包含1位以上的数字;
- 必须包含1位以上的字母;
- 必须包含1位以上的特殊字符。
对于这样的要求,简单使用[0-9a-za-Z@%&]{8,}来匹配的。因此它也匹配像00000000、1111aaaaa这样只含一种或两种字符的字符串。因此,我们要加上更为严格的限制条件,以便匹配更精确。
Stage1
代码:
[0-9a-zA-Z@%&]+\d
字母必须出现一次,则对于每个字符位置来说,它应该是这样的:
代码:
[0-9a-zA-Z@%&]+[a-zA-Z]
特殊字符必须出现一次,则对于每个字符位置来说,它应该是这样的:
代码:
[0-9a-zA-Z@%&]+[@%&]
这三个条件必须同时满足,因此:
代码:
(?=[0-9a-zA-Z@%&]+\d)(?=[0-9a-zA-Z@%&]+[a-zA-Z])(?=[0-9a-zA-Z@%&]+[@%&]).{8,}
为了保证字符整行匹配,需要加上条件^$:
代码:
^(?=[0-9a-zA-Z@%&]+\d)(?=[0-9a-zA-Z@%&]+[a-zA-Z])(?=[0-9a-zA-Z@%&]+[@%&]).{8,}$
它匹配的是,8位(包括)以上字符,由且仅由数字、字母和特殊字符组成。
Stage2
上图中Test部分中彩色部分为正则表达所匹配的字串。但是前三条是符合要求的,却不被匹配。之所以会出现这样的情况,是因为在环视条件中使用了+量词,这会将本来用作辅助验证的字符被消耗掉,原本合格的字串被误认为不合格了。
问题出在+上,因此我们使用*量词,这样就好多了。正则表达式为:
^(?=[0-9a-zA-Z@%&]*\d)(?=[0-9a-zA-Z@%&]*[a-zA-Z])(?=[0-9a-zA-Z@%&]*[@%&]).{8,}$
匹配效果如下所示:
Stage3
但是问题依然存在。测试发现,像这样的字串也是匹配的,但是它显然不是合格的密码字串:
之所以出现这样的问题,是因为stage2代码中
.{8,}$
前边千辛万苦使用[0-9a-zA-Z@%&]所界定的条件,在这里轻轻松松被破坏了。stage2其实只管前8位,只要前8位字符符合要求,它就认为万事大吉了。
认识到这一点,我写个一条长长的正则式:
^(?=[0-9a-zA-Z@%&]*\d)(?=[0-9a-zA-Z@%&]*[a-zA-Z])(?=[0-9a-zA-Z@%&]*[@%&])[0-9a-zA-Z@%&]{8,}$
但是这条正则表达太复杂了。能不能短一些呢?当然可以。从上文可以看出,前边其实不必界定太复杂的条件,只要在最后加上条件判断即可。因此,正则表达式可以改为:
^(?=.*\d)(?=.*[a-zA-Z])(?=.*[@%&])[0-9a-zA-Z@%&]{8,}$
这样一来,我们就得到了这道题迄今为止最简洁的解法。
同理可得,第二道题的解法是:
^(?=.*\d)(?=.*[a-zA-Z])(?=.*[@%&])[0-9a-zA-Z@%&]{8,}$
不多解释。
在思考本题的过程中,感谢创亿无限在stage2的测试,感谢余晟老师在stage3中的指点。余老师现在正写一本正则表达式的傻瓜书,请点击余晟老师的博客来探寻详情。
正则表达式匹配ABCD随机字串
Dec 5th
前一段时间在chinaunix论坛上发现这样一则问题:
要求abcd四个字母连续,但每个字母有且仅出现一次,并且顺序可以不固定,也就是要匹配abcd adbc bcda等等情况
我说一下自己的解决思路。
匹配用户名的asp正则表达式(包括中文)
Jul 13th
求ASP 用户名 表达式
用户名长度在2-20字符之间,由中文/大小写字母/数字/中划线-/下线线_组成。
这个问题不算难,只要下边一行核心代码就能搞定:
"^[-_a-zA-Z0-9\u4e00-\u9fa5]{2,20}$"关键是没有使用过ASP语言。按此页的提示,设置了ASP环境。查询了一些在线的入门级ASP教程之后,解答如下: Read the rest of this entry »
[老贴整理]如何使用正则式从英文句子里提取词根
Apr 25th
以前在chinaunix回答过这样一个问题,用到了正则表达式(而且我认为正则式解决此类问题是最合适的。)
学英语的一些例句,每句都有若干词根相同的词,例如 She swears to wear the pearls that appear to be pears. 但是每句的词根都未必相同;我希望把这些包含词根的词都标记出来,请问如何写?
这里说的词根不是原本词根的定义,只是一组字母序列,比如
9. The dust in the industrial zone frustrated the industrious man.
词根是dust或ust
10. The just budget judge just justifies the adjustment of justice.
词根是dust
11. I used to abuse the unusual usage, but now I’m not used to doing so.
词根是use,有变形
12. The lace placed in the palace is replaced first, and displaced later.
词根是lace
13. I paced in the peaceful spacecraft.
词根是pace
14. Sir, your bird stirred my girlfriend’s birthday party.
词根是ir
如果您对此问题感兴趣,请独立思考后再继续阅读本站提供的解决方法。



Comments