您的位置:首页 > 其它

正则基础之——.NET匹配模式

2011-05-24 09:13 267 查看

1

概述

匹配模式指的是一些可以改变正则表达式匹配行为的选项或修饰符。不同的语言支持的匹配模式不同,使用的方式也不同。

一般可分为全局和内联两种。下面主要介绍
.NET

中的匹配模式,其它语言的匹配模式,后续视情况补充。

2

匹配模式

2.1

全局匹配模式和内联匹配模式概述

.NET

中的全局匹配模式是通过
RegexOptions

枚举值指定的,可以按位“或”进行组合,全局匹配模式只能作用于整个正则表达式。全局匹配模式提供的模式更多,可以灵活的动态指定匹配模式。

而内联匹配模式是通过在正则表达式中,使用
(?imnsx-imnsx:)


(?imnsx-imnsx)

的分组构造来改变正则表达式的匹配行为的。内联匹配模式更灵活、简洁,但是提供的模式较少。

下表摘自
MSDN

,部分说明做了修改。

RegexOption

成员


内联字符


说明


None

N/A

指定不设置任何选项。

IgnoreCase

i

指定不区分大小写的匹配。

Multiline

m

指定多行模式。更改
^



$


的含义,以使它们分别与任何行的开头和结尾匹配,而不只是与整个字符串的开头和结尾匹配。

ExplicitCapture

n

指定唯一有效的捕获是显式命名或编号的 (?<

name

>…)
形式的组。这允许圆括号充当非捕获组,从而避免了由
(?:…)
导致的语法上的笨拙。

Compiled

N/A

指定正则表达式将被编译为程序集。生成该正则表达式的 Microsoft
中间语言 (MSIL)
代码;以较长的启动时间为代价,得到更快的执行速度。

Singleline

s

指定单行模式。更改句点字符 (.)
的含义,以使它与每个字符(而不是除
/n


之外的所有字符)匹配。

IgnorePatternWhitespace

x

指定从模式中排除非转义空白并启用数字符号 (#)
后面的注释。请注意,空白永远不会从字符类中消除。

RightToLeft

N/A

指定搜索是从右向左而不是从左向右进行的。具有此选项的正则表达式将移动到起始位置的左边而不是右边。

ECMAScript

N/A

指定已为表达式启用了符合 ECMAScript
的行为。此选项仅可与
IgnoreCase



Multiline


标志一起使用。将
ECMAScript


同任何其他标志一起使用将导致异常。

CultureInvariant

N/A

指定忽略语言中的区域性差异。

2.2

全局匹配模式

下面根据各种模式使用的频率进行讲解。

2.2.1

IgnoreCase

忽略大小写

几乎所有支持正则的语言中都提供了这一模式,是应用最多的模式之一,同时也是被“滥”用最多的模式之一。

开启忽略大小写模式,则字符可以同时匹配大写或小写形式。比如在此模式下,正则表达式“
<br>


”可同时匹配“
<br>


”和“
<BR>




但并不是所有的字符都有大小写形式,所以在书写的正则中,如果不存在可区分大小写形式的元字符或是字符序列时,开启这一模式是没有任何意义的。

比如替换一般的
html

标签的正则表达式

string
result = Regex
.Replace(srcStr, @"<[^>]*>"
, ""
, RegexOptions
.IgnoreCase);

因为
<[^>]*>


没有哪一个元字符或是字符序列具有大小写形式,所以这里的

RegexOptions
.IgnoreCase
是多余的,用在这里虽然不会改变匹配结果,但是会降低匹配效率,同时这也不是一个好的习惯。

只有在正则表达式中,注意是正则表达式中,而不是待匹配的源字符串中,涉及到大小写形式的元字符或是字符序列时,才使用

IgnoreCase
模式。

2.2.2

Multiline

多行模式

多行模式改变的是“
^

”和“
$

”的匹配行为,使“
^

”和“
$

”不仅可以匹配整个字符串的开始和结束位置,还可以匹配每行的开始和结束位置。

首先说明一下“行”的范围。虽然我们在程序中习惯用“
/r/n

”来表示换行,但实际上“
/r

”和“
/n

”是不相关的两个字符,一个表示回车,一个表示换行。由于历史原因,“
/r

”并不是所有系统都支持的,所以“行”是由“
/n

”来分割的,其中“
/n

”属于前一“行”,而不属于后一“行”。

举例来说,字符串“
a/r/nbc/r/n
”共有三行,“
a/r/n

”为一行,“
bc/r/n

”为一行,最后还有一个“”空行。

2.2.2.1

在不开启多行模式情况下,“
^

”和“
$

”匹配范围

“^
”的匹配范围

MatchCollection
mc = Regex
.Matches("a/r/nbc/r/n"
, @"^"
);

foreach
(Match
m in
mc)

{

richTextBox2.Text += "

匹配内容:"

+ m.Value + "

匹配开始索引:"

+ m.Index + "

匹配长度:"

+ m.Length + "/n"
;

}

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

匹配内容:

匹配开始索引:0

匹配长度:0

*/


$

”的匹配范围

MatchCollection
mc = Regex
.Matches("a/r/nbc/r/n"
, @"$"
);

foreach
(Match
m in
mc)

{

richTextBox2.Text += "

匹配内容:"

+ m.Value + "

匹配开始索引:"

+ m.Index + "

匹配长度:"

+ m.Length + "/n"
;

}

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

匹配内容:

匹配开始索引:6

匹配长度:0

匹配内容:

匹配开始索引:7

匹配长度:0

*/

注意:

这里需要注意的是,在没有开启多行模式时,字符串结尾如果是“/n
”,那么“$
”是可以匹配两个位置的,一个是“/n
”前的位置,一个是字符串结束位置。字符串结尾如果不是“/n
”,那么“$
”就只匹配字符串结束位置。

MatchCollection
mc = Regex
.Matches("a/r/nbc/r"
, @"$"
);

foreach
(Match
m in
mc)

{

richTextBox2.Text += "

匹配内容:"

+ m.Value + "

匹配开始索引:"

+ m.Index + "

匹配长度:"

+ m.Length + "/n"
;

}

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

匹配内容:

匹配开始索引:6

匹配长度:0

*/

2.2.2.2

在开启了多行模式后,“
^

”和“
$

”匹配范围

“^
”的匹配范围

MatchCollection
mc = Regex
.Matches("a/r/nbc/r/n"
, @"^"
, RegexOptions
.Multiline);

foreach
(Match
m in
mc)

{

richTextBox2.Text += "

匹配内容:"

+ m.Value + "

匹配开始索引:"

+ m.Index + "

匹配长度:"

+ m.Length + "/n"
;

}

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

匹配内容:

匹配开始索引:0

匹配长度:0

匹配内容:

匹配开始索引:3

匹配长度:0

匹配内容:

匹配开始索引:7

匹配长度:0

*/


$

”的匹配范围

MatchCollection
mc = Regex
.Matches("a/r/nbc/r/n"
, @"$"
, RegexOptions
.Multiline);

foreach
(Match
m in
mc)

{

richTextBox2.Text += "

匹配内容:"

+ m.Value + "

匹配开始索引:"

+ m.Index + "

匹配长度:"

+ m.Length + "/n"
;

}

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

匹配内容:

匹配开始索引:2

匹配长度:0

匹配内容:

匹配开始索引:6

匹配长度:0

匹配内容:

匹配开始索引:7

匹配长度:0

*/

2.2.2.3

匹配结果分析


^

”匹配结果分析

在不开启多行模式时,“
^

”只匹配字符串的开始位置,也就是位置
0



在开启了多行模式后,“
^

”匹配字符串开始位置和每个“
/n

”之后的行起始位置。


$

”匹配结果分析

在不开启多行模式时,如果字符结尾是“
/n

”,那么“
$

”会匹配结尾“
/n

”之前和结束两个位置。

在开启多行模式后,“
$

”匹配每行“
/n

”之前的位置和字符串结束位置。

需要注意的是,在
.NET

中,无论是否开启多行模式,“
^

”和“
$

”匹配的都只是一个位置,是零宽度的。其它语言中“
^

”和“
$

”的意义可能会有所不同。

只有在正则表达式中涉及到多行的“
^

”和“
$

”的匹配时,才使用
Multiline

模式。

2.2.2.4

应用举例

典型应用一(参考

正则中加字符的问题

):

需求描述:


fffffffffff

fffffffffff

dfdfdfdf

erererere

ferewfdfds

每行后面加一个
“ttt”

即为

fffffffffffttt

fffffffffffttt

dfdfdfdfttt

ererererettt

ferewfdfdsttt

代码实现:


string
result = Regex
.Replace(yourStr, @"^.*$"
, "$0ttt"
, RegexOptions
.Multiline);

典型应用二

需求描述:


源字符串


CODE39/CODE93:

A-Z

space,-,.,$,/,+,%

CODE128A:

A-Z

0-9

space,!,",#,$,%,&,…,(,)*,+,
逗号
,-,.,/, <,=,>,?,@,[,],^,_

CODE128B:

A-Z

a-z

0-9

space,!,",#,$,%,&,…,(,)*,+,
逗号
,-,.,/, <,=,>,?,@,[,],^,_,{,},|,~

CODE2of5:

0-9

说明:

CODE128A:
->
条码类别

A-Z

0-9

space,!,",#,$,%,&,…,(,)*,+,
逗号
,-,.,/, <,=,>,?,@,[,],^,_
->
表示范围

要求分别匹配出条码类别和表示范围

代码实现:


MatchCollection
mc = Regex
.Matches(yourStr, @"(?<type>[^/n:]+):/s*(?<range>(^(?!/s*$).*$/n?)*)"
, RegexOptions
.Multiline);

foreach
(Match
m in
mc)

{

richTextBox2.Text += "

条码类别: /n"

+ m.Groups["type"
].Value + "/n"
;

richTextBox2.Text += "

表示范围: /n"

+ m.Groups["range"
].Value + "/n"
;

}

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

条码类别:

CODE39/CODE93

表示范围:

A-Z

space,-,.,$,/,+,%

条码类别:

CODE128A

表示范围:

A-Z

0-9

space,!,",#,$,%,&,
…,(,)*,+,
逗号,-,.,/, <,=,>,?,@,[,],^,_

条码类别:

CODE128B

表示范围:

A-Z

a-z

0-9

space,!,",#,$,%,&,
…,(,)*,+,
逗号,-,.,/, <,=,>,?,@,[,],^,_,{,},|,~

条码类别:

CODE2of5

表示范围:

0-9

*/

2.2.3

Singleline

单行模式

单行模式改变的是小数点“
.

”的匹配行为,使小数点可以匹配包含换行符“
/n

”在内的任意一个字符。

这是一个很不幸的命名,总让人误会它与
Multiline

多行模式是有关联的,而事实上它改变的是小数点的匹配行为,与
Multiline

多行模式没有任何关联,由于历史原因,这一不幸的命名被保留了下来。使用时需要注意。

单行模式通常在匹配有换行的文本时使用,采用小数点
+

单行模式的方式匹配任意字符,在
.NET

中是效率最高的。参考

正则基础之——小数点



典型应用:

源字符串:

<a>There is one obvious advantage:</a>

<div>

<p>

You've seen it coming!<br/>

Buy now and get nothing for free!<br/>

Well, at least no free beer. Perhaps a bear,<br/>

if you can afford it.

</p>

</div>

<a>Now that you've got...</a>

<div>

<p>

your bear, you have to admit it!<br/>

No, we aren't selling bears.

</p>

</div>

需求:取
<div>

标签之间的内容

代码实现:


MatchCollection
mc = Regex
.Matches(yourStr, @"<div[^>]*>(?:(?!</div/b).)*</div>"
, RegexOptions
.Singleline|RegexOptions
.IgnoreCase);

foreach
(Match
m in
mc)

{

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

}

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

<div>

<p>

You've seen it coming!<br/>

Buy now and get nothing for free!<br/>

Well, at least no free beer. Perhaps a bear,<br/>

if you can afford it.

</p>

</div>

-------------------

<div>

<p>

your bear, you have to admit it!<br/>

No, we aren't selling bears.

</p>

</div>

-------------------

*/

2.2.4

Compiled

编译模式

Compiled

改变的是
.NET

中正则表达式的编译方式。启用了
Compiled

模式,会延长启动时间,占用更多的内存,会提高匹配速度。当然,对最终性能的影响,需要根据具体问题综合考虑的。这一模式也是被“滥”用最多的模式之一。

程序运行过程中,第一次遇到正则表达式,需要加载正则引擎,对正则表达式进行必要的语法检查,并做适当的优化,最后把它转换为适合正则引擎应用的形式。这种“解析”过程,对于复杂的正则表达式,频繁调用或是匹配较大的数据源时,对效率的影响较大。

这时可以在构建正则表达式时开启
Compiled

模式。这样做会将正则表达式直接编译为
MSIL

代码,在正则匹配过程中,可以由
JIT

优化为更快的本地机器代码,获得更高的匹配速度。但这种方式会降低正则的解析速度,占用更多的内存,而且它占用的内存在程序运行过程中会一直占用,无法释放。

什么场景下使用
Compiled

模式,需要根据实际情况具体问题具体分析,一般来说,以下场景不适合使用
Compiled

模式:

1.

对匹配效率没有要求的场景;

2.

非常简单的正则表达式;

3.

极少调用的方法中声明的正则表达式;

4.

循环体中声明的正则表达式(除了动态生成的正则表达式,否则不要在循环体内声明正则表达式);

5.

静态方法中声明的正则表达式(静态方法每次调用都需要重新编辑正则表达式,使用
Compiled

模式只会降低效率)。

2.2.5

RightToLeft

从右到左模式

RightToLeft

改变的是正则表达式匹配的顺序,从右到左进行匹配。目前只有
.NET

支持这一模式,但它对这一模式的支持并不是很完善,有时容易让人费解,所以除非对源字符串的构成很了解,而且又不得不使用的情况,否则不要轻易使用这一模式。

典型应用(参考

求一个好的算法

):

一个由字母组成的字符串,最长
14

位,要求每隔
2

位加一个逗号,最左边不加,求一个好的算法

例:
“abcdefg”

返回
“a,bc,de,fg”

代码实现:


string
test = "abcdefg"
;

string
result = Regex
.Replace(yourStr, @"(?<!^)[a-zA-Z]{2}"
, ",$0"
, RegexOptions
.RightToLeft);

2.2.6

None

这一模式指定不开启任何模式。在
.NET


RegexOptions

枚举值是按位





组合,
None

模式我目前只找到一种应用场景,就是在动态生成正则表达式时,动态指定模式时使用。

///

<summary>

///

动态生成正则参数列表

///

</summary>

///

<returns></returns>

private
RegexOptions
getParameter()

{

RegexOptions
roList = RegexOptions
.None;

if
(cbIgnoreCase.Checked)

{

roList = roList | RegexOptions
.IgnoreCase;

}

if
(cbSingleline.Checked)

{

roList = roList | RegexOptions
.Singleline;

}

if
(cbMultiline.Checked)

{

roList = roList | RegexOptions
.Multiline;

}

if
(cbCompiled.Checked)

{

roList = roList | RegexOptions
.Compiled;

}

if
(cbRightToLelft.Checked)

{

roList = roList | RegexOptions
.RightToLeft;

}

return
roList;

}

2.2.7

ExplicitCapture

这一模式改变的是普通捕获组的匹配行为。将普通捕获组解释为非捕获组,只有显式命名的命名捕获组才当作捕获组使用。

捕获组的作用是将括号
()

内子表达式匹配到的内容保存到内存中一个组里,供以后引用,在
.NET

中捕获组有两种形式

(Expression)


普通捕获组

(?<name>Expression)


命名捕获组

其它形式的
(?...)

都不是捕获组。

但是

(Expression)


这种捕获组语法规则也带来一个副作用,在一些不得不使用
()

的场合,会默认为使用了捕获组,将匹配到的内容保存到内存中,而有些情况下这些内容并不需要关心的,浪费了系统资源,降低了匹配效率,所以才有了非捕获组

(?:Expression)


的出现,来抵消这一副作用。而非捕获组带来的另一个副作用的就是可读性的降低。

ExplicitCapture

模式是为了在不牺牲匹配效率的前提下,提高正则表达式的可读性,一般在命名捕获组和普通捕获组混合出现,而又不关心普通捕获组的正则表达式中使用,如取链接和文字的正则表达式中

MatchCollection
mc = Regex
.Matches(yourStr, @"(?is)<a((?!href=).)*href=(?<s>['""]?)(?<url>[^""'/s>]*)/k<s>[^>]*>(?<text>((?!</a>).)*)</a>"
, RegexOptions
.ExplicitCapture);

foreach
(Match
m in
mc)

{

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

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

}

开启
ExplicitCapture

模式对正则表达式解释行为的影响,可以参考如下举例,匹配时间的正则表达式

未开启

ExplicitCapture


模式


string
test = "<li title=/"

截至2009-07-28 20:45:49
,用户的总技术分为:5988
;截至2009-07-26
日,用户的总技术分排名为:4133/">(...)</li>"

;

Regex
reg = new
Regex
(@"([01][0-9]|2[0-3])(:[0-5][0-9]){2}"
);

MatchCollection
mc = reg.Matches(test);

foreach
(Match
m in
mc)

{

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

richTextBox2.Text += m.Groups[1].Value + "/n"
;

richTextBox2.Text += m.Groups[2].Value + "/n"
;

}

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

20:45:49

20

:49

*/

开启

ExplicitCapture


模式


string
test = "<li title=/"

截至2009-07-28 20:45:49
,用户的总技术分为:5988
;截至2009-07-26
日,用户的总技术分排名为:4133/">(...)</li>"

;

Regex
reg = new
Regex
(@"([01][0-9]|2[0-3])(:[0-5][0-9]){2}"
);

MatchCollection
mc = reg.Matches(test);

foreach
(Match
m in
mc)

{

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

richTextBox2.Text += m.Groups[1].Value + "/n"
;

richTextBox2.Text += m.Groups[2].Value + "/n"
;

}

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

20:45:49

*/

一般来说,关心的只是整个正则表达式匹配的整体,启用了
ExplicitCapture

模式后,“
([01][0-9]|2[0-3])


”和“
(:[0-5][0-9])


”将不会被解释为捕获组,匹配到的内容也不会保存到内存中。

开启
ExplicitCapture

模式虽然可以提高正则表达式的可读性,但
ExplicitCapture

这一模式本身容易被人忽略,所以这种模式应用得也比较少。

一旦使用了
ExplicitCapture

模式,要注意的是,除非你清楚捕获组的编号规则,否则尽量不要再使用
/number

方式进行反向引用,可以使用
/k<name>

方式进行反向引用。

Regex
reg = new
Regex
(@"href=(['""]?)(?<url>[^'""/s>]+)/1"
, RegexOptions
.ExplicitCapture);

MatchCollection
mc = reg.Matches(yourStr);

foreach
(Match
m in
mc)

{

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

}

以上匹配链接的代码通常是得不到任何结果的,因为这里“
/1


”引用的内容,不再是“
(['""]?)

”匹配到的内容,而是“
(?<url>[^'""/s>]+)

”匹配到的内容,等价于“
(?<url>[^'""/s>]+)/k<url>

”,而这样的字符串,通常是不存在的。

2.2.8

IgnorePatternWhitespace

这一模式忽略正则表达式中的非转义空白字符,并启用“
#

”后面的注释,通常用于增强正则表达式的可读性或是用于教学目的。

举个例子基本上就会明白了

string
test = "(One) and ( Two (Three) Four)."
;

Regex
reg = new
Regex
(@"/(

#

普通开括弧

(?>
#
固化分组

/(
(?<OPEN>)
#
遇到开括弧'OPEN'
计数加1

|
#
分支结构

/)
(?<-OPEN>)
#
遇到闭括弧'OPEN'
计数减1

|
#
分支结构

[^()]+
#
非括弧的其它任意字符

)*
#
以上子串出现0
次或任意多次

(?(OPEN)(?!))
#
判断是否还有'OPEN'
,有则说明不配对,什么都不匹配

/)
#
普通闭括弧

"
, RegexOptions
.IgnorePatternWhitespace);

MatchCollection
mc = reg.Matches(test);

foreach
(Match
m in
mc)

{

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

}

其中的空白字符被忽略,“
#

”及该行后面的内容被解释为注释。

2.2.9

ECMAScript

这一模式将按
ECMA


JavaScript

语义来解析正则表达式。通常影响的是以下元字符的匹配行为

/w


/W


/d


/D


/s


/S

使得以上元字符只能匹配
ASCII

码字符,而不再是匹配相应的
Unicode

字符。

事实上比如需求中明确要求只匹配英文字母,数字,下划线,而不包含汉字等字符,那么完全可以用“
[A-Za-z0-9_]

”,而不使用“
/w

”,虽然不够简洁,但可读性更好,语义更明确。

这一模式在
.NET

中的应用比较少,如不清楚什么场景下应该使用,可以忽略这一模式。

2.2.10

CultureInvariant

这一模式指定忽略语言中的区域性差异。一般与
IgnoreCase

模式一起使用,这一模式的应用场景很少,一般可以忽略,无需了解。

2.3

内联匹配模式

内联匹配模式在正则表达式内部使用,可以改变局部子表达式的匹配行为,内联匹配模式支持的模式较少,仅有
immsx

五种,但使用起来更简洁,更灵活。在
.NET

中支持
(?imnsx-imnsx:)


(?imnsx-imnsx)

两种形式。

各内联匹配模式对应的全局匹配模式见匹配模式列表。以下仅就
(?i)

忽略大小写模式进行讲解,其它模式类同。

2.3.1

(?imnsx-imnsx:)

形式

语法:
(?i:Expression)



这种语法规则表达为括号内的子表达式开启忽略大小写模式。

举例:
^[A-Z](?i:[A-Z]{9,19})$



以上正则表示,首字符必须为大写字母,后面跟
9


19

个大小写字母。

string
[] test = new
string
[] { "Abc"
, "AbcdefGHIjklmn"
, "abcdefghijklmn"
};

Regex
reg = new
Regex
(@"^[A-Z](?i:[A-Z]{9,19})$"
);

foreach
(string
s in
test)

{

richTextBox2.Text += "

源字符串: "

+ s.PadRight(15, ' '
) + "

匹配结果: "

+ reg.IsMatch(s) + "/n"
;

}

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

源字符串: Abc

匹配结果: False

源字符串: AbcdefGHIjklmn

匹配结果: True

源字符串: abcdefghijklmn

匹配结果: False

*/

语法:
(?-i:Expression)



这种语法规则表达为括号内的子表达式关闭忽略大小写模式。通常与全局匹配模式配合使用,表示全局为忽略大小写的,局部为严格区分大小写。

举例:

<div id="(?-i:TEST)" [^>]*>[/w/s]+</div>


以上正则表示,
div

标签中,仅匹配
id

为全大写的“
TEST

”的标签内容,其余标签不匹配。

string
test = "<DIV id=/"Test/" class=/"create/">first</div> and <DIV id=/"TEST/" class=/"delete/">second</div>"
;

Regex
reg = new
Regex
(@"<div id=""(?-i:TEST)""[^>]*>[/w/s]+</div>"
, RegexOptions
.IgnoreCase);

MatchCollection
mc = reg.Matches(test);

foreach
(Match
m in
mc)

{

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

}

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

<DIV id="TEST" class="delete">second</div>

*/

2.3.2

(?imnsx-imnsx)

语法:
(?i)



(?-i)


(?i)


为所在位置右侧的子表达式开启忽略大小写模式,直到出现
(?-i)


或者到表达式结束为止;
(?-i)


为所在位置右侧的子表达式关闭忽略大小写模式,直到出现
(?i)


或者到表达式结束为止。

通常在正则表达式开始位置使用
(?i)


来代替

RegexOptions
.IgnoreCase
,使代码更简洁。如提取链接和文字的正则表达式

MatchCollection
mc = Regex
.Matches(yourStr, @"(?is)<a(?:(?!href=).)*href=(['""]?)(?<url>[^""'/s>]*)/1[^>]*>(?<text>(?:(?!</a>).)*)</a>"
);

foreach
(Match
m in
mc)

{

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

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

}

3

小结

.NET

中的正则匹配模式基本上已讲解完了,最后再来总结一下各匹配模式的应用场景吧。

RegexOption

成员


内联字符


作用/
应用场景


None

N/A

指定不设置任何选项。

一般在动态指定匹配模式时使用。

IgnoreCase

i

指定不区分大小写的匹配。

只有在正则表达式中,注意是正则表达式中,而不是待匹配的源字符串中,涉及到大小写形式的元字符或是字符序列时,才使用IgnoreCase
模式。

Multiline

m

指定多行模式。更改
^



$


的含义,以使它们分别与任何行的开头和结尾匹配,而不只是与整个字符串的开头和结尾匹配。

只有在正则表达式中涉及到多行的“^
”和“$
”的匹配时,才使用Multiline
模式。

ExplicitCapture

n

指定唯一有效的捕获是显式命名或编号的 (?<

name

>…)
形式的组。这允许圆括号充当非捕获组,从而避免了由
(?:…)
导致的语法上的笨拙。

ExplicitCapture
模式是为了在不牺牲匹配效率的前提下,提高正则表达式的可读性,一般在命名捕获组和普通捕获组混合出现,而又不关心普通捕获组的正则表达式中使用。

Compiled

N/A

指定正则表达式将被编译为程序集。生成该正则表达式的 Microsoft
中间语言 (MSIL)
代码;以较长的启动时间为代价,得到更快的执行速度。

以下场景不适合使用:

1.

对匹配效率没有要求的场景;

2.

非常简单的正则表达式;

3.

极少调用的方法中声明的正则表达式;

4.

循环体中声明的正则表达式(除了动态生成的正则表达式,否则不要在循环体内声明正则表达式);

5.

静态方法中声明的正则表达式(静态方法每次调用都需要重新编辑正则表达式,使用Compiled
模式只会降低效率)。

Singleline

s

指定单行模式。更改句点字符 (.)
的含义,以使它与每个字符(而不是除
/n


之外的所有字符)匹配。

单行模式通常在匹配有换行的文本时使用,采用小数点+
单行模式的方式匹配任意字符,在.NET
中是效率最高的。

IgnorePatternWhitespace

x

指定从模式中排除非转义空白并启用数字符号 (#)
后面的注释。请注意,空白永远不会从字符类中消除。

为了提高可读性,或是为正则表达式加注释时使用。

RightToLeft

N/A

指定搜索是从右向左而不是从左向右进行的。具有此选项的正则表达式将移动到起始位置的左边而不是右边。

除非对源字符串的构成很了解,而且又不得不使用的情况,否则不要轻易使用这一模式。

ECMAScript

N/A

指定已为表达式启用了符合 ECMAScript
的行为。此选项仅可与
IgnoreCase



Multiline


标志一起使用。将
ECMAScript


同任何其他标志一起使用将导致异常。

除非对这一模式应用场景很了解,否则不要使用。

CultureInvariant

N/A

指定忽略语言中的区域性差异。

很少使用,一般无需了解。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: