亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

.NET正則基礎(chǔ)之.NET正則匹配模式

 更新時間:2023年05月28日 14:14:39   作者:過客  
匹配模式指的是一些可以改變正則表達式匹配行為的選項或修飾符。不同的語言支持的匹配模式不同,使用的方式也不同,需要的朋友可以參考下

1、概述

匹配模式指的是一些可以改變正則表達式匹配行為的選項或修飾符。不同的語言支持的匹配模式不同,使用的方式也不同。

一般可分為全局和內(nèi)聯(lián)兩種。下面主要介紹.NET中的匹配模式,其它語言的匹配模式,后續(xù)視情況補充。

2、匹配模式

2.1全局匹配模式和內(nèi)聯(lián)匹配模式概述

.NET中的全局匹配模式是通過RegexOptions 枚舉值指定的,可以按位“或”進行組合,全局匹配模式只能作用于整個正則表達式。全局匹配模式提供的模式更多,可以靈活的動態(tài)指定匹配模式。

而內(nèi)聯(lián)匹配模式是通過在正則表達式中,使用(?imnsx-imnsx:)或(?imnsx-imnsx)的分組構(gòu)造來改變正則表達式的匹配行為的。內(nèi)聯(lián)匹配模式更靈活、簡潔,但是提供的模式較少。

下表摘自MSDN,部分說明做了修改。

RegexOption 成員

內(nèi)聯(lián)字符

說明

None

N/A

指定不設(shè)置任何選項。

IgnoreCase

i

指定不區(qū)分大小寫的匹配。

Multiline

m

指定多行模式。更改 ^ 和 $ 的含義,以使它們分別與任何行的開頭和結(jié)尾匹配,而不只是與整個字符串的開頭和結(jié)尾匹配。

ExplicitCapture

n

指定唯一有效的捕獲是顯式命名或編號的 (?<name>…) 形式的組。這允許圓括號充當非捕獲組,從而避免了由 (?:…) 導(dǎo)致的語法上的笨拙。

Compiled

N/A

指定正則表達式將被編譯為程序集。生成該正則表達式的 Microsoft 中間語言 (MSIL) 代碼;以較長的啟動時間為代價,得到更快的執(zhí)行速度。

Singleline

s

指定單行模式。更改句點字符 (.) 的含義,以使它與每個字符(而不是除 \n 之外的所有字符)匹配。

IgnorePatternWhitespace

x

指定從模式中排除非轉(zhuǎn)義空白并啟用數(shù)字符號 (#) 后面的注釋。請注意,空白永遠不會從字符類中消除。

RightToLeft

N/A

指定搜索是從右向左而不是從左向右進行的。具有此選項的正則表達式將移動到起始位置的左邊而不是右邊。

ECMAScript

N/A

指定已為表達式啟用了符合 ECMAScript 的行為。此選項僅可與 IgnoreCase 和 Multiline 標志一起使用。將 ECMAScript 同任何其他標志一起使用將導(dǎo)致異常。

CultureInvariant

N/A

指定忽略語言中的區(qū)域性差異。

2.2全局匹配模式

下面根據(jù)各種模式使用的頻率進行講解。

2.2.1 IgnoreCase 忽略大小寫

幾乎所有支持正則的語言中都提供了這一模式,是應(yīng)用最多的模式之一,同時也是被“濫”用最多的模式之一。

開啟忽略大小寫模式,則字符可以同時匹配大寫或小寫形式。比如在此模式下,正則表達式“<br>”可同時匹配“<br>”和“<BR>”

但并不是所有的字符都有大小寫形式,所以在書寫的正則中,如果不存在可區(qū)分大小寫形式的元字符或是字符序列時,開啟這一模式是沒有任何意義的。

比如替換一般的html標簽的正則表達式

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

因為<[^>]*>沒有哪一個元字符或是字符序列具有大小寫形式,所以這里的RegexOptions.IgnoreCase是多余的,用在這里雖然不會改變匹配結(jié)果,但是會降低匹配效率,同時這也不是一個好的習慣。

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

2.2.2  Multiline 多行模式

多行模式改變的是“^”和“$”的匹配行為,使“^”和“$”不僅可以匹配整個字符串的開始和結(jié)束位置,還可以匹配每行的開始和結(jié)束位置。

首先說明一下“行”的范圍。雖然我們在程序中習慣用“\r\n”來表示換行,但實際上“\r”和“\n”是不相關(guān)的兩個字符,一個表示回車,一個表示換行。由于歷史原因,“\r”并不是所有系統(tǒng)都支持的,所以“行”是由“\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 +=?"匹配內(nèi)容:"?+ m.Value +?"??匹配開始索引:"?+ m.Index +?"??匹配長度:"?+ m.Length +?"\n";
}
/*--------輸出--------
匹配內(nèi)容:??匹配開始索引:0??匹配長度:0
*/

“$”的匹配范圍

MatchCollection?mc =?Regex.Matches("a\r\nbc\r\n",?@"$");
foreach?(Match?m?in?mc)
{
?????richTextBox2.Text +=?"匹配內(nèi)容:"?+ m.Value +?"??匹配開始索引:"?+ m.Index +?"??匹配長度:"?+ m.Length +?"\n";
}
/*--------輸出--------
匹配內(nèi)容:??匹配開始索引:6??匹配長度:0
匹配內(nèi)容:??匹配開始索引:7??匹配長度:0
*/

注意:這里需要注意的是,在沒有開啟多行模式時,字符串結(jié)尾如果是“\n”,那么“$”是可以匹配兩個位置的,一個是“\n”前的位置,一個是字符串結(jié)束位置。字符串結(jié)尾如果不是“\n”,那么“$”就只匹配字符串結(jié)束位置。

MatchCollection?mc =?Regex.Matches("a\r\nbc\r",?@"$");
foreach?(Match?m?in?mc)
{
?????richTextBox2.Text +=?"匹配內(nèi)容:"?+ m.Value +?"??匹配開始索引:"?+ m.Index +?"??匹配長度:"?+ m.Length +?"\n";
}
/*--------輸出--------
匹配內(nèi)容:??匹配開始索引:6??匹配長度:0
*/

2.2.2.2  在開啟了多行模式后,“^”和“$”匹配范圍

“^”的匹配范圍

MatchCollection?mc =?Regex.Matches("a\r\nbc\r\n",?@"^",?RegexOptions.Multiline);
foreach?(Match?m?in?mc)
{
?????richTextBox2.Text +=?"匹配內(nèi)容:"?+ m.Value +?"??匹配開始索引:"?+ m.Index +?"??匹配長度:"?+ m.Length +?"\n";
}
/*--------輸出--------
匹配內(nèi)容:??匹配開始索引:0??匹配長度:0
匹配內(nèi)容:??匹配開始索引:3??匹配長度:0
匹配內(nèi)容:??匹配開始索引:7??匹配長度:0
*/

“$”的匹配范圍

MatchCollection?mc =?Regex.Matches("a\r\nbc\r\n",?@"$",?RegexOptions.Multiline);
foreach?(Match?m?in?mc)
{
?????richTextBox2.Text +=?"匹配內(nèi)容:"?+ m.Value +?"??匹配開始索引:"?+ m.Index +?"??匹配長度:"?+ m.Length +?"\n";
}
/*--------輸出--------
匹配內(nèi)容:??匹配開始索引:2??匹配長度:0
匹配內(nèi)容:??匹配開始索引:6??匹配長度:0
匹配內(nèi)容:??匹配開始索引:7??匹配長度:0
*/

2.2.2.3  匹配結(jié)果分析

“^”匹配結(jié)果分析

在不開啟多行模式時,“^”只匹配字符串的開始位置,也就是位置0。

在開啟了多行模式后,“^”匹配字符串開始位置和每個“\n”之后的行起始位置。

“$”匹配結(jié)果分析

在不開啟多行模式時,如果字符結(jié)尾是“\n”,那么“$”會匹配結(jié)尾“\n”之前和結(jié)束兩個位置。

在開啟多行模式后,“$”匹配每行“\n”之前的位置和字符串結(jié)束位置。

需要注意的是,在.NET中,無論是否開啟多行模式,“^”和“$”匹配的都只是一個位置,是零寬度的。其它語言中“^”和“$”的意義可能會有所不同。

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

2.2.2.4  應(yīng)用舉例

典型應(yīng)用一(參考 正則中加字符的問題):

需求描述:

fffffffffff

fffffffffff

dfdfdfdf

erererere

ferewfdfds

每行后面加一個“ttt”,即為

fffffffffffttt

fffffffffffttt

dfdfdfdfttt

ererererettt

ferewfdfdsttt

代碼實現(xiàn):

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

典型應(yīng)用二

需求描述:

源字符串

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,!,",#,$,%,&,…,(,)*,+,逗號,-,.,/, <,=,>,?,@,[,],^,_->表示范圍

要求分別匹配出條碼類別和表示范圍

代碼實現(xiàn):

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 單行模式

單行模式改變的是小數(shù)點“.”的匹配行為,使小數(shù)點可以匹配包含換行符“\n”在內(nèi)的任意一個字符。

這是一個很不幸的命名,總讓人誤會它與Multiline多行模式是有關(guān)聯(lián)的,而事實上它改變的是小數(shù)點的匹配行為,與Multiline多行模式?jīng)]有任何關(guān)聯(lián),由于歷史原因,這一不幸的命名被保留了下來。使用時需要注意。

單行模式通常在匹配有換行的文本時使用,采用小數(shù)點+單行模式的方式匹配任意字符,在.NET中是效率最高的。參考 正則基礎(chǔ)之——小數(shù)點

典型應(yīng)用:

源字符串:

<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>標簽之間的內(nèi)容

代碼實現(xiàn):

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模式,會延長啟動時間,占用更多的內(nèi)存,會提高匹配速度。當然,對最終性能的影響,需要根據(jù)具體問題綜合考慮的。這一模式也是被“濫”用最多的模式之一。

程序運行過程中,第一次遇到正則表達式,需要加載正則引擎,對正則表達式進行必要的語法檢查,并做適當?shù)膬?yōu)化,最后把它轉(zhuǎn)換為適合正則引擎應(yīng)用的形式。這種“解析”過程,對于復(fù)雜的正則表達式,頻繁調(diào)用或是匹配較大的數(shù)據(jù)源時,對效率的影響較大。

這時可以在構(gòu)建正則表達式時開啟Compiled模式。這樣做會將正則表達式直接編譯為MSIL代碼,在正則匹配過程中,可以由JIT優(yōu)化為更快的本地機器代碼,獲得更高的匹配速度。但這種方式會降低正則的解析速度,占用更多的內(nèi)存,而且它占用的內(nèi)存在程序運行過程中會一直占用,無法釋放。

什么場景下使用Compiled模式,需要根據(jù)實際情況具體問題具體分析,一般來說,以下場景不適合使用Compiled模式:

1. 對匹配效率沒有要求的場景;

2. 非常簡單的正則表達式;

3. 極少調(diào)用的方法中聲明的正則表達式;

4. 循環(huán)體中聲明的正則表達式(除了動態(tài)生成的正則表達式,否則不要在循環(huán)體內(nèi)聲明正則表達式);

5. 靜態(tài)方法中聲明的正則表達式(靜態(tài)方法每次調(diào)用都需要重新編輯正則表達式,使用Compiled模式只會降低效率)。

2.2.5 RightToLeft 從右到左模式

RightToLeft改變的是正則表達式匹配的順序,從右到左進行匹配。目前只有.NET支持這一模式,但它對這一模式的支持并不是很完善,有時容易讓人費解,所以除非對源字符串的構(gòu)成很了解,而且又不得不使用的情況,否則不要輕易使用這一模式。

典型應(yīng)用(參考 求一個好的算法):

一個由字母組成的字符串,最長14位,要求每隔2位加一個逗號,最左邊不加,求一個好的算法

例:“abcdefg”    返回“a,bc,de,fg”

代碼實現(xiàn):

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

2.2.6 None

這一模式指定不開啟任何模式。在.NET中RegexOptions 枚舉值是按位“或”組合,None模式我目前只找到一種應(yīng)用場景,就是在動態(tài)生成正則表達式時,動態(tài)指定模式時使用。

///?<summary>
///?動態(tài)生成正則參數(shù)列表
///?</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

這一模式改變的是普通捕獲組的匹配行為。將普通捕獲組解釋為非捕獲組,只有顯式命名的命名捕獲組才當作捕獲組使用。

捕獲組的作用是將括號()內(nèi)子表達式匹配到的內(nèi)容保存到內(nèi)存中一個組里,供以后引用,在.NET中捕獲組有兩種形式

(Expression) 普通捕獲組

(?<name>Expression) 命名捕獲組

其它形式的(?...)都不是捕獲組。

但是(Expression)這種捕獲組語法規(guī)則也帶來一個副作用,在一些不得不使用()的場合,會默認為使用了捕獲組,將匹配到的內(nèi)容保存到內(nèi)存中,而有些情況下這些內(nèi)容并不需要關(guān)心的,浪費了系統(tǒng)資源,降低了匹配效率,所以才有了非捕獲組(?:Expression)的出現(xiàn),來抵消這一副作用。而非捕獲組帶來的另一個副作用的就是可讀性的降低。

ExplicitCapture模式是為了在不犧牲匹配效率的前提下,提高正則表達式的可讀性,一般在命名捕獲組和普通捕獲組混合出現(xiàn),而又不關(guān)心普通捕獲組的正則表達式中使用,如取鏈接和文字的正則表達式中

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,用戶的總技術(shù)分為:5988;截至2009-07-26日,用戶的總技術(shù)分排名為: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,用戶的總技術(shù)分為:5988;截至2009-07-26日,用戶的總技術(shù)分排名為: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
*/

一般來說,關(guān)心的只是整個正則表達式匹配的整體,啟用了ExplicitCapture模式后,“([01][0-9]|2[0-3])”和“(:[0-5][0-9])”將不會被解釋為捕獲組,匹配到的內(nèi)容也不會保存到內(nèi)存中。

開啟ExplicitCapture模式雖然可以提高正則表達式的可讀性,但ExplicitCapture這一模式本身容易被人忽略,所以這種模式應(yīng)用得也比較少。

一旦使用了ExplicitCapture模式,要注意的是,除非你清楚捕獲組的編號規(guī)則,否則盡量不要再使用\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";
}

以上匹配鏈接的代碼通常是得不到任何結(jié)果的,因為這里“\1”引用的內(nèi)容,不再是“(['""]?)”匹配到的內(nèi)容,而是“(?<url>[^'""\s>]+)”匹配到的內(nèi)容,等價于“(?<url>[^'""\s>]+)\k<url>”,而這樣的字符串,通常是不存在的。

2.2.8 IgnorePatternWhitespace

這一模式忽略正則表達式中的非轉(zhuǎn)義空白字符,并啟用“#”后面的注釋,通常用于增強正則表達式的可讀性或是用于教學目的。

舉個例子基本上就會明白了

string?test =?"(One) and ( Two (Three) Four).";
Regex?reg =?new?Regex(@"\(??????????????????????????#普通開括弧
??????????????????????????(?>???????????????????????#固化分組
?????????????????????????????\(???(?<OPEN>)?????????#遇到開括弧'OPEN'計數(shù)加1
????????????????????????????|???????????????????????#分支結(jié)構(gòu)
?????????????????????????????\)???(?<-OPEN>)????????#遇到閉括弧'OPEN'計數(shù)減1
????????????????????????????|???????????????????????#分支結(jié)構(gòu)
?????????????????????????????[^()]+?????????????????#非括弧的其它任意字符
??????????????????????????)*????????????????????????#以上子串出現(xiàn)0次或任意多次
??????????????????????????(?(OPEN)(?!))?????????????#判斷是否還有'OPEN',有則說明不配對,什么都不匹配
????????????????????????\)??????????????????????????#普通閉括弧
???????????????????????",?RegexOptions.IgnorePatternWhitespace);
MatchCollection?mc = reg.Matches(test);
foreach?(Match?m?in?mc)
{
??????richTextBox2.Text += m.Value +?"\n";
}

其中的空白字符被忽略,“#”及該行后面的內(nèi)容被解釋為注釋。

2.2.9 ECMAScript

這一模式將按ECMA的JavaScript語義來解析正則表達式。通常影響的是以下元字符的匹配行為

\w、\W、\d、\D、\s、\S

使得以上元字符只能匹配ASCII碼字符,而不再是匹配相應(yīng)的Unicode字符。

事實上比如需求中明確要求只匹配英文字母,數(shù)字,下劃線,而不包含漢字等字符,那么完全可以用“[A-Za-z0-9_]”,而不使用“\w”,雖然不夠簡潔,但可讀性更好,語義更明確。

這一模式在.NET中的應(yīng)用比較少,如不清楚什么場景下應(yīng)該使用,可以忽略這一模式。

2.2.10 CultureInvariant

這一模式指定忽略語言中的區(qū)域性差異。一般與IgnoreCase模式一起使用,這一模式的應(yīng)用場景很少,一般可以忽略,無需了解。

2.3 內(nèi)聯(lián)匹配模式

內(nèi)聯(lián)匹配模式在正則表達式內(nèi)部使用,可以改變局部子表達式的匹配行為,內(nèi)聯(lián)匹配模式支持的模式較少,僅有immsx五種,但使用起來更簡潔,更靈活。在.NET中支持(?imnsx-imnsx:)和(?imnsx-imnsx)兩種形式。

各內(nèi)聯(lián)匹配模式對應(yīng)的全局匹配模式見匹配模式列表。以下僅就(?i)忽略大小寫模式進行講解,其它模式類同。

2.3.1  (?imnsx-imnsx:)形式

語法:(?i:Expression)

這種語法規(guī)則表達為括號內(nèi)的子表達式開啟忽略大小寫模式。

舉例:^[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,?' ') +?"??匹配結(jié)果:?"?+ reg.IsMatch(s) +?"\n";
}
/*--------輸出--------
源字符串:?Abc??????????????匹配結(jié)果:?False
源字符串:?AbcdefGHIjklmn???匹配結(jié)果:?True
源字符串:?abcdefghijklmn???匹配結(jié)果:?False
*/

語法:(?-i:Expression)

這種語法規(guī)則表達為括號內(nèi)的子表達式關(guān)閉忽略大小寫模式。通常與全局匹配模式配合使用,表示全局為忽略大小寫的,局部為嚴格區(qū)分大小寫。

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

以上正則表示,div標簽中,僅匹配id為全大寫的“TEST”的標簽內(nèi)容,其余標簽不匹配。

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)為所在位置右側(cè)的子表達式開啟忽略大小寫模式,直到出現(xiàn)(?-i)或者到表達式結(jié)束為止;(?-i)為所在位置右側(cè)的子表達式關(guān)閉忽略大小寫模式,直到出現(xiàn)(?i)或者到表達式結(jié)束為止。

通常在正則表達式開始位置使用(?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、小結(jié)

.NET中的正則匹配模式基本上已講解完了,最后再來總結(jié)一下各匹配模式的應(yīng)用場景吧。

RegexOption 成員

內(nèi)聯(lián)字符

作用/應(yīng)用場景

None

N/A

指定不設(shè)置任何選項。

一般在動態(tài)指定匹配模式時使用。

IgnoreCase

i

指定不區(qū)分大小寫的匹配。

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

Multiline

m

指定多行模式。更改 ^ 和 $ 的含義,以使它們分別與任何行的開頭和結(jié)尾匹配,而不只是與整個字符串的開頭和結(jié)尾匹配。

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

ExplicitCapture

n

指定唯一有效的捕獲是顯式命名或編號的 (?<name>…) 形式的組。這允許圓括號充當非捕獲組,從而避免了由 (?:…) 導(dǎo)致的語法上的笨拙。

ExplicitCapture模式是為了在不犧牲匹配效率的前提下,提高正則表達式的可讀性,一般在命名捕獲組和普通捕獲組混合出現(xiàn),而又不關(guān)心普通捕獲組的正則表達式中使用。

Compiled

N/A

指定正則表達式將被編譯為程序集。生成該正則表達式的 Microsoft 中間語言 (MSIL) 代碼;以較長的啟動時間為代價,得到更快的執(zhí)行速度。

以下場景不適合使用:

1.    對匹配效率沒有要求的場景;

2.    非常簡單的正則表達式;

3.    極少調(diào)用的方法中聲明的正則表達式;

4.    循環(huán)體中聲明的正則表達式(除了動態(tài)生成的正則表達式,否則不要在循環(huán)體內(nèi)聲明正則表達式);

5.    靜態(tài)方法中聲明的正則表達式(靜態(tài)方法每次調(diào)用都需要重新編輯正則表達式,使用Compiled模式只會降低效率)。

Singleline

s

指定單行模式。更改句點字符 (.) 的含義,以使它與每個字符(而不是除 \n 之外的所有字符)匹配。

單行模式通常在匹配有換行的文本時使用,采用小數(shù)點+單行模式的方式匹配任意字符,在.NET中是效率最高的。

IgnorePatternWhitespace

x

指定從模式中排除非轉(zhuǎn)義空白并啟用數(shù)字符號 (#) 后面的注釋。請注意,空白永遠不會從字符類中消除。

為了提高可讀性,或是為正則表達式加注釋時使用。

RightToLeft

N/A

指定搜索是從右向左而不是從左向右進行的。具有此選項的正則表達式將移動到起始位置的左邊而不是右邊。

除非對源字符串的構(gòu)成很了解,而且又不得不使用的情況,否則不要輕易使用這一模式。

ECMAScript

N/A

指定已為表達式啟用了符合 ECMAScript 的行為。此選項僅可與 IgnoreCase 和 Multiline 標志一起使用。將 ECMAScript 同任何其他標志一起使用將導(dǎo)致異常。

除非對這一模式應(yīng)用場景很了解,否則不要使用。

CultureInvariant

N/A

指定忽略語言中的區(qū)域性差異。

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

到此這篇關(guān)于.NET正則基礎(chǔ)之.NET正則匹配模式的文章就介紹到這了,更多相關(guān).NET正則匹配模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論