反向引用:
* 匹配 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";如果还有,则匹配失败
> #最外层的右括号