学习之路——正则表达式(下)
来源:互联网 发布:英语 荷兰语知乎 编辑:程序博客网 时间:2024/05/01 13:25
转载请注明出处
[我的博客]http://www.lostbug.com
贪婪与懒惰
- 贪婪 - 当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。- 以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
- 懒惰 - 有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。- 现在看看懒惰版的例子吧:a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)
处理选项
- 一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外
平衡组/递归匹配
- 有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构,这时简单地使用(.+)则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式,懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等,比如( 5 / ( 3 + 2 ) ) ),那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的,配对的括号之间的内容呢?
为了避免(和(把你的大脑彻底搞糊涂,我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把xx
<aa <bbb> <bbb> aa> yy
这样的字符串里,最长的配对的尖括号内的内容捕获出来?这里需要用到以下的语法构造:
1>.(?’group’) 把捕获的内容命名为group,并压入堆栈(Stack)
2>.(?’-group’) 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
3>.(?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
4>.(?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败我们需要做的是每碰到了左括号,就在压入一个”Open”,每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。
< #最外层的左括号 [^<>]* #最外层的左括号后面的不是括号的内容 ( ( (?'Open'<) #碰到了左括号,在黑板上写一个"Open" [^<>]* #匹配左括号后面的不是括号的内容 )+ ( (?'-Open'>) #碰到了右括号,擦掉一个"Open" [^<>]* #匹配右括号后面不是括号的内容 )+ )* (?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败> #最外层的右括号
平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的
标签:
<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>.
其他未尽事宜
原文 请移步http://deerchao.net/tutorials/regex/regex.htm#greedyandlazy
0 0
- 学习之路——正则表达式(下)
- 学习之路——正则表达式(上)
- javascript学习之 正则表达式 (20)—— 概述
- javascript学习之 正则表达式 (23)——字符集
- javascript学习之 正则表达式 (22)——String正则方法
- 正则表达式学习(二)之常见正则表达式汇总
- PHP学习之路六(php与正则表达式)
- shell学习笔记之三——正则表达式
- Linux学习之——特殊字符和正则表达式
- JavaScript学习笔记之——正则表达式总结
- 黑马程序员——学习日记之--正则表达式总结
- JAVA学习笔记之十四——常用正则表达式
- Python学习之路-正则表达式
- Python之学习笔记(正则表达式)
- linux下正则表达式学习
- 正则表达式学习——精通正则表达式
- 正则表达式学习笔记之一——正则表达式引擎
- 正则表达式(下)
- 关于阿里云和ucloud云服务器负载均衡器slb和ulb会话保持的配置
- post与getAsp.net传值区别
- 关于 easyui datagrid 更改单元格值后getChanges无法获取
- HTML5 Web 存储
- TOP K算法问题
- 学习之路——正则表达式(下)
- JavaSE高级篇学习笔记
- 《Android群英传》学习笔记 ---Android系统架构
- 出现问题自己的心得体会.
- 使用Ajax+jQuery实现省市区三级联动
- MySQL binlog三种模式
- 【CUDA并行程序设计系列(4)】CUDA内存
- git管理代码常用命令
- mysql配置