1        概述

初学正则时,对于Regex类不熟悉,遇到问题不知道该用哪种方法解决,本文结合一些正则应用的典型应用场景,介绍一下Regex类的基本应用。这里重点进行.NET类的介绍,对于正则的运用,不做深入探讨。

正则的应用最终都是进行模式的匹配,而根据目的的不同,基本上可以分为以下几种应用:验证、提取、替换、分割。结合.NET提供的控件、类以及类的方法,可以很方便的实现这些应用。

以下将结合一些典型的应用场景,对.NET中常见的类、方法及属性进行介绍。本文旨在.NET类基础用法的引导,对于其中涉及到的正则表达式不做深入探讨。本文适合于在.NET平台下使用正则的初学者。

2        基础应用

2.1     验证

验证的目的是为了判断输入的源字符串是否符合某一规律或规则,根据需求的不同,可能是校验整个源字符串,也可能只是校验其中一个子串。

验证在.NET中一般有两种应用,一种是在验证控件RegularExpressionValidator中,另一种是在程序中。

2.1.1  验证控件RegularExpressionValidator

RegularExpressionValidator是.NET自带的一种客户端验证控件,通过简单的设置,即可完成对某控件输入值的校验。

基本应用语法如下:

<asp:RegularExpressionValidator

ID="RegularExpressionValidator1"

runat="server"

ControlToValidate="TextBox1"

ErrorMessage="RegularExpressionValidator"

ValidationExpression="^([1-9][0-9]*|0)(/.[0-9][2])?$">

</asp:RegularExpressionValidator>

对于RegularExpressionValidator控件不做过多介绍,只是说明一下使用时需要注意的几点:

1、  RegularExpressionValidator进行的是客户端验证;

2、  RegularExpressionValidator中正则使用的是JavaScript语法规则;

3、  RegularExpressionValidator控件不能验证输入是否为空。

由于RegularExpressionValidator做的是客户端验证,很容易被跳过,所以在使用RegularExpressionValidator验证的同时,还要做服务器端验证。

RegularExpressionValidator最终是要生成客户端的JavaScript代码进行验证的,所以RegularExpressionValidator使用的正则要求符合JavaScript语法规则,与.NET的几点区别:

1、  不支持逆序环视,也就是(?<=Expression)和(?<!Expression)这样的语法;

2、  元字符仅支持ASCII码,即/w等价于[a-zA-Z0-9_],/d等价于[0-9]

RegularExpressionValidator控件一般是用来验证某一控件输入的字符串整体是否符合某一规则的,所以通常情况下“^”和“$”是必不可少的;在使用“|”表示“或”的关系时,一定要用“()”来限定“|”作用范围,比如0-100可以写作“^([1-9]?[0-9]|100)$”。

RegularExpressionValidator是不能验证输入是否为空的,验证是否为空要用RequiredFieldValidator控件。

RegularExpressionValidator验证控件是.NET为方便客户端验证封装的一组验证控件之一,但由于RegularExpressionValidator受限于支持的正则语法规则,只能做有限的格式校验,一些复杂的校验可以通过自己写JavaScript代码来实现,也是很简单的。

2.1.2  程序验证——IsMatch()

程序中的校验基本上就是使用IsMatch方法,验证的对象可能是源字符串的整体,也可能只是其中一个子串。

验证源字符串的整体是否符合某一规则,与使用RegularExpressionValidator时的需求基本上一致,不过由于是在.NET程序中,所以使用的是.NET的语法,比JavaScript中要强大得多。比如验证一个文本框输入的字符串是否符合某一规则,就是一个典型的验证整体的需求。

举例1:验证textBox1输入内容,要求整数部分为0或正整数,小数可有可无,有小数时必须为2位。

Regex reg = new Regex(@"^(?:[1-9][0-9]*|0)(?:/.[0-9]{2})?$");

if (reg.IsMatch(textBox1.Text))

{

richTextBox2.Text = "输入格式正确!";

}

else

{

richTextBox2.Text = "输入格式错误!";

}

由于是对源字符串的整体进行验证,所以“^”和“$”是必不可少的。否则验证的结果可能是错误的,比如正则表达式“(?:[1-9][0-9]*|0)(?:/.[0-9]{2})?”,在输入“0.123”时是可以匹配成功的,匹配结果为“0.12”,此时正则只起到了匹配的作用,没有起到验证的作用。

验证源字符串的局部是否符合某一规则,就是对于源字符串中子串的校验,通常是用来判断源字符串中是否包含,或是不包含符合某一规律的子串,作用类似于string类中的IndexOf。

举例2(参考问两个正则表达式):

数据:

1985aaa1985bb

bcae1958fiefadf1955fef

atijc1944cvkd

df2564isdjfef2564d

abc1234def5678ghi5678jkl

需求1:验证字符串中任意位置出现的连续四个数字在整个字符串中是否有重复,有重复为True,无重复为False。

以上数据需求1的验证结果为True的应为:

1985aaa1985bb

df2564isdjfef2564d

abc1234def5678ghi5678jkl

因为需求中指明是任意位置的连续4个数字是否有重复,所以在找到重复前,要遍历源字符串中每一个位置时行验证,这样就不能限定开始标识符“^”;而在匹配过程中,除非一直到结尾仍找不到重复,否则只要匹配到有重复的位置就可以了,这样也不需要结束标识符“$”,所以这是典型的对字符串的子串行验证的需求。

代码实现:

string[] test = new string[] { "1985aaa1985bb", "bcae1958fiefadf1955fef", "atijc1944cvkd","df2564isdjfef2564d", "abc1234def5678ghi5678jkl" };

Regex reg = new Regex(@"(/d{4})(?:(?!/1).)*/1");

foreach (string s in test)

{

richTextBox2.Text += "源字符串:  " + s.PadRight(25, ' ') + "验证结果:  " + reg.IsMatch(s) + "/n";

}

/*--------输出--------

源字符串:  1985aaa1985bb            验证结果:  True

源字符串:  bcae1958fiefadf1955fef   验证结果:  False

源字符串:  atijc1944cvkd            验证结果:  False

源字符串:  df2564isdjfef2564d       验证结果:  True

源字符串:  abc1234def5678ghi5678jkl 验证结果:  True

*/

由于涉及到了重复问题,所以这里用到了反向引用,对于反向引用的细节,可以参考正则基础之——反向引用

需求2:验证字符串中第一个出现的连续4个数字是否有重复,有重复为True,无重复为False。

以上数据需求2的验证结果为True的应为:

1985aaa1985bb

df2564isdjfef2564d

因为需求中指明是第一个是否有重复,所以需要有开始标识符“^”,来保证是第一个出现的连续4个数字;而在匹配过程中,除非一直到结尾仍找不到重复,否则只要匹配到有重复的位置就可以了,这样也不需要结束标识符“$”,所以这仍是对字符串的子串行验证的需求,只不过相对于需求1来说,加了一个限定条件。

代码实现:

string[] test = new string[] { "1985aaa1985bb", "bcae1958fiefadf1955fef", "atijc1944cvkd","df2564isdjfef2564d", "abc1234def5678ghi5678jkl" };

Regex reg = new Regex(@"^(?:(?!/d{4}).)*(/d{4})(?:(?!/1).)*/1");

foreach (string s in test)

{

richTextBox2.Text += "源字符串:  " + s.PadRight(25, ' ') + "验证结果:  " + reg.IsMatch(s) + "/n";

}

/*--------输出--------

源字符串:  1985aaa1985bb            验证结果:  True

源字符串:  bcae1958fiefadf1955fef   验证结果:  False

源字符串:  atijc1944cvkd            验证结果:  False

源字符串:  df2564isdjfef2564d       验证结果:  True

源字符串:  abc1234def5678ghi5678jkl 验证结果:  False

*/

2.2     提取——Match()、Matches()

提取主要是从源字符串中,取得一个或多个符合某一规律或规则的子串。一般来说,在字符串处理中,提取应用比较广泛。提取时用得比较多的是Match()和Matches()方法,以及结果处理时Match类和MatchCollection类的一些方法,有时也会用到Capture类的一些方法。

2.2.1  提取单次匹配内容——Match()

当需要提取的内容只有一个,或是只需要获取第一次成功匹配的内容时,可以使用Match()方法。当使用Match()方法时,只要在某一位置匹配成功,就不再继续尝试匹配,并返回一个Match类型的对象。

举例:提取姓名

源字符串:姓名:张三,性别:男,年龄:25

代码实现:

string test = "姓名:张三,性别:男,年龄:25";

Regex reg = new Regex(@"(?<=姓名:)[^,]+");

Match m = reg.Match(test);

if (m.Success)    //验证是否匹配成功

{

richTextBox2.Text = m.Value;

}

/*--------输出--------

张三

*/

虽然Match()只是取一次匹配,但是可以通过捕获组来获取多个指定子串,比如获取第一个<a…>标签的链接和文本。

string test = "abc<a href=/"www.test1.com/">测试一</a>def<a href=/"www.test2.com/">测试二</a>ghi";

Regex reg = new Regex(@"(?is)<a(?:(?!href=).)href=(['""]?)(?<url>[^""/s>]*)/1[^>]*>(?<text>(?:(?!</?a/b).)*)</a>");

Match m = reg.Match(test);

if(m.Success)

{

richTextBox2.Text += m.Groups["url"].Value + "/n";      //链接

richTextBox2.Text += m.Groups["text"].Value + "/n";     //文本

}

/*--------输出--------

www.test1.com

测试一

*/

对于捕获组捕获结果的引用,还有一种方式

string test = "abc<a href=/"www.test1.com/">测试一</a>def<a href=/"www.test2.com/">测试二</a>ghi";

Regex reg = new Regex(@"(?is)<a(?:(?!href=).)href=(['""]?)(?<url>[^""/s>]*)/1[^>]*>(?<text>(?:(?!</?a/b).)*)</a>"); Match m = reg.Match(test);

if(m.Success)

{

richTextBox2.Text += m.Result("${url}") + "/n";      //链接

richTextBox2.Text += m.Result("${text}") + "/n";     //文本

}

/*--------输出--------

www.test1.com

测试一

*/

这两种方法获取的结果都是一样的,使用哪一种,通常根据个人习惯而定。

2.2.2  提取多次匹配内容——Matches()

当需要提取的内容有多个,并且需要提取所有符合规律的子串时,可以使用Matches()方法。当使用Matches()方法时,需要遍历源字符串的每一个位置进行尝试匹配,匹配结束返回一个MatchCollection类型的对象。

对于1.2.1节提到的提取链接和文本的例子,如果提取的是全部链接和文本,而不仅仅是第一个时,可以使用Matches()方法。

string test = "abc<a href=/"www.test1.com/">测试一</a>def<a href=/"www.test2.com/">测试二</a>ghi";

Regex reg = new Regex(@"(?is)<a(?:(?!href=).)href=(['""]?)(?<url>[^""/s>]*)/1[^>]*>(?<text>(?:(?!</?a/b).)*)</a>");

MatchCollection mc = reg.Matches(test);

foreach(Match m in mc)

{

richTextBox2.Text += m.Groups["url"].Value + "/n";      //链接

richTextBox2.Text += m.Groups["text"].Value + "/n";     //文本

}

/*--------输出--------

www.test1.com

测试一

www.test2.com

测试二

*/

对于Matches(),某些场景下,也可以通过Count属性,用做统计符合某一规律的子串出现的次数,例如统计字符串中独立的“3”出现的次数。

string test = "137,1,33,4,3,6,21,3,35,93,2,98";

Regex reg = new Regex(@"/b3/b");

int count = reg.Matches(test).Count;    //2

这时候关心的只是匹配成功的次数,对于匹配的内容是不关心的,所以实现这种需求时,正则应尽量简洁,能达到目的即可,这样可以加快匹配效率,减少资源占用。比如上面的提取链接的源字符串中,统计<a…>标签出现的次数,一般来说,如下代码即可达到目的了。

string test = "abc<a href=/"www.test1.com/">测试一</a>def<a href=/"www.test2.com/">测试二</a>ghi";

Regex reg = new Regex(@"(?i)<a/b");

int count = reg.Matches(test).Count;    //2

2.2.3  捕获组匹配过程集合——Capture

在某些情况下,一个正则表达式整体匹配一次时,其中的捕获组可能会匹配多次。

举例

源字符串:<region name=oldslist col=1 row=2 order=asc>abcsadf </region> jfdsajf  <region name=newslist class="list" col=4 row=10 order=desc>abcsadf </region>

需求:提取出每个region的属性和属性值,按region分组。

对于这个需求,可以先提取出所有region,再对每个region标签提取它的属性和属性值,但这样做比较麻烦,可以考虑在一个正则表达式中提取。由于属性的个数是不固定的,所以不能用固定个数的量词来匹配属性对,正则可以写为

(?is)<region/s+(?:(?<key>[^/s=]+)=(?<value>[^/s>]+)/s*)+>

此时如果还用Groups来取匹配结果时,由于Groups只保留最后一次匹配结果,所以只能取到最后一次匹配成功的子串。这时就要用到Captures属性。

string test = "<region name=oldslist col=1 row=2 order=asc>abcsadf </region> jfdsajf  <region name=newslist class="list" col=4 row=10 order=desc>abcsadf </region>";

MatchCollection mc = Regex.Matches(test, @"(?is)<region/s+(?:(?<key>[^/s=]+)=(?<value>[^/s>]+)/s*)+>");

for (int i = 0; i < mc.Count; i++)

{

richTextBox2.Text += "第" + (i + 1) + "个region的属性:/n";

for (int j = 0; j < mc[i].Groups["key"].Captures.Count; j++)

{

richTextBox2.Text += "属性: " + mc[i].Groups["key"].Captures[j].Value.PadRight(10, ' ') + "  值: " + mc[i].Groups["value"].Captures[j].Value + "/n";

}

richTextBox2.Text += "/n";

}

/*--------输出--------

第1个region的属性:

属性: name        值: oldslist

属性: col         值: 1

属性: row         值: 2

属性: order       值: asc

第2个region的属性:

属性: name        值: newslist

属性: class       值: list

属性: col         值: 4

属性: row         值: 10

属性: order       值: desc

*/

Group实际上是Capture的一个集合,在捕获组只匹配一个子串时,这个集合只有一个元素,而在捕获组先后匹配多个子串时,Groups[i].Value只保留最后一个匹配结果,而Capture集合却可以记录匹配过程中匹配到的所有子串。

Capture的应用场景并不多,对于上面的例子,如果不使用 Capture,可以通过分次匹配的方式实现,但是在一些复杂的表达式中,很难进行分次匹配,这时Capture就比较有用了。

2.3      替换

替换主要是从源字符串中,将符合某一规律或规则的子串替换为其它内容。一般来说,在字符串处理中,替换应用也比较广泛。替换主要是用Replace()方法,在一些替换规则复杂的应用场景中,也可能会用到委托方法。

2.3.1  一般替换

替换的目的很明确,只要找出待替换子串的规律,替换为目标子串就可以了。

举例1

源字符串:<img src="/imgs/logo.jpg"> abc <img src="http://www.test.com/imgs/top.gif">

需求:将相对地址替换为绝对地址,已经是绝对地址的不替换。

string test = "<img src=/"/imgs/logo.jpg/"> abc <img src=/"http://www.test.com/imgs/top.gif/">";

Regex reg = new Regex(@"(?i)(?<=src=(['""]?))(?!http://)(?=[^'""/s>]+/1)");

string result = reg.Replace(test, "http://www.test.com");

/*--------输出--------

<img src="http://www.test.com/imgs/logo.jpg"> abc <img src="http://www.test.com/imgs/top.gif">

*/

这里需要说明的是,在.NET中只提供了一个Replace()方法,没有提供类似于Java中的replaceAll()和replaceFirst()两种方法,所以如果在.NET中只替换第一次出现的符合规律的子串时,需要在正则表达式中处理。

举例2

源字符串:abc123def123ghi

需求:将第一次出现的“123”替换为空,其余位置不替换。

string test = "abc123def123ghi";

Regex reg = new Regex(@"(?s)^((?:(?!123).)*)123");

string result = reg.Replace(test, "$1");

/*--------输出--------

abcdef123ghi

*/

这时用“^”限定只替换第一次出现的子串,由于绝大多数正则引擎都对“^”进行了优化,所以正则表达式在位置0处匹配成功或失败后,将不再对其它位置进行尝试匹配。

2.3.2  替换中的委托方法应用

对于一些比较复杂的替换规则,可能会用到委托方法,由于这种应用属于比较典型的一种应用,所以将在后面的文章中单独进行介绍。

2.4     分割

分割就是用符合某一规律的子串,将源字符串分割成一个数组,主要用到的是Split()方法。由于Regex的Split()方法中,并没有提供类似于string的Split()方法的StringSplitOptions.RemoveEmptyEntries参数,而如果符合规律的子串出现在开头或结尾时,会出现不需要的空串,这时需要在正则表达式中进行一下处理。

举例1

源字符串:汉字123文字english

需求:按英文单词和非英文单词进行分割(英文单词包括由a-z,A-Z,0-9,_组成的子串)。

string str = "汉字123文字english";

string[] result = Regex.Split(str, @"(?<!^)/b(?!$)", RegexOptions.ECMAScript);

foreach (string s in result)

{

richTextBox2.Text += s + "/n";

}

/*--------输出--------

汉字

123

文字

English

*/

这里分别用“(?<!^)”和“(?!$)”来限定不以开头或结尾的子串进行分割,结果中也就不会出现不必要的空串了。

还有一些应用,其实可以算作是正则就用技巧范畴的了。

举例2

源字符串:Left(姓名,1),Left(姓名,1) ,  Left    (姓名,1)

需求:以不在“()”内的“,”进行分割。

string test = "Left(姓名,1),Left(姓名,1) ,  Left    (姓名,1)";

Regex reg = new Regex(@"(?<!/([^)]*),(?![^(]*/))");

string[] sArray = reg.Split(test);

foreach (string s in sArray)

{

richTextBox2.Text += s + "/n";

}

/*--------输出--------

Left(姓名,1)

Left(姓名,1)

Left    (姓名,1)

*/

使用正则的Split()方法时,有一点需求注意,那就是如果正则中出现了捕获组,那么捕获组匹配到的内容也会保存到分割结果中。

以下举例不做详细说明,看下结果基本上就明白了。

string test = "aa11<bbb>cc22<ddd>ee";

string[] temp = Regex.Split(test, @"[0-9]+(<[^>]*>)");

foreach (string s in temp)

{

richTextBox2.Text += s + "/n";

}

/*--------输出--------

aa

<bbb>

cc

<ddd>

ee

*/

如果不想把捕获组匹配到的内容也存入结果,可以使用非捕获组。

string test = "aa11<bbb>cc22<ddd>ee";

string[] temp = Regex.Split(test, @"[0-9]+(?:<[^>]*>)");

foreach (string s in temp)

{

richTextBox2.Text += s + "/n";

}

/*--------输出--------

aa

cc

ee

*/

3       扩展应用

这里介绍一些可能涉及到的一些.NET中的正则扩展应用。

3.1     动态生成正则时的转义——Escape()

有时需要根据一些变量动态生成正则表达式,这时如果变量中含有正则中的元字符,会被解析成元字符,就可能会导致正则编译不通过,从而导致程序异常,需要对变量进行转义处理。Regex. Escape()方法通过替换为转义码来转义最小的字符集(/、*、+、?、|、{、[、(、)、^、$、.、# 和空白)。

比如根据用户输入的id取相应的div标签,id中没有元字符时,可以取得正确结果。

string test = "<div id=/"test1/">abc</div><div id=/"test2/">def</div>";

string[] ids = new string[] { "test1", "test2" };

foreach (string id in ids)

{

Regex reg = new Regex(@"(?is)<div/s+id=""" + id + @"""[^>]*>(?:(?!</?div/b).)*</div>");

MatchCollection mc = reg.Matches(test);

foreach (Match m in mc)

{

richTextBox2.Text += m.Value + "/n";

}

}

/*--------输出--------

<div id="test1">abc</div>

<div id="test2">def</div>

*/

但是如果输入的id中一旦出现未经转义的元字符,如“abc(”,就会抛类似于下面的异常。

正在分析“(?is)<div/s+id="abc("[^>]*>(?:(?!</?div/b).)*</div>”- ) 不足。

此时可以用Escape()方法对输入的变量进行转义处理。

string test = "<div id=/"test1/">abc</div><div id=/"test2/">def</div>";

string[] ids = new string[] { "test1", "test2", "abc(" };

foreach (string id in ids)

{

Regex reg = new Regex(@"(?is)<div/s+id=""" + Regex.Escape(id) + @"""[^>]*>(?:(?!</?div/b).)*</div>");

MatchCollection mc = reg.Matches(test);

foreach (Match m in mc)

{

richTextBox2.Text += m.Value + "/n";

}

}

/*--------输出--------

<div id="test1">abc</div>

<div id="test2">def</div>

*/

使用Escape()方法转义后,就可以得到正确的结果,而不会抛异常了。

3.2     静态方法

.NET中一些Regex类的常见方法都提供了相应的静态方法,可以不显式的声明Regex对象,而直接调用相应的方法,书写起来更方便,代码更简洁、易读。

比如替换IP地址最后一节为“*”,只需一行代码。

string result = Regex.Replace("10.27.123.12", @"/d+$", "*");   //10.27.123.*

静态方法每次调用都会创建一个临时的Regex对象,使用之后释放,所以每次调用静态方法时,都会重新编译,而这将会降低执行效率。因此在循环或是频繁调用的方法中,不适合使用静态方法,而需要进行显式声明Regex对象。

但是对于一些只调用一次,或是对执行效率没有要求的场景下,静态方法则是很不错的选择。

  1. Regex..::.Split(String) 方法与 String..::.Split(array<Char>[]()[]) 方法类似,但前者是在由正则表达式而不是一组字符确定的分隔符处拆分字符串。将以尽可能多的次数拆分该字符串。如果找不到分隔符,返回值将包含一个值为原始 input 参数字符串的元素。
  2. 如果多个匹配项彼此相邻,则会在数组中插入空字符串。例如,如果用一个连字符来拆分字符串,将会导致返回的数组在两个相邻的连字符所在的位置包括一个空字符串,如下面的代码所示。
  3. Visual Basic  复制代码
  4. Dim regex As Regex = New Regex("-")         ' Split on hyphens.
  5. Dim substrings() As String = regex.Split("plum--pear")
  6. For Each match As String In substrings
  7. Console.WriteLine("'{0}'", match)
  8. Next
  9. ' The method writes the following to the console:
  10. '    'plum'
  11. '    ''
  12. '    'pear'
  13. C#  复制代码
  14. Regex regex = new Regex("-");         // Split on hyphens.
  15. string[] substrings = regex.Split("plum--pear");
  16. foreach (string match in substrings)
  17. {
  18. Console.WriteLine("'{0}'", match);
  19. }
  20. // The method writes the following to the console:
  21. //    'plum'
  22. //    ''
  23. //    'pear'
  24. 如果将捕获括号用于 Regex.Split 表达式中,则任何捕获的文本将包含在生成的字符串数组中。例如,如果要通过在捕获括号中放入一个连字符的方式来拆分字符串“plum-pear”,则会向返回的数组添加一个包含该连字符的字符串元素。
  25. Visual Basic  复制代码
  26. Dim regex As Regex = New Regex("(-)")          ' Split on hyphens.
  27. Dim substrings() As String = regex.Split("plum-pear")
  28. For Each match As String In substrings
  29. Console.WriteLine("'{0}'", match)
  30. Next
  31. ' The method writes the following to the console:
  32. '    'plum'
  33. '    '-'
  34. '    'pear'
  35. C#  复制代码
  36. Regex regex = new Regex("(-)");         // Split on hyphens.
  37. string[] substrings = regex.Split("plum-pear");
  38. foreach (string match in substrings)
  39. {
  40. Console.WriteLine("'{0}'", match);
  41. }
  42. // The method writes the following to the console:
  43. //    'plum'
  44. //    '-'
  45. //    'pear'
  46. 但是,如果正则表达式模式包含多组捕获括号,则此方法的行为取决于 .NET Framework 的版本。在 .NET Framework 1.0 和 1.1 版中,如果在第一组捕获括号中未找到匹配项,则在返回的数组中不会包含从其他捕获括号中捕获的文本。在 .NET Framework 2.0 版中,所有捕获的文本还添加到返回的数组中。例如,下面的代码使用两组捕获括号从日期字符串中提取日期元素(包括日期分隔符)。第一组捕获括号捕获连字符,而第二组捕获括号捕获左斜线。如果已编译示例代码并在 .NET Framework 1.0 或 1.1 中运行,则它不包括斜线;如果已编译示例代码并在 .NET Framework 2.0 中运行,则它包括斜线。
  47. Visual Basic  复制代码
  48. Dim input As String = "07/14/2007"
  49. Dim pattern As String = "(-)|(/)"
  50. Dim regex As Regex = New Regex(pattern)
  51. For Each result As String In regex.Split(input)
  52. Console.WriteLine("'{0}'", result)
  53. Next
  54. ' In .NET 1.0 and 1.1, the method returns an array of
  55. ' 3 elements, as follows:
  56. '    '07'
  57. '    '14'
  58. '    '2007'
  59. '
  60. ' In .NET 2.0, the method returns an array of
  61. ' 5 elements, as follows:
  62. '    '07'
  63. '    '/'
  64. '    '14'
  65. '    '/'
  66. '    '2007'
  67. C#  复制代码
  68. string input = @"07/14/2007";
  69. string pattern = @"(-)|(/)";
  70. Regex regex = new Regex(pattern);
  71. foreach (string result in regex.Split(input))
  72. {
  73. Console.WriteLine("'{0}'", result);
  74. }
  75. // Under .NET 1.0 and 1.1, the method returns an array of
  76. // 3 elements, as follows:
  77. //    '07'
  78. //    '14'
  79. //    '2007'
  80. //
  81. // Under .NET 2.0, the method returns an array of
  82. // 5 elements, as follows:
  83. //    '07'
  84. //    '/'
  85. //    '14'
  86. //    '/'
  87. //    '2007'
  88. 如果正则表达式可以匹配空字符串,则 Split(String) 会将字符串拆分为由单字符组成的字符串的数组,因为每个位置都有空字符串分隔符。例如:
  89. Visual Basic  复制代码
  90. Dim input As String = "characters"
  91. Dim regex As New Regex("")
  92. Dim substrings() As String = regex.Split(input)
  93. Console.Write("{")
  94. For ctr As Integer = 0 to substrings.Length - 1
  95. Console.Write(substrings(ctr))
  96. If ctr < substrings.Length - 1 Then Console.Write(", ")
  97. Next
  98. Console.WriteLine("}")
  99. ' The example produces the following output:
  100. '    {, c, h, a, r, a, c, t, e, r, s, }
  101. C#  复制代码
  102. string input = "characters";
  103. Regex regex = new Regex("");
  104. string[] substrings = regex.Split(input);
  105. Console.Write("{");
  106. for(int ctr = 0; ctr < substrings.Length; ctr++)
  107. {
  108. Console.Write(substrings[ctr]);
  109. if (ctr < substrings.Length - 1)
  110. Console.Write(", ");
  111. }
  112. Console.WriteLine("}");
  113. // The example produces the following output:
  114. //    {, c, h, a, r, a, c, t, e, r, s, }
  115. 请注意,返回数组的开头和结尾还包括空字符串。

.NET正则基础——.NET正则类及方法应用的更多相关文章

  1. OC基础4:类和方法

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.类的声明(@interface)要放在 ...

  2. Python学习之路——迭代器、生成器、算法基础、正则

    一.迭代器: 迭代器是访问集合元素的一种方式. 迭代器对象是从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 另外,迭代 ...

  3. .NET正则基础之——平衡组

    1        概述 平衡组是微软在.NET中提出的一个概念,主要是结合几种正则语法规则,提供对配对出现的嵌套结构的匹配..NET是目前对正则支持最完备.功能最强大的语言平台之一,而平衡组正是其强大 ...

  4. Java提取文本文档中的所有网址(小案例介绍正则基础知识)

    正则表达式基础以及Java中使用正则查找 定义: 正则表达式是一些用来匹配和处理文本的字符串 正则的基础(先大致了解下) 1. 正则表达式的作用 查找特定的信息(搜索) 替换一些文本(替换) 2. 正 ...

  5. python基础-re正则

    一:什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. (在Python中)它内嵌在Python中,并通过 ...

  6. JAVA基础(二)—— 常用的类与方法

    JAVA基础(二)-- 常用的类与方法 1 Math类 abs ceil floor 绝对值 大于等于该浮点数的最小整数 小于等于该浮点数的最大整数 max min round 两参数中较大的 两参数 ...

  7. c#面向对象基础 类、方法、方法重载

    C#是纯粹的面向对象编程语言,它真正体现了“一切皆为对象”的精神.在C#中,即使是最基本的数据类型,如int,double,bool类型,都属于System.Object(Object为所有类型的基类 ...

  8. python基础--类的方法

    一:类的方法说明 类的方法分为实例方法,析构方法,构造方法,类方法,静态方法,属性方法,等等 类方法和静态方法都可以被类和类实例调用,类实例方法仅可以被类实例调用 类方法的隐含调用参数是类,而类实例方 ...

  9. Java基础之对包,类,方法,变量理解(灵感)

    包,类,方法,变量 灵感乍现 感觉就如电脑上的各个大小文档一般,只不过名称不同,用法不同,功效不同,就好比你要调用网上的一个图片,这个图片可以是变量,可以是方法,可以是类.你要调用可以把他幻化成接口, ...

随机推荐

  1. 15stl模板

    1.stack #include<iostream> #include<stdio.h> #include<stack> using namespace std; ...

  2. 【Linux】Mutex互斥量线程同步的例子

    0.互斥量  Windows下的互斥量 是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致. 当多次Wait**时就 ...

  3. windows10UWP开发真机调试时遇到DEP6100和DEP6200解决办法

    windows10UWP开发真机调试时遇到DEP6100和DEP6200(其实未连接上设备都会报这两个错误,无论真机还是虚拟机)…… 此方法适合真机调试时遇到: 弹出提示框要求输入配对码,无论如何输入 ...

  4. Python超级程序员使用的开发工具

    我以个人的身份采访了几个顶尖的Python程序员,问了他们以下5个简单的问题: 当前你的主要开发任务是什么? 你在项目中使用的电脑是怎样的? 你使用什么IDE开发? 你将来的计划是什么? 有什么给Py ...

  5. phpcms V9实现QQ登陆OAuth2.0

    phpcmsV9使用的QQ登陆依然是OAuth1.0,但现在腾讯已经不审核使用OAuth1.0的网站了.这对于使用pc的站长来讲是一个无比巨大的坑.经过对phpcms论坛的一位同学做的插件进行修改,现 ...

  6. MyEclipse2015对Javascript自动提示的终极支持

    2015通过集成Tern.js,进入了JS自动提示的最新时代 先看看具体效果吧:   点击链接会进入:   而tern.js已经支持相当多的框架:   关键这个提示不只是纯粹的js文件,对于jsp等等 ...

  7. mongdb创建自增主键(primary key)的相关讨论 - Jason.Zhi

    根据mongodb官方文档介绍,如果在插入(insert)操作时,没有指定主键id,那么它会自动给插入行自动附上一个主键id.看起来不错,但是详细看看,就会发现这个id值有点复杂. 如下图: mong ...

  8. android 源码 中修改系统字体大小

    在源码\android\frameworks\base\core\java\android\content\res \Configuration.java下有读取DEFAULT_FONTSCALE的值 ...

  9. xe mysql

    [FireDAC][Phys][MySQL]-314. Cannot load vendor library [libmysql.dll or libmysqld.dll]. The specifie ...

  10. 【下载】支持中文的 jspSmartUpload jar 包

    http://www.blogjava.net/hijackwust/archive/2007/08/22/138598.html —————————————————————————————————— ...