C# 正则表达式进阶
.NET中的正则表达式是基于Perl5的正则表达式。
超时
从.NETFramework4.5开始,正则表达式支持在匹配操作中指定超时时间。如果匹配超时,就会抛出RegexMatchTimeoutException。
所有方法都增加了带超时时间参数的重载:
publicstaticMatchMatch(stringinput,stringpattern,RegexOptionsoptions,TimeSpanmatchTimeout); publicstaticMatchCollectionMatches(stringinput,stringpattern,RegexOptionsoptions,TimeSpanmatchTimeout); publicstaticstringReplace(stringinput,stringpattern,stringreplacement,RegexOptionsoptions,TimeSpanmatchTimeout); publicstaticstring[]Split(stringinput,stringpattern,RegexOptionsoptions,TimeSpanmatchTimeout);
如果应用程序需要处理任意的正则表达式(例如在高级搜索对话框中)则务必使用该参数以防止一些恶意的正则表达式导致无限计算。
编译正则表达式
RegexOptions.Compiled选项将会使Regex实例通过轻量级的代码生成器动态地构建并编译针对特定正则表达式的代码,提高匹配速度。
模式修正符
模式修正符不仅可以打开,还可以关闭。如下示例,先打开忽略大小写,再关闭忽略大小写,所以匹配结果是Aa。
Regex.Match("AAAa","(?i)a(?-i)a").Value;//Aa
零宽断言
现在要写一个用于验证密码是否符合要求的正则表达式,要求是至少包含一个数字。
这个很简单,如下就可以了
Regex.IsMatch("12345678","\d");
现在加一个条件,长度要大于6位。似乎用一个正则无法实现。
其实是可以的,用零宽断言中的正向先行断言就可以了。
正向先行断言(?=exp),一般用来匹配exp之前的内容。例如下面个例子,要取出姓名,需要匹配,之前的内容。
Regex.Match("姓名张三,男,30岁","(?<=姓名).*?(?=,)").Value;//张三
其实,正确的理解是:正向先行断言,匹配成功之后,会退回起始位置,然后继续之后的匹配。
这里最重要的一点是,匹配成功以后退回起始位置,所以,对它正确的理解是,一个前向条件判断。
那么上面的密码至少包含一个数字,且长度大于6就好实现了:
Regex.IsMatch("abcde6",@"(?=.*\d).{6,}");
我们再增加一点难度,密码要求符合如下条件:
- 至少8位
- 至少包含一个数字
- 至少包含一个小写字母
- 至少包含一个大写字母
stringpattern=@"(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"; Regex.IsMatch("12345678",pattern);//false Regex.IsMatch("1234567a",pattern);//false Regex.IsMatch("123456aA",pattern);//true
分割字符串
分割字符串分隔符不会包含在结果中,若要将分隔符包含在结果中,则可以将表达式包含在正前向条件中。
foreach(stringsinRegex.Split("oneTwoThree","(?=[A-Z])")) Console.WriteLine(s); //one //Two //Three
分组
正则表达式中可以通过\n语法来引用索引为n的分组。
varm=Regex.Matches("poppopepeep",@"\b(\w)\w+\1\b"); //pop //peep
命名捕获分组语法:
(?'组名'表达式)或(?<组名>表达式)
引用命名分组语法:
\k'组名'或\k<组名>
替换并分割文本
替换字符串可以通过$0作为替代结构访问原始的匹配。$1、$2访问任意捕获的分组。对于命名分组,可以通过${name}的方式进行访问。
给所有数字加上<>:
Console.WriteLine(Regex.Replace("1+11=12",@"\d+",@"<$0>")); //<1>+<11>=<12>
MatchEvaluator委托
Replace方法有一个重载,使用MatchEvaluator委托作为参数,替代replacement。该委托将对每个匹配执行一次,并使用其返回结果替换原字符串中的值。
MatchEvaluator委托定义:
publicdelegatestringMatchEvaluator(Matchmatch);
示例:
Console.WriteLine(Regex.Replace("1+11=12",@"\d+",m=>(int.Parse(m.Value)*10).ToString())); //10+110=120
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。