匹配模式指的是一些可以改变正则表达式匹配行为的选项或修饰符。不同的语言支持的匹配模式不同,使用的方式也不同。
一般可分为全局和内联两种。下面主要介绍 .NET 中的匹配模式,其它语言的匹配模式,后续视情况补充。
.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 |
指定忽略语言中的区域性差异。 |
下面根据各种模式使用的频率进行讲解。
几乎所有支持正则的语言中都提供了这一模式,是应用最多的模式之一,同时也是被“滥”用最多的模式之一。
开启忽略大小写模式,则字符可以同时匹配大写或小写形式。比如在此模式下,正则表达式“ <br> ”可同时匹配“ <br> ”和“ <BR> ”
但并不是所有的字符都有大小写形式,所以在书写的正则中,如果不存在可区分大小写形式的元字符或是字符序列时,开启这一模式是没有任何意义的。
比如替换一般的 html 标签的正则表达式
string result = Regex .Replace(srcStr, @"<[^>]*>" , "" , RegexOptions .IgnoreCase);
因为 <[^>]*> 没有哪一个元字符或是字符序列具有大小写形式,所以这里的 RegexOptions .IgnoreCase 是多余的,用在这里虽然不会改变匹配结果,但是会降低匹配效率,同时这也不是一个好的习惯。
只有在正则表达式中,注意是正则表达式中,而不是待匹配的源字符串中,涉及到大小写形式的元字符或是字符序列时,才使用 IgnoreCase 模式。
多行模式改变的是“ ^ ”和“ $ ”的匹配行为,使“ ^ ”和“ $ ”不仅可以匹配整个字符串的开始和结束位置,还可以匹配每行的开始和结束位置。
首先说明一下“行”的范围。虽然我们在程序中习惯用“ /r/n ”来表示换行,但实际上“ /r ”和“ /n ”是不相关的两个字符,一个表示回车,一个表示换行。由于历史原因,“ /r ”并不是所有系统都支持的,所以“行”是由“ /n ”来分割的,其中“ /n ”属于前一“行”,而不属于后一“行”。
举例来说,字符串“ a/r/nbc/r/n ”共有三行,“ a/r/n ”为一行,“ bc/r/n ”为一行,最后还有一个“”空行。
“^ ”的匹配范围
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
*/
“^ ”的匹配范围
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
*/
“ ^ ”匹配结果分析
在不开启多行模式时,“ ^ ”只匹配字符串的开始位置,也就是位置 0 。
在开启了多行模式后,“ ^ ”匹配字符串开始位置和每个“ /n ”之后的行起始位置。
“ $ ”匹配结果分析
在不开启多行模式时,如果字符结尾是“ /n ”,那么“ $ ”会匹配结尾“ /n ”之前和结束两个位置。
在开启多行模式后,“ $ ”匹配每行“ /n ”之前的位置和字符串结束位置。
需要注意的是,在 .NET 中,无论是否开启多行模式,“ ^ ”和“ $ ”匹配的都只是一个位置,是零宽度的。其它语言中“ ^ ”和“ $ ”的意义可能会有所不同。
只有在正则表达式中涉及到多行的“ ^ ”和“ $ ”的匹配时,才使用 Multiline 模式。
典型应用一(参考 正则中加字符的问题 ):
需求描述:
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
*/
单行模式改变的是小数点“ . ”的匹配行为,使小数点可以匹配包含换行符“ /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>
-------------------
*/
Compiled 改变的是 .NET 中正则表达式的编译方式。启用了 Compiled 模式,会延长启动时间,占用更多的内存,会提高匹配速度。当然,对最终性能的影响,需要根据具体问题综合考虑的。这一模式也是被“滥”用最多的模式之一。
程序运行过程中,第一次遇到正则表达式,需要加载正则引擎,对正则表达式进行必要的语法检查,并做适当的优化,最后把它转换为适合正则引擎应用的形式。这种“解析”过程,对于复杂的正则表达式,频繁调用或是匹配较大的数据源时,对效率的影响较大。
这时可以在构建正则表达式时开启 Compiled 模式。这样做会将正则表达式直接编译为 MSIL 代码,在正则匹配过程中,可以由 JIT 优化为更快的本地机器代码,获得更高的匹配速度。但这种方式会降低正则的解析速度,占用更多的内存,而且它占用的内存在程序运行过程中会一直占用,无法释放。
什么场景下使用 Compiled 模式,需要根据实际情况具体问题具体分析,一般来说,以下场景不适合使用 Compiled 模式:
1. 对匹配效率没有要求的场景;
2. 非常简单的正则表达式;
3. 极少调用的方法中声明的正则表达式;
4. 循环体中声明的正则表达式(除了动态生成的正则表达式,否则不要在循环体内声明正则表达式);
5. 静态方法中声明的正则表达式(静态方法每次调用都需要重新编辑正则表达式,使用 Compiled 模式只会降低效率)。
RightToLeft 改变的是正则表达式匹配的顺序,从右到左进行匹配。目前只有 .NET 支持这一模式,但它对这一模式的支持并不是很完善,有时容易让人费解,所以除非对源字符串的构成很了解,而且又不得不使用的情况,否则不要轻易使用这一模式。
典型应用(参考 求一个好的算法 ):
一个由字母组成的字符串,最长 14 位,要求每隔 2 位加一个逗号,最左边不加,求一个好的算法
例: “abcdefg” 返回 “a,bc,de,fg”
代码实现:
string test = "abcdefg" ;
string result = Regex .Replace(yourStr, @"(?<!^)[a-zA-Z]{2}" , ",$0" , RegexOptions .RightToLeft);
这一模式指定不开启任何模式。在 .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;
}
这一模式改变的是普通捕获组的匹配行为。将普通捕获组解释为非捕获组,只有显式命名的命名捕获组才当作捕获组使用。
捕获组的作用是将括号 () 内子表达式匹配到的内容保存到内存中一个组里,供以后引用,在 .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> ”,而这样的字符串,通常是不存在的。
这一模式忽略正则表达式中的非转义空白字符,并启用“ # ”后面的注释,通常用于增强正则表达式的可读性或是用于教学目的。
举个例子基本上就会明白了
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" ;
}
其中的空白字符被忽略,“ # ”及该行后面的内容被解释为注释。
这一模式将按 ECMA 的 JavaScript 语义来解析正则表达式。通常影响的是以下元字符的匹配行为
/w 、 /W 、 /d 、 /D 、 /s 、 /S
使得以上元字符只能匹配 ASCII 码字符,而不再是匹配相应的 Unicode 字符。
事实上比如需求中明确要求只匹配英文字母,数字,下划线,而不包含汉字等字符,那么完全可以用“ [A-Za-z0-9_] ”,而不使用“ /w ”,虽然不够简洁,但可读性更好,语义更明确。
这一模式在 .NET 中的应用比较少,如不清楚什么场景下应该使用,可以忽略这一模式。
这一模式指定忽略语言中的区域性差异。一般与 IgnoreCase 模式一起使用,这一模式的应用场景很少,一般可以忽略,无需了解。
内联匹配模式在正则表达式内部使用,可以改变局部子表达式的匹配行为,内联匹配模式支持的模式较少,仅有 immsx 五种,但使用起来更简洁,更灵活。在 .NET 中支持 (?imnsx-imnsx:) 和 (?imnsx-imnsx) 两种形式。
各内联匹配模式对应的全局匹配模式见匹配模式列表。以下仅就 (?i) 忽略大小写模式进行讲解,其它模式类同。
语法: (?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>
*/
语法: (?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" ;
}
.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 |
指定忽略语言中的区域性差异。 很少使用,一般无需了解。 |