设为首页 加入收藏

TOP

正则表达式30分钟入门教程(三)
2014-11-24 11:27:58 来源: 作者: 【 】 浏览:30
Tags:正则 表达式 30分钟 入门教程
hting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q( !u)\w*\b


零宽度负预测先行断言( !exp)断言此位置的后面不能匹配表达式exp。例如:\d{3}( !\d)匹配三位数字,而且这三位数字的后面不能是数字\b(( !abc)\w)+\b匹配不包含连续字符串abc的单词


同理,我们可以用( ,零宽度负回顾后发断言断言此位置的前面不能匹配表达式exp( 匹配前面不是小写字母的七位数字


一个更复杂的例子:( <=<(\w+)>).*( =<\/\1>)匹配不包含属性的简单HTML标签内里的内容( <=<(\w+)>)指定了这样的前缀被尖括号括起来的单词(比如可能是),然后是.*(任意的字符串),最后是一个后缀( =<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是的话,后缀就是了。整个表达式匹配的是之间的内容(再次提醒,不包括前缀和后缀本身)。


小括号的另一种用途是通过语法( #comment)来包含注释。例如:2[0-4]\d( #200-249)|25[0-5]( #250-255)|[01] \d\d ( #0-199)


要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如,我们可以前面的一个表达式写成这样:


( <= # 断言要匹配的文本的前缀


<(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签)


) # 前缀结束


.* # 匹配任意文本


( = # 断言要匹配的文本的后缀


<\/\1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签


) # 后缀结束


当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。


有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号 。这样.* 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:


a.* b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)ab(第四到第五个字符)


上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项:


一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外。


有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构,这时简单地使用\(.+\)则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式,懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等,比如( 5 / ( 3 + 2 ) ) ),那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的,配对的括号之间的内容呢?


为了避免(\(把你的大脑彻底搞糊涂,我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把xx aa>yy这样的字符串里,最长的配对的尖括号内的内容捕获出来?


这里需要用到以下的语法构造:


我们需要做的是每碰到了左括号,就在压入一个"Open",每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。


< #最外层的左括号


[^<>]* #最外层的左括号后面的不是括号的内容


(


(


( 'Open'<) #碰到了左括号,在黑板上写一个"Open"


[^<>]* #匹配左括号后面的不是括号的内容


)+


(


( '-Open'>) #碰到了右括号,擦掉一个"Open"


[^<>]* #匹配右括号后面不是括号的内容


)+


)*


( (Open)( !)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败



> #最外层的右括号


平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的

标签]*>[^<>]*((( 'Open']*>)[^<>]*)+(( '-Open'
)[^<>]*)+)*( (Open)( !))
.


上边已经描述了构造正则表达式的大量元素,但是还有很多没有提到的东西。下面是一些未提到的元素的列表,包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN Library,你也可以在里面找到.net下正则表达式详细的文档。


好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.被忽悠的感觉很爽吧?


要投诉我,或者觉得我其实可以忽悠得更高明,或者有任何其它问题,欢迎来我的博客让我知道.


首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇如何使用Java synchronized进行线.. 下一篇C语言中通过函数指针实现函数重载

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Python 数据分析与可 (2025-12-26 21:51:20)
·从零开始学Python之 (2025-12-26 21:51:17)
·超长干货:Python实 (2025-12-26 21:51:14)
·为什么 Java 社区至 (2025-12-26 21:19:10)
·Java多线程阻塞队列 (2025-12-26 21:19:07)