日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】正则基础之——捕获组(capture group)

發布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】正则基础之——捕获组(capture group) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

源地址?

1?????? ?概述

1.1???? 什么是捕獲組

捕獲組就是把正則表達式中子表達式匹配的內容,保存到內存中以數字編號或顯式命名的組里,方便后面引用。當然,這種引用既可以是在正則表達式內部,也可以是在正則表達式外部。

捕獲組有兩種形式,一種是普通捕獲組,另一種是命名捕獲組,通常所說的捕獲組指的是普通捕獲組。語法如下:

普通捕獲組:(Expression)

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

普通捕獲組在大多數支持正則表達式的語言或工具中都是支持的,而命名捕獲組目前只有.NETPHPPython等部分語言支持,據說Java會在7.0中提供對這一特性的支持。上面給出的命名捕獲組的語法是.NET中的語法,另外在.NET中使用(?’name’Expression)與使用(?<name>Expression)是等價的。在PHPPython中命名捕獲組語法為:(?P<name>Expression)

另外需要說明的一點是,除(Expression)(?<name>Expression)語法外,其它的(?...)語法都不是捕獲組。

1.2???? 捕獲組編號規則

編號規則指的是以數字為捕獲組進行編號的規則,在普通捕獲組或命名捕獲組單獨出現的正則表達式中,編號規則比較清晰,在普通捕獲組與命名捕獲組混合出現的正則表達式中,捕獲組的編號規則稍顯復雜。

在展開討論之前,需要說明的是,編號為0的捕獲組,指的是正則表達式整體,這一規則在支持捕獲組的語言中,基本上都是適用的。下面對其它編號規則逐一展開討論。

1.2.1? 普通捕獲組編號規則

如果沒有顯式為捕獲組命名,即沒有使用命名捕獲組,那么需要按數字順序來訪問所有捕獲組。在只有普通捕獲組的情況下,捕獲組的編號是按照“(”出現的順序,從左到右,從1開始進行編號的

正則表達式:(\d{4})-(\d{2}-(\d\d))

??

上面的正則表達式可以用來匹配格式為yyyy-MM-dd的日期,為了在下表中得以區分,月和日分別采用了\d{2}\d\d這兩種寫法。

用以上正則表達式匹配字符串:2008-12-31,匹配結果為:

編號

命名

捕獲組

匹配內容

0

?

(\d{4})-(\d{2}-(\d\d))

2008-12-31

1

?

(\d{4})

2008

2

?

(\d{2}-(\d\d))

12-31

3

?

(\d\d)

31

1.2.2? 命名捕獲組編號規則

命名捕獲組通過顯式命名,可以通過組名方便的訪問到指定的組,而不需要去一個個的數編號,同時避免了在正則表達式擴展過程中,捕獲組的增加或減少對引用結果導致的不可控。

不過容易忽略的是,命名捕獲組也參與了編號的,在只有命名捕獲組的情況下,捕獲組的編號也是按照“(”出現的順序,從左到右,從1開始進行編號的

正則表達式:(?<year>\d{4})-(?<date>\d{2}-(?<day>\d\d))

?

?

用以上正則表達式匹配字符串:2008-12-31

匹配結果為:

編號

命名

捕獲組

匹配內容

0

?

(?<year>\d{4})-(?<date>\d{2}-(?<day>\d\d))

2008-12-31

1

year

(?<year>\d{4})

2008

2

date

(?<date>\d{2}-(?<day>\d\d))

12-31

3

day

(?<day>\d\d)

31

1.2.3? 普通捕獲組與命名捕獲組混合編號規則

當一個正則表達式中,普通捕獲組與命名捕獲組混合出現時,捕獲組的編號規則稍顯復雜。對于其中的命名捕獲組,隨時都可以通過組名進行訪問,而對于普通捕獲組,則只能通過確定其編號后進行訪問。

混合方式的捕獲組編號,首先按照普通捕獲組中“(”出現的先后順序,從左到右,從1開始進行編號,當普通捕獲組編號完成后,再按命名捕獲組中“(”出現的先后順序,從左到右,接著普通捕獲組的編號值繼續進行編號。

也就是先忽略命名捕獲組,對普通捕獲組進行編號,當普通捕獲組完成編號后,再對命名捕獲組進行編號。

正則表達式:(\d{4})-(?<date>\d{2}-(\d\d))

?

?

用以上正則表達式匹配字符串:2008-12-31,匹配結果為:

編號

命名

捕獲組

匹配內容

0

?

(\d{4})-(?<date>\d{2}-(\d\d))

2008-12-31

1

?

(\d{4})

2008

3

date

(?<date>\d{2}-(\d\d))

12-31

2

?

(\d\d)

31

2?????? 捕獲組的引用

對捕獲組的引用一般有以下幾種:

1)?????? 正則表達式中,對前面捕獲組捕獲的內容進行引用,稱為反向引用;

2)?????? 正則表達式中,(?(name)yes|no)的條件判斷結構;

3)?????? 在程序中,對捕獲組捕獲內容的引用。

2.1???? 反向引用

捕獲組捕獲到的內容,不僅可以在正則表達式外部通過程序進行引用,也可以在正則表達式內部進行引用,這種引用方式就是反向引用。

反向引用的作用通常是用來查找或限定重復,限定指定標識配對出現等等。

對于普通捕獲組和命名捕獲組的引用,語法如下:

普通捕獲組反向引用:\k<number>,通常簡寫為\number

命名捕獲組反向引用:\k<name>或者\k'name'

普通捕獲組反向引用中number是十進制的數字,即捕獲組的編號;命名捕獲組反向引用中的name為命名捕獲組的組名。

反向引用涉及到的內容比較多,后續單獨說明。

2.2???? 條件判斷表達式

條件判斷結構在平衡組中談到過,基本應用和擴展應用都可以在其中找到例子,這里不再贅述,請參考.NET正則基礎之——平衡組

2.3???? 程序中引用

根據語言的不同,程序中對捕獲組引用的方式也有所不同,下面就JavaScript.NET進行舉例說明。

2.3.1? JavaScript中的引用

由于JavaScript中不支持命名捕獲組,所以對于捕獲組的引用就只支持普通捕獲組的反向引用和$number方式的引用。程序中的引用一般在替換和匹配時使用。

注:以下應用舉例僅考慮簡單應用場景,對于<a href="javascript:document.write('<b>hello</b>')"/>這種復雜場景暫不考慮。

1)???????? Replace中引用,通常是通過$number方式引用。

舉例:替換掉html標簽中的屬性。

<textareaid="result"rows="10"cols="100"></textarea>
<scripttype="text/javascript">
var data = "<table id=\"test\"><tr class=\"light\"><td> test </td></tr></table>";
var reg = /<([a-z]+)[^>]*>/ig;
document.getElementById("result").value = data.replace(reg, "<$1>");
</script>
//輸出
<table><tr><td> test </td></tr></table>
2)???????? 在匹配時的引用,通常通過RegExp.$number方式引用。

舉例:同時獲取<img…>中的srcname屬性值,屬性的順序不固定。參考一條正則能不能同時取出一個img標記的srcname?

?<textarea id="result" rows="10" cols="100"></textarea> <script type="text/javascript"> var data = [' <img alt="" border="0" name="g6-o44-1" οnlοad="DrawImage" src="/bmp/foo1.jpg" />', ' <img src="/bmp/foo2.jpg" alt="" border="0" name="g6-o44-2" οnlοad="DrawImage" />'] ; var reg = /<img\b(?=(?:(?!name=).)*name=(['"]?)([^'"\s>]+)\1)(?:(?!src=).)*src=(['"]?)([^'"\s>]+)\3[^>]*>/i; for(var i=0;i<data.length;i++) { var s = data[i]; document.getElementById("result").value += "源字符串:" + s + "\n"; document.write("<br />"); if(reg.test(s)) { document.getElementById("result").value += "name: " + RegExp.$2 + "\n"; document.getElementById("result").value += "src: " + RegExp.$4 + "\n"; } } </script>

?

?

2.3.2? .NET中的引用

由于.NET支持命名捕獲組,所以在.NET中的引用方式會多一些。通常也是在兩種場景下應用,一是替換,一是匹配。

1)???????? 替換中的引用

普通捕獲組:$number

命名捕獲組:${name}

替換中應用,仍是上面的例子。

舉例:替換掉html標簽中的屬性。使用普通捕獲組。

?

string data ="<table id=\"test\"><tr class=\"light\"><td> test
</td></tr></table>";
richTextBox2.Text
= Regex.Replace(data, @"(?i)<([a-z]+)[^>]*>", "<$1>");
//輸出
<table><tr><td> test </td></tr></table> 使用命名捕獲組。

?

string data ="<table id=\"test\"><tr class=\"light\"><td> test
</td></tr></table>";
richTextBox2.Text
= Regex.Replace(data, @"(?i)<(?<tag>[a-z]+)[^>]*>", "<${tag}>");
//輸出
<table><tr><td> test </td></tr></table>


2)???????? 匹配后的引用

對于匹配結果中捕獲組捕獲內容的引用,可以通過GroupsResult對象進行引用。

?

string test = "<a href=\"http://www.csdn.net\">CSDN</a>";
Regex reg = new Regex(@"(?is)<a(?:(?!href=).)*href=(['""]?)(?<url>[^""'\s>]*)\1[^>]*>(?<text>(?:(?!</a>).)*)</a>");
MatchCollection mc = reg.Matches(test);
foreach (Match m in mc)
{
richTextBox2.Text += "m.Value?".PadRight(25) + m.Value + "\n";
richTextBox2.Text += "m.Result(\"$0\") : ".PadRight(25) + m.Result("$0") + "\n";
richTextBox2.Text += "m.Groups[0].Value : ".PadRight(25) +m.Groups[0].Value + "\n";
richTextBox2.Text += "m.Result(\"$2\") : ".PadRight(25) + m.Result("$2") + "\n";
richTextBox2.Text += "m.Groups[2].Value : ".PadRight(25) + m.Groups[2].Value + "\n";
richTextBox2.Text += "m.Result(\"${url}\") : ".PadRight(25) + m.Result("${url}") + "\n";
richTextBox2.Text += "m.Groups[\"url\"].Value : ".PadRight(25) + m.Groups["url"].Value + "\n";
richTextBox2.Text += "m.Result(\"$3\") : ".PadRight(25) + m.Result("$3") + "\n";
richTextBox2.Text += "m.Groups[3].Value : ".PadRight(25) + m.Groups[3].Value + "\n";
richTextBox2.Text += "m.Result(\"${text}\") : ".PadRight(25) + m.Result("${text}") + "\n";
richTextBox2.Text += "m.Groups[\"text\"].Value : ".PadRight(25) + m.Groups["text"].Value + "\n";
}
//輸出

m.Value : <a href="http://www.csdn.net">CSDN</a>
m.Result("$0")?:?<a href="http://www.csdn.net">CSDN</a>
m.Groups[0].Value?:?<a href="http://www.csdn.net">CSDN</a>
m.Result("$2")?:?http://www.csdn.net
m.Groups[2].Value?:?http://www.csdn.net
m.Result("${url}")?:?http://www.csdn.net
m.Groups["url"].Value?:?http://www.csdn.net
m.Result("$3")?:?CSDN
m.Groups[3].Value?:?CSDN
m.Result("${text}")?:?CSDN
m.Groups["text"].Value?:?CSDN



對于捕獲組0的引用,可以簡寫作m.Value

?

轉載于:https://www.cnblogs.com/pmars/archive/2011/12/30/2307507.html

總結

以上是生活随笔為你收集整理的【转】正则基础之——捕获组(capture group)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。