首页 > 学院 > 开发设计 > 正文

.NET正则基础——.NET正则类及方法应用

2019-11-17 02:55:15
字体:
来源:转载
供稿:网友
.NET正则基础——.NET正则类及方法应用

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位。

Regexreg =newRegex(@"^(?:[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 =newstring[] {"1985aaa1985bb","bcae1958fiefadf1955fef","atijc1944cvkd","df2564isdjfef2564d","abc1234def5678ghi5678jkl"};

Regexreg =newRegex(@"(/d{4})(?:(?!/1).)*/1");

foreach(stringsintest)

{

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 =newstring[] {"1985aaa1985bb","bcae1958fiefadf1955fef","atijc1944cvkd","df2564isdjfef2564d","abc1234def5678ghi5678jkl"};

Regexreg =newRegex(@"^(?:(?!/d{4}).)*(/d{4})(?:(?!/1).)*/1");

foreach(stringsintest)

{

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

代码实现:

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

Regexreg =newRegex(@"(?<=姓名:)[^,]+");

Matchm = reg.Match(test);

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

{

richTextBox2.Text = m.Value;

}

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

张三

*/

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

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

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

Matchm = reg.Match(test);

if(m.Success)

{

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

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

}

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

www.test1.com

测试一

*/

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

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

Regexreg =newRegex(@"(?is)<a(?:(?!href=).)href=(['""]?)(?<url>[^""/s>]*)/1[^>]*>(?<text>(?:(?!</?a/b).)*)</a>");Matchm = 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()方法。

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

Regexreg =newRegex(@"(?is)<a(

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表