有关正则表达式中非捕获组的网上总结和个人见解[zz]
正则表达式是个极其麻烦的东西,这篇博文对非捕获组的讲解比较详细。
(另捕获组讲解http://blog.csdn.net/lxcnn/article/details/4146148)
转自http://blog.sina.com.cn/s/blog_5a6f39cf0100n9ki.html
看到7.3.4 非捕获性分组这里,书上说非捕获性分组不会创建反向引用,下面是例子:
var sToMatch = “#123456789″;
var reNumbers = /#(?:\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1);
这里alert输出是空的。
var sToMatch = “en-us rv:0.9.4″;
var reNumbers = /rv:(\d+\.\d+(?:\.\d+)?)/;
var result = reNumbers.test(sToMatch);
alert(RegExp.$1);
这里alert输出就成了0.9.4。
最后那个.4是非捕获性分组捕获到的。这里就奇怪了,为什么前面的非捕获性分组不能捕获,而嵌套的非捕获性分组就又可以捕获了?而且这里好像不用非捕获性分组照样可以达到相同的目的,为什么要用非捕获性分组呢?
解答一:
因为RegExp.$1取的是第一个捕获组而且.4包含在第一个捕获组中,所以取RegExp.$1时可以取到。而.4所在的第二个组是非捕获组,当取RegExp.$2的时候.4是取不到的。
如果改成:var reNumbers = /rv:(\d+\.\d+(\.\d+)?)/;则RegExp.$2是.4。上面问题中的(?:\.\d+)是非捕获组,内存不会保存你取到的值。所以RegexExp的组中应该就没有$2这一个值。RegExp.$2取到的是空的。
反向引用的时候(\d+\.\d+(?:\.\d+)?)–\1 这里是反向引用第一个捕获组,匹配–前后都一样的字符串。而(\d+\.\d+(?:\.\d+)?)–\2 是有错误的,因为第二个组是非捕获的,内存上就没有第二个组的内容,所以引用失败。
解答二:
要了解非捕获组就要先了解捕获组,之后再了解为什么会有非捕获组的出现。简单点说,捕获组就是把()中匹配到的内容保存到一个按“(”出现的顺序编号的组里,以供后续引用,引用的方式有反向引用,或是RegExp.$number等方式,不同的语言,支持的引用方式不同。
只要使用了(),默认为使用了捕获组,而这就带来一个问题,有些场景不得不使用(),但又不关心它匹配到的内容,比如写一个匹配24小时制HH:mm:ss的时间的正则如下:([01][0-9]|2[0-3])(:([0-5][0-9])){2},通常关心的只是整体的时间,并不关心局部的内容,这样就产生了一种副作用,将不关心的内容单独保存到内存中,只会浪费资源,降低效率。非捕获组就是为了抵消这一副作用来产生的,非捕获组只参与匹配,但不会把匹配到的内容捕获到组里。所以非捕获组根本就不参与编号,也就无从谈起它对应哪个$number。在取不存在的编号的捕获组时,有些语言会返回空字符串,有些语言会报异常。
(\d+\.\d+(?:\.\d+)?)中,整体是一个捕获组,按“(”出现的顺序,编号为1,(?:\.\d+)虽然是非捕获组,也是要参与匹配的,只是不将匹配结果单独保存到组里而已。
还需要说明的是,在绝大多数语言中,正则表达式整体对应的是$0,捕获组的编号是从1开始的。
本人见解:
本人在网上看到这个问题以及相关解答后,把所有的答案总结了一下,分成这两类。本人倾向于解答二,认为非捕获组不参与编号,没有对应的$number,也就肯定取不到值了。在取不存在的编号的捕获组时,有些语言会返回空字符串,有些语言会报异常。
本人为此试验了一下,在flashdevelop下编译代码:
var re:RegExp = /(i|you|he|she|it|we|they) likes? to (\w+)/i; //标示为句M
var match:Object = re.exec(“We like to party.”);
trace(match); //标示为句N
结果返回:We like to party,We,party(从显示结果可以看出match中含有三个元素,用’,'隔开)
然后把句M改成:var re:RegExp = /(i|you|he|she|it|we|they) likes? to (?:\w+)/i;
结果返回:We like to party,We(此时match中只含有两个元素了)
然后把句N改成:trace(match[2]);
结果返回:undefined(说明match中第三个元素没有定义)
然后把句M改成:var re:RegExp = /(?:i|you|he|she|it|we|they) likes? to (?:\w+)/i;
结果返回:We like to party(此时match中只含有一个元素了)
然后把句N改成:trace(match[1]);
结果返回:undefined(说明match中第二个元素没有定义)
从上述实验结果来看,非捕获组确实不参与编号,不在内存保存。并且在flashdevelop中如果非法访问不存在的元素,不会报异常,但是会显示undefined(这只是flashdevelop的效果,其他软件是报错还是怎么我就不知道了。)
说点啥吧
页面
腾讯微博
文章标签
营销 倒计时 avatar 三维数字 homestyler 北大关机门 翻墙 Matrix 收录 正则表达式 apple 图片检索 Adobe WP 31号 成人玩具 代理 roxik shoe obj flower puzzle 源码 google java3d 平面设计 人脸识别 Google Map Flash3D 全景 优化 Away3D Alternativa3D Flash网站 Tips最新评论
- Hsinglin 在 发几个今天在校园里拍的全景图 上的评论
- Rming 在 实验室360全景图 上的评论
- 哪种减肥药效果好 在 发几个今天在校园里拍的全景图 上的评论
- jianhualee 在 新作品flash网站-至尊数码-3D图墙 上的评论
- panda 在 away3d中的obj 上的评论




