非捕获(?:Exp):匹配Exp部分正则表达式,但匹配的结果并不保存到捕获组,一般在验证规则时使用,因为保存捕获组都要占用一定的内存资源,而不需要保留匹配结果时,可以使用非捕获组来节省资源举例:匹配日期的正则表达式
^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))([-/.])(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})([-/.])(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[13-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$
如果都用捕获组,那会有数十个捕获组,而这个正则只是为了验证规则的,没有必要保留捕获组的内容,所以这里使用非捕获组
非回溯(?>Exp):该组匹配后,其匹配的字符不能通过回溯用于后面的表达式的匹配。
举个例子来说明吧
源字符串:www.csdn.net
正则一:\w+\.(.*)\.\w+
正则二:\w+\.(?>.*)\.\w+
正则一是可以匹配成功的,由(.*)匹配csdn,而正则二是匹配不成功的
因为在正则一中,(.*)是贪婪模式,它要一直匹配到字符串末尾,也就是csdn.net,这时发现\.\w+没有匹配到内容,而你需要明白的一点是,正则匹配的一个大前提,就是尽可能的匹配成功,这时它将会采用回溯匹配,所谓回溯,就是把(.*)匹配的结果往回推也就是由(.*)匹配csdn,而由\.\w+来匹配.net,以使整个表达式匹配成功
正则二之所以匹配不成功,是因为它是非回溯匹配,当(?>.*)匹配到末尾时,它发现没有匹配成功,因为它是非回溯的,不允许采用回溯来匹配\.\w+,所以整个表达式也就匹配不成功了
弱弱的说,用正则半年多了,几乎天天都在用,但是从来没用过非回溯匹配
同时应注意,回溯匹配是很浪费资源,效率很低的一种匹配方式,要尽量避免,如上式改为
\w+\.([^.]*)\.\w+
就可以避免回溯匹配方式了

解决方案 »

  1.   

    楼上这个问题问得好-_-#,我这里恰好有一颗,要不要试试效果$#%^&.....有些是只要了解一些语法就行了,到了必须用的时候,自然就会用上了,就像最近开始用平衡组一样,因为其它方法解决不了这个问题了其实有些方法是提供了,但并不一定就非要用到,只要把常用到的用熟了也就差不多了,比如c#的RegularExpressions命名空间中,有些类我至今都没用过,但是能用正则解决的问题,我差不多也都可以用现有的类和方法解决了