JavaScript:正则表达式 前瞻 找位置

js中全部都是顺序环视

顺序环视匹配过程

对于顺序肯定环视(?=Expression)来说,当子表达式Expression匹配成功时,(?=Expression)匹配成功,并报告(?=Expression)匹配当前位置成功。

对于顺序否定环视(?!Expression)来说,当子表达式Expression匹配成功时,(?!Expression)匹配失败;当子表达式Expression匹配失败时,(?!Expression)匹配成功,并报告(?!Expression)匹配当前位置成功;

顺序肯定环视的例子已在NFA引擎匹配原理中讲解过了,这里再讲解一下顺序否定环视。

 环视01

 

源字符串:aa<p>one</p>bb<div>two</div>cc

正则表达式:<(?!/?p\b)[^>]+>

这个正则的意义就是匹配除<p…>或</p>之外的其余标签。

匹配过程:

 环视02

首先由字符“<”取得控制权,从位置0开始匹配,由于“<”匹配“a”失败,在位置0处整个表达式匹配失败,第一次迭代匹配失败,正则引擎向前传动,由位置1处开始尝试第二次迭代匹配。

重复以上过程,直到位置2,“<”匹配“<”成功,控制权交给“(?!/?p\b)”;“(?!/?p\b)”子表达式取得控制权后,进行内部子表达式的匹配。首先由“/?”取得控制权,尝试匹配“p”失败,进行回溯,不匹配,控制权交给“p”;由“p”来尝试匹配“p”,匹配成功,控制权交给“\b”;由“\b”来尝试匹配位置4,匹配成功。此时子表达式匹配完成,“/?p\b”匹配成功,那么环视表达式“(?!/?p\b)”就匹配失败。在位置2处整个表达式匹配失败,新一轮迭代匹配失败,正则引擎向前传动,由位置3处开始尝试下一轮迭代匹配。

在位置8处也会遇到一轮“/?p\b”匹配“/p”成功,而导致环视表达式“(?!/?p\b)”匹配失败,从而导致整个表达式匹配失败的过程。

重复以上过程,直到位置14,“<”匹配“<”成功,控制权交给“(?!/?p\b)”;“/?”尝试匹配“d”失败,进行回溯,不匹配,控制权交给“p”;由“p”来尝试匹配“d”,匹配失败,已经没有备选状态可供回溯,匹配失败。此时子表达式匹配完成,“/?p\b”匹配失败,那么环视表达式“(?!/?p\b)”就匹配成功。匹配的结果是位置15,然后控制权交给“[^>]+”;由“[^>]+”从位置15进行尝试匹配,可以成功匹配到“div”,控制权交给“>”;由“>”来匹配“>”。

此时正则表达式匹配完成,报告匹配成功。匹配结果为“<div>”,开始位置为14,结束位置为19。其中“<”匹配“<”,“(?!/?p\b)”匹配位置15,“[^>]+”匹配字符串“div”,“>”匹配“>”。

前瞻相当于对“所在位置”附加了一个条件,前瞻的难点在于找到这个“位置”

前瞻在字符串左边:就是从该字符串前面的第一个位置(包括字符串)开始查找符合该前瞻条件的字符串。

前瞻在字符串右边:就是从该字符串后面的第一个位置(不包括字符串)开始查找符合该前瞻条件的字符串。

前瞻在字符串中间,就是

既要不包含前字符串,

也要包含后字符串,

再符合前瞻条件。

代码:

var str="abcdefg hi";
var re=/(?=(.*?)f)cd/i;
show(1);
 function show(num){
      for(var i=0;i<num;i++){
        console.dir(re.exec(str));console.log("");
      }
   }

 

前瞻要包含cd,位置在cd左边

2.前瞻在右边

var str="abcdefg hi";
var re=/cd(?=(.*?)f)/i;
show(1);
 function show(num){
      for(var i=0;i<num;i++){
        console.dir(re.exec(str));console.log("");
      }
   }

 

3.前瞻在中间,但是确定位置在左边

var str="abcdefg hi";
var re=/ab(?=(.*?)f).*d/i;
show(1);

 

4.前瞻在中间,但是确定位置在右边

var str="abcdefg hi";
var re=/a.*(?=(.*?)f)cd/i;
show(1);

 

5.前瞻在中间,但是两边都没有确定位置

var str="abcdefg hi";
var re=/a.*(?=(.*?)f).*d/i;
show(1);

6.前瞻在中间,但是两边都有确定位置

var str="abcdefg hi";
var re=/a(?=(.*?)f)b/i;
show(1);

 

http://blog.csdn.net/lxcnn/article/details/4304754

posted @ 2013-10-18 14:35  hongdada  阅读(970)  评论(0编辑  收藏  举报