在http://www.jb51.net/article/2...网站上看到匹配日期的一个正则,表示很疑惑,没看懂,请高手指点。
^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$
匹配结果如下:
1, ?:是什么意思?
2, ?! 是什么意思?
谢邀,昨天不在,现在刚看到,首先你这个例子中的匹配表达式也太长了,匹配个日期根本不需要这么麻烦,不建议纠结这个表达式,可以找到更好的正则写法,我就你的两点问题做一个回答吧。
1.简单来说,
(?:)
就是为了分组,但是不捕获下来供正则表达式其他部分使用,就是说不能使用\1
,\2
这种捕获的子模式。举个例子
第一个匹配到了,没问题,普通的匹配
第二个就没匹配到,因为
\1
在这里无法识别,是非获取匹配第三个就匹配到了,因为
()
是获取性匹配,看后面的输出 数组中第二项是aa,匹配了这个子模式,可以供后续使用,后面的\1
就是匹配到的子模式aa。所以说(?:)的作用就是为了分组,它和()的区别在上面这个例子中已经表现出来了,至于它和普通模式的区别,就体现在分组的便利上。
上面的例子改一下:
两种写法是一样的匹配模式,但是用了分组之后,简洁了不少,这就是非获取匹配的最常用的作用
2.(?!p)是负向先行断言,意思是要求接下来的字符不与p表达式匹配,,还有一个(?=p)也一块说了吧,这个正好和?!相反,称为正向先行断言,要求接下来的字符与p表达式匹配。也就是说这里的(?:)和(?!)起的就是一个条件作用,用来判断前面的表达式满足不满足p这个条件,只有满足了才匹配,不满足就不匹配。
同样用上面类似的例子来说明:
s1匹配了pattern6,因为s1中的aa后面接着的是cd,s2匹配了pattern7,因为s1中的aa后面接着的不是cd。