不太好理解的Alternation Constructs

2004-08-13 by 开心就好

看到有人对.NET中正则表示式的Alternation Constructs不太理解,这里写个简单例子说明一下。

英语里说 "0 feet"(0英尺), "1 foot"(一英尺),"2 feet"(二英尺),"3 feet"(三英尺),...我们怎么来匹配这些字符串?

这个例子很简单,象 
 "\^01 foot|[02-9] feet|[1-9]\d+ feet\$"

 "\^0
1 foot|(?:(?:[02-9]|[1-9]\d+) feet)\$"

这样的表达式大概就行了。

下面用Alternation Constructs来演示一下。

1。 "\^\d+ f(?(?\<=\b0*1 f)oo|ee)t\$"

在这里,(?\<=\b01 f) is a zero-width positive lookbehind, (?(?\<=\b01 f)oo|ee) 表示

假如前面3个字符是1 f的话(有可能有些前置的0),那么匹配oo,否则匹配ee

2。 "\^((?\<one>0*1)|[02-9]|\d{2,}) f(?(one)oo|ee)t\$"

在前面我们尝试匹配1(有可能有些前置的0),假如1被匹配的话,表明第一部分(?\<one>0*1)被captured了,group "one"就有了定义

在第二部分里

(?(one)oo|ee)

说,假如前面的group "one"被captured了,那么就匹配oo,否则匹配ee

这里是个测试编码

using System;
using System.Text.RegularExpressions;

class TestRegAC
{
  static void Main()
  {
 string[] slist = {"11 foot", "01 feet", "1 foot", "1 feet", "2 feet", "3 foot", "10 feet", "100 foot", "0 feet", "001 foot"};
 Regex re = new Regex(@"\^\d+ f(?(?\<=\b0*1 f)oo|ee)t\$", RegexOptions.IgnoreCase);
 foreach (string s in slist)
 {
  Console.WriteLine("{0} matches? {1}", s, re.IsMatch(s));
 }

Console.WriteLine();

re = new Regex(@"\^((?\<one>0*1)|[02-9]|\d{2,}) f(?(one)oo|ee)t\$", RegexOptions.IgnoreCase);
 foreach (string s in slist)
 {
  Console.WriteLine("{0} matches? {1}", s, re.IsMatch(s));
 }
  }
}

同时参考

Manipulate Text With Regular Expressions

里面有个匹配25-09-2003后任一天的例子,很有意思


Comments