c 正則表代式的分組和匹配模式

2021-04-16 21:28:57 字數 4651 閱讀 4626

一、組的分類

正則中的組有捕獲組和非捕獲組,而捕獲組又分為普通的捕獲組和命名捕獲組,分別為

捕獲組:(exp)   

命名捕獲組:(? exp)   

非捕獲組:(?:exp) 

二、組的作用

1、捕獲組的作用

捕獲組的作用是將正規表示式exp匹配到的內容儲存到組裡,供以後使用

比如這樣乙個字串:

csdn

我想得到**,而它符合的規則是在 標籤內,那就可以這樣做

c# code

string

test ="

csdn

";match m

=regex.match(test,

@"]*>

", regexoptions.ignorecase);

if(m.success)

messagebox.show(m.groups[

1].value);

上面的正規表示式匹配到了 ,而我們想得到**,表示式其它部分只是為了保證取到的**是在 標籤內的,所以這裡用到的捕獲組,把匹配到的**儲存到捕獲組裡,然後用m.groups[1].value得到這個捕獲組所匹配到的內容

m.groups[1].value是一種對捕獲的引用方式,還有另外一種引用方式m.result("$1"),效果是一樣的

普通捕獲組是用1,2,3...這樣的自然數對捕獲組進行引用的

而命名捕獲組可以不用去數捕獲組的序號,直接通過捕獲組的命稱對它進行引用

c# code

string

test ="

csdn

";match m

=regex.match(test,

@"[^""]*)""[^>]*>

", regexoptions.ignorecase);

if(m.success)

messagebox.show(m.groups[

"url

"].value);

至於捕獲組的分組命名及序號排序規則,在後面說明

2、非捕獲組的作用

非捕獲組的作用有兩個,第乙個比較常用,第二個了解一下即可

(1)、節省系統資源,提高效率

在使用「 ¦」表示「或」的關係時,稍微複雜的情況,需要用()來限制「 ¦」的作用範圍,否則即表示「 ¦」的左右兩側整體為「或」的關係,這是題外話,這裡不詳細說明了,還有用來表示式匹配次數時,有時前面也要用到()限制作用範圍

而使用()來限制作用範圍的同時,預設情況下會把匹配到的結果儲存到乙個捕獲組裡,而大多數時候,我們是不需要儲存這部分內容的,這就帶來一定的***,浪費了系統資源,降低了效率

非捕獲組的乙個作用就是用來消除這種***的,(?:exp)用來匹配exp所表示的規則,但不將匹配結果儲存到捕獲組裡

比如匹配hh:mm:ss這樣的時間

c# code

messagebox.show(regex.i**atch(

"18:23:55",

"^(?:[01][0-9]|2[0-3])(?::[0-5][0-9])$

").tostring());

(?:[01][0-9] ¦2[0-3])驗證小時部分是否符合規則,但不會將匹配結果儲存到捕獲組裡

(?::[0-5][0-9])驗證了分秒部分,但不會將匹配結果儲存到捕獲組裡

(2)、在使用regex.split方法時,起到與regexoptions .explicitcapture引數相同的作用,這個用得不多,了解一下就行了

三、捕獲組分組命名及序號排序

普通捕獲組是按「(」從左到右出現的先後順序以自然數1,2,3...進行命名的

命名捕獲組就是以(? exp)中的name進行命名的

但是要注意一點,在表示式匹配成功的前提下,$0在任何情況下都表示整個表示式所匹配到的內容,m.groups[0].value表示整個表示式匹配到的內容,可以簡寫為m.value

另外就是命名捕獲組除了可以用name對它進行引用外,還可以通過序號對它引用,它的命名規則為:先對普通捕獲組從左到右進行序號命名,然後再從開頭,從左到右對命名捕獲組進行序號命名,舉例如下

[^"]*)"/s*title="([^"]*)"[^> ]*> (? [/s/s]*?)

2   url                  1               3    text

c# code

string

test ="

csdn

";match m

=regex.match(test,

@"[^""]*)""/s*title=""([^""]*)""[^>]*>(?[/s/s]*?)

", regexoptions.ignorecase);

if(m.success)

四、組的另一種引用方式

除了上面 m.groups[1].value 和 m.result("$1") 這兩種對結果集進行處理時的引用方式外,還有在替換時的一種引用方式,舉例如下

c# code

string

test ="

csdn

";string

result

=regex.replace(test,

@"]*>(?[/s/s]*?)

", @"

$ "

, regexoptions.ignorecase);

messagebox.show(result);

普通捕獲組就是用$number來引用,而命名捕獲是用$來引用 

c# code

string

test ="

matchcollection mc

=regex.matches(test,

@"]*>

", regexoptions .ignorecase);

foreach

(match m

inmc)

輸出結果為:

這時再看一下 ]*> 這個正規表示式

(?!img)所在的「縫隙」是「

同理, ]*> 表示只匹配 標籤

c# code

string

test ="

matchcollection mc

=regex.matches(test,

@"]*>

", regexoptions.ignorecase);

foreach

(match m

inmc)

輸出:

(? <= ]*> ) ]*> 表示只匹配前面為 標籤的 標籤

c# code

string

test ="

matchcollection mc

=regex.matches(test,

@"(?<=]*>)]*>

", regexoptions.ignorecase);

foreach

(match m

inmc)

輸出:

(? ]*> ) ]*> 表示只匹配前面不為 標籤的 標籤 

c# code

string

test ="

matchcollection mc

=regex.matches(test,

@"(?]*>)]*>

", regexoptions.ignorecase);

foreach

(match m

inmc)

輸出:

以上面的這個(? <= ]*> ) ]*> 為例,表示式中雖然有(? <= ]*> ),但是在結果m.value中並不存在它匹配到的內容 ,所以說它是零寬度的,只是作為乙個附加條件存在 

C 泛型分組和Linq分組的異同

沒什麼好說的,因為用的到,所以作個記錄,如下 using system using system.collections.generic using system.linq using system.text using system.threading.tasks namespace consol...

10 匹配數字和字母表的字母

說明 使用連字元 匹配一系列字元並不只限於字母,它也可以匹配一系列數字。例如,0 5 匹配0和5之間的所有數字,包括0和5。此外,可以將單個字符集中的一系列字母和數字進行組合。var jennystr jenny8675309 var myregex a z0 9 ig 匹配jennystr中的所有...

正規表示式的分組和反向引用

一 分組 所謂分組就是為了實現多個字元繫結在一起而加括號把這一組字元限定為乙個整體。比如我們要表達0個或者多個a那麼可以直接a 而如果表達0ge或者多個ab那麼就用括號把ab括起來 ab 這個時候ab就是乙個分組。分組常用的的語法有 exp 匹配exp,並且捕獲文字到自動命名的組裡。這裡這個自動命名...