#008 - 正则表达式高阶

反向引用:

* 匹配 taobao taobao , home home 这样的情况
* \b(\w+)\b\s+\1\b
* \b(?<Word>\w+)\b\s+\k<Word>\b 这是命名后另一种写法

零宽断言:

* ?=exp:零宽度正预测先行断言,自身出现位置的后面能匹配表达式exp
\b\w+(?=ing\b)
i’m singing while you’re dancing.
* ?<=exp:零宽度正回顾后发断言,自身出现位置的前面能匹配的表达式exp
(?<=\bre)\w+\b
reading a book

负向零宽断言:

  • 例子:查找单词 - 它里面出现了字母q,但是后面跟的不是字母u
    * \b\w*q[^u]\w*\b
    * 上面表达式没有使用负向零宽断言,当出现bendq以q结尾的单词不会匹配,因为q后面必须跟一个不是字母u的字母,与题目不符合
    * \b\w*q(?!u)\w*\b        负向零宽断言:零宽度负预测先行断言
    * \d{3}(?!\d)             匹配三位数字,而且这三位数字的后面不能是数字
    * \b((?!abc)\w)+\b     匹配不包含连续字符串abc的单词
    * 同样的,还有零宽度负回顾后发断言
    * (?<![a-z])\d{7}    匹配前面不是小写字母的七位数字
    * (?<=<(\w+)>).*(?=<\/\1>)     不包括前缀和后缀本身

平衡组/递归匹配

* 如何把  “ xx <aa <bbb> <bbb> aa> yy “这样的字符串里的最长的配对的尖括号内的内容捕获出来?
* (?group’) 把捕获的内容命名为group,并压如堆栈(Stack* (?-group’) 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
* (?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
* (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败

练习:
反向引用:

* 匹配 taobao taobao taobao hugi taobao  taobao
* \b(\w+)\s+(\1)\s+     匹配两个重复的内容
* \b(\w+)\s+(\1)\s+(\1)    匹配三个重复的内容

零宽断言&负向零宽断言

* 零宽断言 :是
    * 后面:exp(?=exp)
    * 前面:(?<=exp)exp

* 负向零宽断言:不是
* 后面:exp(?!exp)
* 前面:(?<!exp)exp

* 匹配 “ 5 5 6 456 524 0 4 56 2349 8 “ 中的单个数字,思考:1、前面是空格中间是数字后面是空格。2、第一个数字的前面没有数字,后面是空格。3、最后一个数字前面是空格,后面没有数字
* (?<=\s+)\d(?=\s+) | (?<!\d+)\d(?=\s+) | (?<=\s+)\d(?!\d+)    例子是为了理解零宽和负向零宽断言,实际环境中多用于匹配字符串,不会这么复杂

如何把 “ xx <aa <bbb> <bbb> aa> yy “这样的字符串里的最长的配对的尖括号内的内容捕获出来?

只有在.net环境中能匹配,其他环境不匹配

<                         #最外层的左括号
    [^<>]*                #最外层的左括号后面的不是括号的内容
    (
        (
                (?'Open'<)    #碰到了左括号,在黑板上写一个"Open"
            |
                (?'-Open'>)   #碰到了右括号,擦掉一个"Open"

            |    #匹配右括号后面不是括号的内容
           [^<>]*        
        )+  
    )*
    (?(Open)(?!))         #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败

>                         #最外层的右括号

猜你喜欢

转载自blog.csdn.net/aarron_dl/article/details/80203224
008