正则表达式入门与提高
例2:查找后面不跟着某个特定单词(如Cat)的任意单词 正则:
\\b\\w+\\b(?!\\W+cat\\b)
这个正则表达式首先用”\\b\\w+\\b”去匹配一个单词,如匹配成功,紧接着尝试表达式(?!\\W+cat\\b),它的意思是查找该位置之后有无这样的字符串:若干个非单词字符(如空格)后跟着单词”cat”.
如果没有,则环视部分报告匹配成功,于是整个正则表达式匹配尝试结束,最终成功匹配,匹配结果为第一部分找到的单词.
反之,如果有,则环视部分报告匹配失败,于是整个正则表达式匹配失败,最终结果是,第一部分找到的单词不是符合要求的.
要注意的是在环视的子表达式中,Cat后用了单词边界\\b,是避免把某一个单词内部的cat字符当成单词了.
例3:查找不重复的单词 正则:
\\b(\\w+)\\b(?!.*?\\b\\1\\b)
前面我们介绍过查找相邻重复单词的正则表达式: \\b(\\w+)\\s+\\1\\b
你能否写一个查找相邻或不相邻的重复单词的正则表达式呢?
(二)用作对特定字符串是否存在的判断
例1:搜索同时包含多个单词的文本行,如:搜索包含单词one和two的文本行 正则:
^(?=.*?\\bone\\b)(?=.*?\\bwo\\b).+$
例2:查找除某个单词(cat)之外的任意单词 \\b(?!cat\\b)\\w+
例3:查找不包含另一个单词(cat)的单词 \\b((?!cat)\\w)+\\b
例4:匹配不包含某个单词(cat)的整行 ^((?!\\bcat\\b).)*$
请自己仔细解读这几个可在实际工作应用的经典正则表达式.
小结:与锁定文本功能不同,用作判断时,环视结构是放在前面的,匹配尝试时,它将在指定位置判断是否存在特定的字符串(即尝试匹配环视结构内的子表达式),如果环视报告成功则继续下一字符的匹配尝试;如
39
VBA平台的正则学习参考资料
果环视报告失败,则宣布整个匹配过程失败.
例1中指定位置是从行开始位置尝试子表达式的匹配; 例2中是从每个单词边界尝试子表达式的匹配;
例3和例4是在单词内部或行内部的每个位置尝试匹配子表达式,所以效率较低.另外,如果不需要提取文本,例3和例4中的捕获括号可修改为非捕获性括号.
40
正则表达式入门与提高
第三篇 正则匹配的工作原理
一、匹配的基本术语
1. 匹配
一个正则表达式能”匹配”一个字符串,其实是指这个正则表达式能在字符串中找到匹配文本.
2. 正则”引擎”
引擎本来是指发动机的核心部分, 现也用作IT方面的术语,指经包装过的函数库,方便别人调用,如搜索引擎、图形引擎等。
一个正则表达式不仅仅是一个代码模式,更是用正则符号写出的程序.当我们把它赋值给正则对象的属性时,其内部进行了所谓的”编译”,即对正则表达式进行语法分析,建立一个语法分析树,根据这个树生成一个正则引擎.
正则引擎有DFA和NFA类型之分,而VBscript中使用的是传统NFA引擎.这种引擎是所谓的”非确定有穷自动机(即NFA)”计算机算法的实现.本文接下来讨论的是NFA引擎的工作原理.(这是大多数语言平台上的选择,较流行的MySQL,使用的是DFA)
这是不是让人觉得模糊和深奥,本人也以为是.不过没关系,现在你只需要知道,在正则匹配的过程有一个”东东”在”操控”匹配形为,它就是”引擎”.而且我们也不打算从匹配算法理论角度去解读原理,而是从运用的角度去考察匹配的各种形为.
尽管如此,你应该从正则”引擎”的形成过程,明白一个事实:引擎受制于你编写的正则表达式.合理的正则表达式可以让引擎马力十足,而有问题的正则表达式则可能让引擎慢如蜗牛,更甚者,可能导致引擎空转或熄火.
换一种法,就是匹配是否成功或效率高低都掌握在你手里,这也是我们要研究原理的意义.
3. 引擎”眼”中的目标文本—位置和字符
对于一段目标文本,在引擎眼中,它是没有单词/句子/段落/等等复杂概念意义的,它看到的只是”位置”与”字符”:如
41
VBA平台的正则学习参考资料
4. 子表达式
在表述过程中,时常出现”子表达式”叫法.子表达式是整个正则表达式的一部分.如:括号中的内容,或由”|”分隔的多选分支,或环视内的表达式等.
二、匹配总原则
说到原理,总让人觉得它该是若干条高度概括的结论.不幸的是对正则原理来说貌似任何概括都对理解和利用没有指导意义.如果一定概括,那么,想到的就两条匹配原则:
1. NFA是以正则表达式为主导从文本开始处依次匹配的 2. 如果有必要,NFA总是穷尽所有途径,找到匹配
事实上,只要我们把握了各元字符(序列)及组合的匹配过程,也就把握了匹配原理.
三、正则表达式匹配的基本过程
1. 在正则制导下,引擎从目标文本的开始处,依次进行匹配尝试.
引擎会从左向右在每一个位置上扫描目标文本,同时检查正则表达式的每一个元素。如果产生一个合法匹配,匹配过程就会停在这个位置.
例: 正则表达式: cat 目标文本:
He captured a catfish for his cat 过程:
引擎先比较<