• javascript正则表达式中 (?=exp)、(?<=exp)、(?!exp)


     (?=exp)

    百度百科给的解释:非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

    只看这个,看一辈子恐怕也看不明白。

    我们看个案例:

     console.log(('123456789.56').match(/d{1,3}(?=(d{3})+(.d*)?$)/g)); //结果: ["123", "456"]

    解释:

    首先要满足 : d{1,3}这个正则。

    第 1 步: 开始的 1 满足d{1,3}最大匹配,后面的 23456789.56 不满足 (?=(d{3})+(.d*)?$),所以这个 “1” 不满足。

    第 2 步:开始的 12 满足 d{1,3}最大匹配,后面的 3456789.56 不满足 (?=(d{3})+(.d*)?$),所以这个 “12” 不满足。

    第 3 步:开始的 123 满足 d{1,3}最大匹配,后面的 456789.56 满足 (?=(d{3})+(.d*)?$),所以这个  “123” 满足,返回  “123”

    第 4 步: 从4开始搜索,开始的 4 满足d{1,3}最大匹配,后面的 56789.56 不满足 (?=(d{3})+(.d*)?$),所以这个 “4 ”不满足。

    第 5 步: 从5开始搜索,开始的 45 满足d{1,3}最大匹配,后面的 6789.56 不满足 (?=(d{3})+(.d*)?$),所以这个 “45“ 不满足。

    第 6 步: 从6开始搜索,开始的 456 满足d{1,3}最大匹配,后面的 789.56 满足 (?=(d{3})+(.d*)?$),所以这个 “456“ 满足,返回 “456”

    第 7 步: 从7开始搜索,开始的 7 满足d{1,3}最大匹配,后面的 89.56 不满足 (?=(d{3})+(.d*)?$),所以这个 “7“ 不满足。

    第 8 步: 从8开始搜索,开始的 78 满足d{1,3}最大匹配,后面的 9.56 不满足 (?=(d{3})+(.d*)?$),所以这个 “78“ 不满足。

    第 9 步: 从9开始搜索,开始的 789 满足d{1,3}最大匹配,后面的 .56 不满足 (?=(d{3})+(.d*)?$),所以这个 “789“ 不满足,此时“789”满足了 d{1,3}最大的匹配,但是后面没有能匹配的。

    第 10 步: 从 . 开始搜索,开始的 .(.|9. | 89. )都不满足d{1,3},所以这个 从 . 位置搜索的没满足的。

    第 11 步 : 从 5 开始搜索,开始的 5 满足 d{1,3}最大匹配,后面的6 不满足  (?=(d{3})+(.d*)?$),所以这个 “5“ 不满足。

    第 12 步 : 从 6 开始搜索,开始的 56 满足 d{1,3}最大匹配,后面就没有了,不满足   (?=(d{3})+(.d*)?$),  所以这个 “56 “ 不满足。

    说的直接点就是: (?=exp) 里面匹配的内容是不会被 match捕获的,只是当个条件来对待使用,只是用来判断当前检索的位置后面的能否满足这个条件。

     (?<=exp)

         也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=re)w+会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

    有点奇怪,在js 的正则表达式中来测试这个一直报错,猜测估计是不支持。

    (?!exp)

     这个与  (?=exp) 相反.

    console.log(('123456789.56').match(/d{1,3}(?!(d{3})+(.d*)?$)/g));//["12", "345", "678", "9", "56"]

    解释:

    首先的满足 d{1,3}

    从 1 处开始搜索,d{1,3}的最大匹配是 1,后面是 23456789.56  ,满足, (?!(d{3}) +(.d*)?$), OK, 此时 d{1,3} 匹配的是 “1”

    第二次从 2 开始搜索,,d{1,3}的最大匹配是 12, 后面是 3456789.56  ,满足, (?!(d{3}) +(.d*)?$), OK, 此时 d{1,3} 匹配的是 “12”

    第三次从 3 开始搜索,d{1,3}的最大匹配是 123,后面是 456789.56  ,不满足, (?!(d{3}) +(.d*)?$),所以返回的结果数组中第一个是 “12”., 此时 d{1,3} 匹配的最大是是 “12”

    第四次从 4 开始搜索, 后面是 56789.56 ,d{1,3}的最大匹配是 34,满足, (?!(d{3}) +(.d*)?$), OK,  此时 d{1,3} 匹配的是 “34”

    第五次从 5 开始搜索, 后面是 6789.56  ,d{1,3}的最大匹配是 345,满足, (?!(d{3}) +(.d*)?$), OK,  此时 d{1,3} 匹配的是 “345”.,已经满足最大3个数字了,此时返回 “345”

    第六次从 6 开始搜索, 后面是 789.56  ,d{1,3}的最大匹配是 6,不满足, (?!(d{3}) +(.d*)?$),  此时 d{1,3} 匹配的是 “6”.

    第七次从 7 开始搜索, 后面是 89.56  ,d{1,3}的最大匹配是 67,满足, (?!(d{3}) +(.d*)?$),  此时 d{1,3} 匹配的是 “67”.

     第八次从 8 开始搜索, 后面是 9.56  ,d{1,3}的最大匹配是 678,满足, (?!(d{3}) +(.d*)?$),  此时 d{1,3} 匹配的是 “678”.,已经满足最大3个数字了,此时返回 “678”.

     第九次从 9 开始搜索, 后面是 .56  ,d{1,3}的最大匹配是 9,满足, (?!(d{3}) +(.d*)?$),  此时 d{1,3} 匹配的是 “9”

     第十次从 .  开始搜索, 此时 “9.” 不满足 d{1,3} ,所以此时返回 “9”

     第十一次从 5 开始搜索, 后面是 6  ,d{1,3}的最大匹配是 6,满足, (?!(d{3}) +(.d*)?$),  此时 d{1,3} 最大匹配的是 “5”

     第十二次从 6 开始搜索, 后面没有 ,d{1,3}的最大匹配是 56,满足, (?!(d{3}) +(.d*)?$),  此时 d{1,3} 最大匹配的是 “56”,结束,返回最后一个 “56”

    这只是个人的理解,有不对之处,望各位大神们指正。

  • 相关阅读:
    java socket解析和发送二进制报文工具(附java和C++转化问题)
    hibernate缓存机制(二级缓存)
    Spring MVC中前后台数据传输小结
    NUC972 MDK NON-OS
    代码是如何控制硬件的?
    C语言位运算+实例讲解(转)
    C语言程序真正的启动函数
    51单片机的时钟及总线时序和总线扩展
    如何通过Keil将程序正确的下载进flash中
    说说M451例程讲解之串口
  • 原文地址:https://www.cnblogs.com/huaan011/p/7040554.html
Copyright © 2020-2023  润新知