C#中正则表达式的3种匹配模式
在C#中,我们⼀般使⽤Regex类来表⽰⼀个正则表达式。⼀般正则表达式引擎⽀持以下3种匹配模式:单⾏模式(Singleline)、多⾏模式(Multiline)与忽略⼤⼩写(IgnoreCase)。
1. 单⾏模式(Singleline)
MSDN定义:更改点 (.) 的含义,使它与每⼀个字符匹配(⽽不是与除 \n 之外的每个字符匹配)。
使⽤单⾏模式的典型场景是获取⽹页源码中的信息。
⽰例:
<html>
<body>
<div>
Line 1
Line 2
</div>
</body>
</html>
我们想把div标签以及其中的内容提取出来,编写代码如下:
string pattern = @"<div>.*</div>";
Regex regex = new Regex(pattern);
if (regex.IsMatch(str))
Console.WriteLine(regex.Match(str).Value);
else
Console.WriteLine("Mismatch!");
//结果为:Mismatch!
错误分析:
正则表达式提取中文字符⼀般认为点符号(.)是匹配任意单个字符的,⽽(.*)就是匹配任意多个字符。但实际上点符号不能匹配换⾏符。在Windows中与它等效的表达式为[^\r\n]。
⽽我们从⽹站上获取的HTML源码,极少有不换⾏的。这时候单⾏模式派上⽤场了,它可以改变点符号的意义。修改regex实例的构造函数,⽤RegexOptions.Singleline来声明使⽤单⾏模式:
string pattern = @"<div>.*</div>";
Regex regex = new Regex(pattern, RegexOptions.Singleline);
if (regex.IsMatch(str))
Console.WriteLine(regex.Match(str).Value);
else
Console.WriteLine("Mismatch!");
/*
结果为:
<div>
Line 1
Line 2
</div>
*/
单⾏模式的嵌⼊修饰符:
我们可以直接在正则表达式中嵌⼊单⾏模式:
(?s)<div>.*</div>
(?s)修饰符说明,其后⾯的表达式采⽤单⾏模式。所以使⽤时请不要将它放在末尾。另外可以使⽤(?-s)关闭单⾏模式。
注意:嵌⼊模式的优先级要⾼于Regex类的RegexOptions设置,所以使⽤了(?s)后,⽆论是否使⽤
RegexOptions.Singleline,均按照单⾏模式解析。
2. 多⾏模式(Multiline)
MSDN定义:更改 ^ 和 $ 的含义,使它们分别在任意⼀⾏的⾏⾸和⾏尾匹配,⽽不仅仅在整个字符串的开头和结尾匹配。
⽰例:
有⼀个⽂本⽂件,它的每⼀⾏是⼀个⽤户名,将⽂件读⼊变量str中进⾏处理。其内容如下:
⼆⼗四画⽣
TerryLee
莫相会
Dflying Chen
Rainy
借⽤博客园各位前辈的⼤名:)
我们想出⼀个使⽤英⽂字母开头的⽤户名,编写代码如下:
string pattern = @"^[A-Za-z]+.*";
Regex regex = new Regex(pattern);
if (regex.IsMatch(str))
Console.WriteLine(regex.Match(str).Value);
else
Console.WriteLine("Mismatch!");
//结果为:Mismatch!
错误分析:
(^)是字符串的起始锚定,str的第⼀个字符是⼀个中⽂字,所以匹配不上。我们就可以使⽤多⾏模式来改变(^)的含义,使它匹配每⼀⾏的起始,⽽不是整个字符串的起始。
更改代码如下:
string pattern = @"^[A-Za-z]+.*";
Regex regex = new Regex(pattern, RegexOptions.Multiline);
if (regex.IsMatch(str))
Console.WriteLine(regex.Match(str).Value);
else
Console.WriteLine("Mismatch!");
//结果为:TerryLee
同时,多⾏模式也会改变($)的含义,使它匹配每⼀⾏的结尾,⽽不是整个字符串的结尾。
与(^)和($)不同的是,(\A)和(\Z)并不受多⾏模式的影响,永远匹配整个字符串的起始和结尾。
多⾏模式的嵌⼊修饰符:(?m)与(?-m)
3. 忽略⼤⼩写(IgnoreCase)
MSDN定义:指定不区分⼤⼩写的匹配。
这个模式很容易理解,它认为⼤⼩写字符是相同的。我们仍以上例来说明。
⽰例:
string pattern = @"^[a-z]+.*";
Regex regex = new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
if (regex.IsMatch(str))
Console.WriteLine(regex.Match(str).Value);
else
Console.WriteLine("Mismatch!");
//结果为:TerryLee
分析:请注意这次使⽤的正则表达式,我们并没有写⼊⼤写字母,但却匹配了以⼤写字母开头的名字,这就是忽略⼤⼩写的效果。
忽略⼤⼩写的嵌⼊修饰符:(?i)与(?-i)
总结:
最后我们⽤⼀个表格来总结⼀下这三个模式
定义影响的表达式RegexOptions枚
举嵌⼊标识
符
单⾏模
式
更改点 (.) 的含义,使它与每⼀个字符匹配(⽽不是与除 \n 之外的每个字符匹配)。Singleline(?s)
多⾏模式更改 ^ 和 $ 的含义,使它们分别在任意⼀⾏的⾏⾸和⾏尾匹配,⽽不仅仅在整个字
符串的开头和结尾匹配。
Multiline(?m)
忽略⼤
⼩写
指定不区分⼤⼩写的匹配。IgnoreCase(?i)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论