死磕JavaScript正则表达式(四)
发布在每天学点javascript2014年4月3日view:5595
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

死磕JavaScript正则表达式(四)

睽违已久的JavaScript正则表达式小学堂又回来啦,不知道新同学老同学还记不记得前面三篇“死磕”究竟讲了些什么内容。如果不记得的话,可以回头去快速浏览前面三章的内容,温故而知新,JavaScript也是图样图森破。

在本片文章中,我们将揭开JavaScript正则表达式的神秘面纱,看看正则表达式究竟是怎样进行字符串搜索的。

我们首先来看一个简单的例子:

用正则表达式/”.*”/g来匹配字符串’a “witch” and her “broom” is one’得到的结果会是什么?

我们来运行下面的代码:

/".*"/.exec('a "witch" and her "broom" is one');  

得到的结果是”witch” and her “broom”,而不是我们想象中的”witch”以及”broom”。

这是因为,在正则表达式都具有贪婪性(greedyness)。在默认情况下,正则表达式都是默认开启贪婪模式 ,就像进了38元吃到饱的自助餐厅,非要拿到最多才觉得够本。

正则表达式的搜索算法

JavaScript中的正则引擎都是从字符串的位置0开始,然后不断的向后进行匹配。

为了说清楚正则表达式的搜索算法,我们将使用上面的例子来一步一步说明。

  1. 首先,正则引擎在第三个字符的位置找到了正则表达式中的’”’符号,于是开始匹配:

#图1

  1. 接下来,正则引擎开始匹配正则表达式的下一个字符,因为下一个字符.代表任何字符,因此正则引擎将它匹配到了字符’w’:

#图2

  1. 因为在正则表达式中.字符后面带有*字符,这表示0到无穷个字符,因此正则引擎就一直重复匹配任意字符:

#图3

  1. 正则引擎会一直匹配到字符结束为止,但是此时它发现,字符串结束了,但是最后一个字符居然不是’”’而是’e’,匹配失败了肿么办:

#图4

  1. 此时正则引擎会后退一步,看看前一个是不是’”’,结果发现居然是’n’,又失败了:

#图5

  1. 但是正则君没有被失败吓倒,而是越挫越勇,知道它找到了一个’”’ ,终于成功了:

#图6

  1. 此时我们已经得到了结果,但是由于正则表达式中指明了全局匹配,因此正则引擎还不会停下来,它会继续往下开始匹配,直到字符串结束为止。

在默认的贪婪模式中,正则引擎会尽可能多的匹配字符。

懒惰模式

有了贪婪模式就有懒惰模式,如果说贪婪模式就好比2008年的股民,看着大盘升上了6000点依然不满足,还盼望着“专家”口中的10000点。那么懒惰模式就像是一个谨小慎微的人,见好就收,具体体现在正则表达式中,就是只要匹配到了,马上返回结果。

开启懒惰模式的方法非常简单,只需要在原来的正则表达式后面添加一个”?”符号就可以,具体到上面的例子,代码如下所示:

var exp = /".*?"/g;
'a "witch" and her "broom" is one'.match(exp); 

我们将得到:[””witch””, ””broom””]

非常简单对不对,so easy!

我们再来看两个例子:

例1:

" item 1a".match(/\d\w?/)结果是什么?

要注意的是,这里的?可不是用来开启懒惰模式的,而是用来表示0个或1个,和{0,1}等价,于是我们得到的结果是”1a”。

例2:

" item 1a".match(/\d\w??/)结果是什么?

这里的第二个?是用来开启懒惰模式,因此\w?会匹配最少的可能性,即0个。因此我们得到的结果是”1”。

再来一个例子:

例3:

"123 456".match(/\d+ \d+?/)结果是什么?

前面的\d+用来匹配1个以上的连续数字,中间有一个空格,后面的\d+?开启了懒惰模式,于是它只匹配最少的字符,即1个数字。于是我们得到的结果是”123 4”。

一些替代的方法

对于我们最一开始讲的例子,我们也可以用其他的替代方法:

'a "witch" and her "broom" is one'.match(/"[^"]*"/g);

结果为”witch” and her “broom”,其中的字符集[^”]表示非’”’的任意字符,后面的表示任意多数量的字符,于是这个正则表达式的意思就是两边有双引号,中间任意多个字符的字符串。因为正则引擎默认是贪婪的,于是它就会匹配尽可能多的字符。如果要开启懒惰模式,在后面加上?即可。

看到这里,相信你一定对正则表达式的贪婪模式和懒惰模式有了一定了解,但是这还远远不够,练习是最好的老师。相信在“死磕”系列的帮助之下,加上你的勤奋,小小的正则一定不在话下,下个章节再见!


本文参考自JavaScript.info,原文地址http://javascript.info/tutorial/greedy-and-lazy

如果你觉得本文对你有帮助,请为我提供赞助 https://me.alipay.com/jabez128

评论
发表评论
3年前

4年前

赞个

WRITTEN BY
张小俊128
Intern in Baidu mobile search department。认真工作,努力钻研,期待未来更多可能。
TA的新浪微博
PUBLISHED IN
每天学点javascript

javascript进阶级教程,循序渐进掌握javascript

我的收藏