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


    js中全部都是顺序环视

    顺序环视匹配过程

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

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

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

     环视01

     

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

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

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

    匹配过程:

     环视02

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

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

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

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

    此时正则表达式匹配完成,报告匹配成功。匹配结果为“<div>”,开始位置为14,结束位置为19。其中“<”匹配“<”,“(?!/?p)”匹配位置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

  • 相关阅读:
    配置linux 防火墙,只有固定IP和端口才能能访问完美解决
    转.HTML中img标签的src属性绝对路径问题解决办法,完全解决!
    weblogic 安全漏洞问题解决
    转 echarts 的使用时遇到的坑 初始化和销毁,亲测有效!
    在使用 Fortify进行源码扫描时需要做对项目需要做什么?
    eclipse 导出 jar包详细步骤
    转 Fortofy扫描漏洞解决方案2
    JSON 之 SuperObject(1)
    Delphi使用JSON解析调用淘宝IP地址库REST API 示例
    Jsoncpp的使用
  • 原文地址:https://www.cnblogs.com/hongdada/p/3376023.html
Copyright © 2020-2023  润新知