为你解疑:VB.NET正则表达式操作

经过长时间学习VB.NET,对于VB.NET正则表达式很感兴趣,于是和大家分享一下关于选择符 、组与向后引用 、VB.NET正则表达式的匹配模式 、原子组与防止回溯 四个方面进行详细的分析和语法的讲解,看完本文你肯定有不少收获,希望本文能教会你更多东西。

1.选择符

VB.NET正则表达式中“ ¦”表示选择。你可以用选择符匹配多个可能的正则表达式中的一个。如果你想搜索文字“cat”或“dog”,你可以用cat ¦dog> > 。如果你想有更多的选择,你只要扩展列表cat ¦dog ¦mouse ¦fish> > 。选择符在正则表达式中具有最低的优先级,也就是说,它告诉引擎要么匹配选择符左边的所有表达式,要么匹配右边的所有表达式。你也可以用圆括号来限制选择符的作用范围。如\b(cat ¦dog)\b> > ,这样告诉正则引擎把(cat ¦dog)当成一个正则表达式单位来处理。

注意正则引擎的“急于表功”性正则引擎是急切的,当它找到一个有效的匹配时,它会停止搜索。因此在一定条件下,选择符两边的表达式的顺序对结果会有影响。假设你想用正则表达式搜索一个编程语言的函数列表:Get,GetValue,Set或SetValue。一个明显的解决方案是Get ¦GetValue ¦Set ¦SetValue> > 。让我们看看当搜索SetValue时的结果。因为Get> > 和GetValue> > 都失败了,而Set> > 匹配成功。因为正则导向的引擎都是“急切”的,所以它会返回第一个成功的匹配,就是“Set”,而不去继续搜索是否有其他更好的匹配。和我们期望的相反,正则表达式并没有匹配整个字符串。有几种可能的解决办法。

一是考虑到正则引擎的“急切”性,改变选项的顺序,例如我们使用GetValue ¦Get ¦SetValue ¦Set> > ,这样我们就可以优先搜索最长的匹配。我们也可以把四个选项结合起来成两个选项:Get(Value)? ¦Set(Value)?> > 。因为问号重复符是贪婪的,所以SetValue总会在Set之前被匹配。一个更好的方案是使用单词边界:\b(Get ¦GetValue ¦Set ¦SetValue)\b> > 或\b(Get(Value)? ¦Set(Value)?\b> > 。更进一步,既然所有的选择都有相同的结尾,我们可以把正则表达式优化为\b(Get ¦Set)(Value)?\b> > 。

2.组与向后引用

把正则表达式的一部分放在圆括号内,你可以将它们形成组。然后你可以对整个组使用一些正则操作,例如重复操作符。要注意的是,只有圆括号“()”才能用于形成组。“[]”用于定义字符集。“{}”用于定义重复操作。当用“()”定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。当对被匹配的组进行向后引用的时候,可以用“\数字”的方式进行引用。\1> > 引用第一个匹配的后向引用组,\2> > 引用第二个组,以此类推,\n> > 引用第n个组。而\0> > 则引用整个被匹配的正则表达式本身。我们看一个例子。假设你想匹配一个HTML标签的开始标签和结束标签,以及标签中间的文本。比如 Thisisatest ,我们要匹配 和 以及中间的文字。我们可以用如下正则表达式:“ <([A-Z][A-Z0-9]*)[^> ]*> .*? \1>”首先,“ <”将会匹配“ ”的第一个字符“ <”。然后[A-Z]匹配B,[A-Z0-9]*将会匹配0到多次字母数字,后面紧接着0到多个非“> ”的字符。最后正则表达式的“> ”将会匹配“ ”的“> ”。

接下来正则引擎将对结束标签之前的字符进行惰性匹配,直到遇到一个“ ”符号。然后正则表达式中的“\1”表示对前面匹配的组“([A-Z][A-Z0-9]*)”进行引用,在本例中,被引用的是标签名“B”。所以需要被匹配的结尾标签为“ ”你可以对相同的后向引用组进行多次引用,([a-c])x\1x\1> > 将匹配“axaxa”、“bxbxb”以及“cxcxc”。如果用数字形式引用的组没有有效的匹配,则引用到的内容简单的为空。一个后向引用不能用于它自身。([abc]\1)> > 是错误的。因此你不能将\0> > 用于一个正则表达式匹配本身,它只能用于替换操作中。后向引用不能用于字符集内部。(a)[\1b]> > 中的\1> > 并不表示后向引用。在字符集内部,\1> > 可以被解释为八进制形式的转码。向后引用会降低引擎的速度,因为它需要存储匹配的组。如果你不需要向后引用,你可以告诉引擎对某个组不存储。例如:Get(?:Value)> > 。其中“(”后面紧跟的“?:”会告诉引擎对于组(Value),不存储匹配的值以供后向引用。

重复操作与后向引用当对组使用重复操作符时,缓存里后向引用内容会被不断刷新,只保留最后匹配的内容。例如:([abc]+)=\1> > 将匹配“cab=cab”,但是([abc])+=\1> > 却不会。因为([abc])第一次匹配“c”时,“\1”代表“c”;然后([abc])会继续匹配“a”和“b”。最后“\1”代表“b”,所以它会匹配“cab=b”。应用:检查重复单词--当编辑文字时,很容易就会输入重复单词,例如“thethe”。使用\b(\w+)\s+\1\b> > 可以检测到这些重复单词。要删除第二个单词,只要简单的利用替换功能替换掉“\1”就可以了。

组的命名和引用在PHP,Python中,可以用(?P group)> > 来对组进行命名。在本例中,词法?P 就是对组(group)进行了命名。其中name是你对组的起的名字。你可以用(?P=name)进行引用。.NET的命名组.NETframework也支持命名组。不幸的是,微软的程序员们决定发明他们自己的语法,而不是沿用Perl、Python的规则。目前为止,还没有任何其他的正则表达式实现支持微软发明的语法。

下面是.NET中的例子:(? group)(?’second’group)正如你所看到的,.NET提供两种词法来创建命名组:一是用尖括号“ <> ”,或者用单引号“’’”。尖括号在字符串中使用更方便,单引号在ASP代码中更有用,因为ASP代码中“ <> ”被用作HTML标签。要引用一个命名组,使用\k 或\k’name’.当进行搜索替换时,你可以用“${name}”来引用一个命名组。

3.VB.NET正则表达式的匹配模式

本教程所讨论的正则表达式引擎都支持三种匹配模式:/i> > 使正则表达式对大小写不敏感,/s> > 开启“单行模式”,即点号“.”匹配新行符/m> > 开启“多行模式”,即“^”和“$”匹配新行符的前面和后面的位置。

在正则表达式内部打开或关闭模式如果你在正则表达式内部插入修饰符(?ism),则该修饰符只对其右边的正则表达式起作用。(?-i)是关闭大小写不敏感。你可以很快的进行测试。(?i)te(?-i)st> > 应该匹配TEst,但是不能匹配teST或TEST.

4.原子组与防止回溯

相关推荐