1.贪婪匹配(greedy)
它会匹配尽可能多的字符。它首先看整个字符串,如果不匹配,对字符串进行收缩;遇到可能匹配的文本,停止收缩,对文本进行扩展,当发现匹配的文本 时,它不着急将该匹配保存到匹配集合中,而是对文本继续扩展,直到无法继续匹配 或者 扩展完整个字符串,然后将前面最后一个符合匹配的文本(也是最长的)保存起来到匹配集合中。所以说它是贪婪的。
光看上面的定义,我们很难有一个生动的认识,现在假设我们要匹配下面 <b>和</b> 之间的文本。为了做演示,尽管不符合 HTML 的定义,我们再加入一段<b>和</c>之间的文本:
nowamagic.net is a <b>good</b> website to <b>learn</b> IT <b>skills</c>.
效果演示
nowamagic.net is a
good website to
learn IT
skills.
本例代码
3 | var test = document.getElementById( "test" ); |
5 | var regex = new RegExp( "(" +aim+ ")" , "g" ); |
6 | test.innerHTML = test.innerHTML.replace(regex, "<span style='background-color:orange'>$1</span>" ); |
这样匹配显然不是我们的初衷,它仅找到了一个匹配,而通常情况下,我们希望得到的是<b>junior</b> 和 <b>living</b> 两个匹配。
贪婪匹配的匹配过程
02 | nowamagic.net is a <b>good</b> website to <b>learn</b> IT <b>skills</c>. |
04 | owamagic.net is a <b>good</b> website to <b>learn</b> IT <b>skills</c>. |
06 | wamagic.net is a <b>good</b> website to <b>learn</b> IT <b>skills</c>. |
09 | <span style= "background-color:orange" ><</span>b>good</b> website to <b>learn</b> IT <b>skills</c>. |
11 | <span style= "background-color:orange" ><b</span>>good</b> website to <b>learn</b> IT <b>skills</c>. |
13 | <span style= "background-color:orange" ><b></span>good</b> website to <b>learn</b> IT <b>skills</c>. |
15 | //找到一个匹配,但是并不保存到结果集中,而是继续进行扩展 |
16 | <span style= "background-color:orange" ><b>good</b></span> website to <b>learn</b> IT <b>skills</c>. |
17 | <span style= "background-color:orange" ><b>good</b> </span>website to <b>learn</b> IT <b>skills</c>. |
19 | <span style= "background-color:orange" ><b>good</b> website to <b>learn</b></span> IT <b>skills</c>. |
20 | //字符串结束,将前面找到的最后一个匹配 <b>good</b> website to <b>learn</b> 保存到匹配结果集中 |
2.惰性匹配
惰性匹配(lazy)
它会匹配尽可能少的字符,它从第一个字符开始找起,一旦符合条件,立刻保存到匹配集合中,然后继续进行查找。所以说它是懒惰的。
还是这个例子:
nowamagic.net is a <b>good</b> website to <b>learn</b> IT <b>skills</c>.
效果演示
nowamagic.net is a
good website to
learn IT
skills.
本例代码
3 | var test = document.getElementById( "test" ); |
5 | var regex = new RegExp( "(" +aim+ ")" , "g" ); |
6 | test.innerHTML = test.innerHTML.replace(regex, "<span style='background-color:orange'>$1</span>" ); |
这样匹配显然不是我们的初衷,它仅找到了一个匹配,而通常情况下,我们希望得到的是<b>good</b> 和 <b>learn</b> 两个匹配。
解决的办法,就是上面说到的惰性匹配,它的语法如下表所示:
贪婪匹配 | 惰性匹配 | 匹配描述 |
? | ?? | 匹配 0 个或 1 个 |
+ | +? | 匹配 1 个或多个 |
* | *? | 匹配 0 个或多个 |
{n} | {n}? | 匹配 n 个 |
{n,m} | {n,m}? | 匹配 n 个或 m 个 |
{n,} | {n,}? | 匹配 n 个或多个 |
对于本例,当我们再使用惰性匹配。
效果演示
nowamagic.net is a
good website to
learn IT
skills.
惰性匹配的匹配过程
04 | nowamagic.net is a <span style= "background-color:orange" ><</span> // 找到可能匹配的字符,继续 |
05 | nowamagic.net is a <span style= "background-color:orange" ><b</span> // 找到可能匹配的字符,继续 |
07 | //找到匹配,保存到结果集中,继续进行剩下的文本。 |
08 | nowamagic.net is a <span style= "background-color:orange" ><b>good</b></span> website to <b>learn</b> IT <b>skills</c>. |
11 | website to <span style= "background-color:orange" ><</span> // 找到可能的匹配,继续 |
12 | website to <span style= "background-color:orange" ><b</span> // 找到可能的匹配,继续 |
14 | //找到匹配,保存到结果集中,继续进行剩下的文本。 |
15 | website to <span style= "background-color:orange" ><b>learn</b></span> |
18 | IT <span style= "background-color:orange" ><</span> // 找到可能的匹配,继续 |
19 | IT <span style= "background-color:orange" ><b</span> // 找到可能的匹配,继续 |
21 | IT <span style= "background-color:orange" ><b>skills</</span>c>. // 匹配失败,继续找 |
22 | IT <b>skills</c>. // 不匹配,继续 |
23 | // 字符串结束,匹配结束。一共找到了两个匹配<b>good</b>和<b>learn</b> |
我们回顾一下上面 “\d{1,3}” 匹配数字的例子,对于“1234”,当我们使用“\d{1,3}”时,进行的是贪婪匹配,它首先找到“123”(因为“1234”不符合),之后的“4”也符合,所以,找到的匹配是“123”和“4”。
当我们使用“\d{1,3}?”匹配上面的例子,对于“1234”,这次是惰性匹配。首先,发现“1”符合,将“1”保存到匹配集合中;随后,依次发现“2”、“3”、“4”符合,并依次保存到结果集中,最后,我们得到了四个匹配“1”、“2”、“3”、“4”。
from blog:www.nowamagic.net/librarys/veda/detail/1038