zoukankan      html  css  js  c++  java
  • 正则表示式

    以前看到别人正则里写(?=),(?!)...这些,觉得云里雾里,完全不知道什么意思,今天突然搜到专门介绍的文章,看完后,有一种拨开云雾见月明的感觉。特此分享下。

    正则表达式有俩种特别的情况:

     1. 零宽断言:用于查找在某些内容(但不包括这些内容)之前或之后出现的字符,也就是说像,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。

      (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置后面能匹配表达式exp。如:w+(?=ing)匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。

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

       假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=d)d{3})+,用它对xxxxxxxxxx进行查找时结果是xxxxxxxxxx

          下面这个例子同时使用了这两种断言:(?<=s)d+(?=s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)
          断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。
     
      2. 负向零宽:如果我们只是想要确保某个字符没有出现,但是不想去匹配它是怎么办?
     

       例如我们想查找这样的单词:它里面出现了字母q,但是q后面跟的不是字母u。我们可以尝试这样:w*q[^u]w*匹配包含字母q后面不是字母u的单词,但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出单词的结尾的话,像Iraq,Benq,这个表达式就会出错。因为[^u]总要去匹配一个字符,当字母q出现在最后的话,[^u]就会去匹配q后面的单词分隔符(可能是空格,句号,或者其它什么的),后面的w*将会匹配下一个单词,于是w*q[^u]w*就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,不消耗任何字符。我们可以这样来解决这个问题:w*q(?!u)w*。

     
         (?!exp)零宽度负预测先行断言,断言此后面的位置不能匹配表达式exp。例如:d{3}(?!d)匹配3为数字,而且这三位数字的后面不能是数字;((?!abc)w)+匹配不包含连续字符串abc的单词。
     
         (?<!exp)零宽度负回顾后发断言,断言此位置的前面不能匹配表达式exp。(?<![a-z])d{7}匹配前面不是小写字母的七位数字。
     
    一个更复杂的例子:(?<=<(w+)>).*(?=</1>)这个表达式最能表现零宽断言的真正用途。匹配不包含属性的简单HTML标签内里的内容。 (?<=<(w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最 后是一个后缀(?=</1>)。注意后缀里的/,它用到了前面提过的字符转义,将”/“转义;1则是一个反向引用,引用的正是捕获的 第一组,前面的(w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的 是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。
         
  • 相关阅读:
    Instr() 函数用法
    tomcat通过tomcat 安装根目录下的conf-Catalina-localhost目录发布项目详解
    字符串中包含任意几个字符中的至少一个
    四大奶粉中的三个
    mysql几个操作数据库命令符下的常用命令
    访问网络资源302 200 解释
    浅谈Java变量的初始化顺序详解
    static块的本质
    迭代器
    集合接口和类
  • 原文地址:https://www.cnblogs.com/mihu/p/4140943.html
Copyright © 2011-2022 走看看