3分钟让你知道什么是VB.NET正则表达式引擎

开发 后端
大家知道VB.NET正则表达式引擎吗?在这里给大家介绍什么是正则表达式。让我们更进一步了解VB.NET正则表达式引擎内部机制让我们把 < <(? <=a)b> > 应用到“thingamabob”。

本人很喜欢VB.NET正则表达式引擎,在工作中也很喜欢总结关于VB.NET正则表达式的经验教训,下面就这个问题来详细说说吧。

什么是正则表达式

基本说来,正则表达式是一种用来描述一定数量文本的模式。Regex代表RegularExpress。本文将用 < > 来表示一段具体的正则表达式。一段文本就是最基本的模式,简单的匹配相同的文本。

向前查看与向后查看

Perl5引入了两个强大的正则语法:“向前查看”和“向后查看”。他们也被称作“零长度断言”。他们和锚定一样都是零长度的(所谓零长度即指该正则表达式不消耗被匹配的字符串)。不同之处在于“前后查看”会实际匹配字符,只是他们会抛弃匹配只返回匹配结果:匹配或不匹配。这就是为什么他们被称作“断言”。他们并不实际消耗字符串中的字符,而只是断言一个匹配是否可能。几乎本文讨论的所有正则表达式的实现都支持“向前向后查看”。唯一的一个例外是Javascript只支持向前查看。

肯定和否定式的向前查看如我们前面提过的一个例子:要查找一个q,后面没有紧跟一个u。也就是说,要么q后面没有字符,要么后面的字符不是u。采用否定式向前查看后的一个解决方案为 < > 。否定式向前查看的语法是 < <(?!查看的内容)> > 。肯定式向前查看和否定式向前查看很类似: < <(?=查看的内容)> > 。如果在“查看的内容”部分有组,也会产生一个向后引用。但是向前查看本身并不会产生向后引用,也不会被计入向后引用的编号中。这是因为向前查看本身是会被抛弃掉的,只保留匹配与否的判断结果。如果你想保留匹配的结果作为向后引用,你可以用 < <(?=(regex))> > 来产生一个向后引用。

肯定和否定式的先后查看向后查看和向前查看有相同的效果,只是方向相反否定式向后查看的语法是: < <(? > 肯定式向后查看的语法是: < <(? <=查看内容)> > 我们可以看到,和向前查看相比,多了一个表示方向的左尖括号。例: < <(? > 将会匹配一个没有“a”作前导字符的“b”。值得注意的是:向前查看从当前字符串位置开始对“查看”正则表达式进行匹配;向后查看则从当前字符串位置开始先后回溯一个字符,然后再开始对“查看”正则表达式进行匹配。

深入VB.NET正则表达式引擎内部让我们看一个简单例子。把正则表达式 < > 应用到字符串“Iraq”。正则表达式的第一个符号是 < > 。正如我们知道的,引擎在匹配 < > 以前会扫过整个字符串。当第四个字符“q”被匹配后,“q”后面是空字符(void)。而下一个正则符号是向前查看。引擎注意到已经进入了一个向前查看正则表达式部分。下一个正则符号是 < > ,和空字符不匹配,从而导致向前查看里的正则表达式匹配失败。因为是一个否定式的向前查看,意味着整个向前查看结果是成功的。于是匹配结果“q”被返回了。我们在把相同的正则表达式应用到“quit”。 < > 匹配了“q”。下一个正则符号是向前查看部分的 < > ,它匹配了字符串中的第二个字符“i”。引擎继续走到下个字符“i”。然而引擎这时注意到向前查看部分已经处理完了,并且向前查看已经成功。于是引擎抛弃被匹配的字符串部分,这将导致引擎回退到字符“u”。因为向前查看是否定式的,意味着查看部分的成功匹配导致了整个向前查看的失败,因此引擎不得不进行回溯。最后因为再没有其他的“q”和 < > 匹配,所以整个匹配失败了。为了确保你能清楚地理解向前查看的实现,让我们把 < > 应用到“quit”。 < > 首先匹配“q”。然后向前查看成功匹配“u”,匹配的部分被抛弃,只返回可以匹配的判断结果。引擎从字符“i”回退到“u”。由于向前查看成功了,引擎继续处理下一个正则符号 < > 。结果发现 < > 和“u”不匹配。因此匹配失败了。由于后面没有其他的“q”,整个正则表达式的匹配失败了。

更进一步理解VB.NET正则表达式引擎内部机制让我们把 < <(? <=a)b> > 应用到“thingamabob”。引擎开始处理向后查看部分的正则符号和字符串中的第一个字符。在这个例子中,向后查看告诉VB.NET正则表达式引擎回退一个字符,然后查看是否有一个“a”被匹配。因为在“t”前面没有字符,所以引擎不能回退。因此向后查看失败了。引擎继续走到下一个字符“h”。再一次,引擎暂时回退一个字符并检查是否有个“a”被匹配。结果发现了一个“t”。向后查看又失败了。向后查看继续失败,直到正则表达式到达了字符串中的“m”,于是肯定式的向后查看被匹配了。因为它是零长度的,字符串的当前位置仍然是“m”。下一个正则符号是 < > ,和“m”匹配失败。下一个字符是字符串中的第二个“a”。引擎向后暂时回退一个字符,并且发现 < > 不匹配“m”。在下一个字符是字符串中的第一个“b”。引擎暂时性的向后退一个字符发现向后查看被满足了,同时 < > 匹配了“b”。因此整个正则表达式被匹配了。作为结果,正则表达式返回字符串中的第一个“b”。

向前向后查看的应用我们来看这样一个例子:查找一个具有6位字符的,含有“cat”的单词。首先,我们可以不用向前向后查看来解决问题,例如: < > 足够简单吧!但是当需求变成查找一个具有6-12位字符,含有“cat”,“dog”或“mouse”的单词时,这种方法就变得有些笨拙了。我们来看看使用向前查看的方案。在这个例子中,我们有两个基本需求要满足:一是我们需要一个6位的字符,二是单词含有“cat”。满足第一个需求的正则表达式为 < <\b\w{6}\b> > 。满足第二个需求的正则表达式为 < <\b\w*cat\w*\b> > 。把两者结合起来,我们可以得到如下的正则表达式: < <(?=\b\w{6}\b)\b\w*cat\w*\b> > 具体的匹配过程留给读者。但是要注意的一点是,向前查看是不消耗字符的,因此当判断单词满足具有6个字符的条件后,引擎会从开始判断前的位置继续对后面的正则表达式进行匹配。最后作些优化,可以得到下面的正则表达式: < <\b(?=\w{6}\b)\w{0,3}cat\w*> > .正则表达式中的条件测试条件测试的语法为 < <(?ifthen ¦else)> > 。“if”部分可以是向前向后查看表达式。如果用向前查看,则语法变为: < <(?(?=regex)then ¦else)> > ,其中else部分是可选的。如果if部分为true,则正则引擎会试图匹配then部分,否则引擎会试图匹配else部分。需要记住的是,向前先后查看并不实际消耗任何字符,因此后面的then与else部分的匹配时从if测试前的部分开始进行尝试。16.为正则表达式添加注释在正则表达式中添加注释的语法是: < <(?#comment)> > 例:为用于匹配有效日期的正则表达式添加注释:(?#year)(19 ¦20)\d\d[-/.](?#month)(0[1-9] ¦1[012])[-/.](?#day)(0[1-9] ¦[12][0-9] ¦3[01])

【编辑推荐】

  1. 剖析VB.NET平台调用是如何执行操作
  2. 分享个人总结VB.NET多线程
  3. 详细说明VB.NET变量中四点
  4. 三类十二种VB.NET数据类型全面介绍
  5. VB.NET初步知识,初学者必看
责任编辑:田树 来源: 乐博网
相关推荐

2009-10-26 16:12:19

VB.NET正则表达式

2009-10-26 15:33:27

VB.NET正则表达式

2010-01-07 13:29:00

VB.NET正则表达式

2009-10-28 09:02:41

VB.NET开发正则表

2009-10-27 10:14:54

VB.NET正则表达式

2009-10-26 16:01:03

VB.NET正则表达式

2017-08-10 13:13:44

Linux正则表达式

2009-09-16 17:15:57

正则表达式引擎

2009-11-17 10:13:29

PHP正则表达式

2009-11-02 17:24:57

VB.NET语言

2009-08-07 14:24:31

.NET正则表达式

2009-10-27 09:17:26

VB.NET生成静态页

2009-10-30 13:12:40

VB.NET创建类

2009-10-21 18:19:36

VB.NET实现拖放

2009-10-26 15:45:43

VB.NET类构造

2012-05-08 13:29:01

VB

2012-01-12 10:21:57

正则表达式

2009-08-07 14:31:40

.NET正则表达式基础

2009-11-10 16:27:45

VB.NET指针

2009-08-13 15:02:52

C#正则表达式引擎贪婪
点赞
收藏

51CTO技术栈公众号