这文是上个月开始写的,本来想深入的分析一下零宽断言,可惜工作一直忙,现在又要去转战DWR…OMG~~
起因
将要上线的系统中有一个字符规则:“13位的字符串,其中有8位连续数字”,需要用这则表达式对这个字符串进行判断。而我之前对正则的认识仅仅停留在匹配固定的字符上 ,对这个问题一筹莫展。
这时候热心的小邪出现了,我在他的博客 邪罗刹的菠萝阁 留下这个[问题](http://www.evlos.org/2010/01/05/use-regex-to-clear-the-mix-of-tag- img/#comment-5968)
小邪很热心的撰写了一篇文章给出回答: 一个杯具和一个洗具与最近学习手记 : 邪罗刹的菠萝阁。
解答
核心字符串如下: ‘/^(?!(.?d){9,})(?!(.?D){6,}).{13}$/’;
小邪的文章给了很详细的解答,比我自己解释要好得多~我就索性copy过来,如下:
小邪是这个样子解答的,首先两边的斜杠是 Perl 正则式的要求。
然后两边的 ^ 和 $ 用来表示对应的是字符串的开始和结束。
接着
.{13}
,. 表示除了换行以外的所有字符,13
规定了匹配长度。
我们这里前面用了两次零宽断言,第一次,
(?!exp)
这里的 exp 是(.*?d){9,}
。
表示数字的个数大于等于 9,零宽断言把它反过来就是数字的个数小于 9。
第二次 exp 是
(.*?D){6,}
表示非数字大于等于 6 个以上。
即表示非数字的个数大于等于 6,把它反过来就是非数字的个数小于 6。
而这里
.*
表示?d
和?D
的前面可能有零次或更多次的其他字符。
而这里的
?
表示这段连续的字符会重复零次或一次。
Python下的实现和测试代码
import re
def fun(p, datas):
for data in datas:
print p.match(data)
if __name__ == '__main__':
p = re.compile(r'^(?!(.*?d){9,})(?!(.*?D){6,}).{13}$');
datas = ['asss13336644ss', 'aas15151515ss', 'aa15151515sss',
'aa15151515ss1', 'aa15151515ss11', 'aa151515151ss',
'aa15151511ssss']
fun(p, datas)
恩,问题解决了,不过,如果想把零宽断言彻底搞清楚,还需要深入学习一下~
深入零宽断言
正则表达式的零宽断言的一个小应用 - 楼兰之风… - 博客园
正则表达式–零宽断言 - panhf2003的专栏 - CSDN博客
原文链接: 正则表达式中的零宽断言 | Log4D
3a1ff193cee606bd1e2ea554a16353ee
欢迎关注我的微信公众号:窥豹