欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET正則基礎(chǔ)之正則委托

 更新時(shí)間:2023年05月28日 13:35:12   作者:過(guò)客  
一般的正則替換,只能對(duì)匹配的子串做簡(jiǎn)單的處理,.NET的Replace()方法中的replacement參數(shù),不僅可以是字符串,還可以是委托(delegate),在每次匹配成功時(shí),都會(huì)調(diào)用委托方法,對(duì)匹配的子串進(jìn)行處理之后,再作為替換文本返回

1、概述

一般的正則替換,只能對(duì)匹配的子串做簡(jiǎn)單的處理,且只能是做string類(lèi)型的處理之后,作為替換文本替換匹配子串,可以實(shí)現(xiàn)的功能比較有限。.NET的Replace()方法中的replacement參數(shù),不僅可以是字符串,還可以是委托(delegate),在每次匹配成功時(shí),都會(huì)調(diào)用委托方法,對(duì)匹配的子串進(jìn)行處理之后,再作為替換文本返回,匹配子串使用委托方法,可以做任意復(fù)雜的處理,因此這種替換功能非常強(qiáng)大。

委托的類(lèi)型可以是MatchEvaluator,也可以是匿名方法,在每次匹配成功時(shí)調(diào)用。委托方法傳入?yún)?shù)是Match對(duì)象,返回類(lèi)型是string,即正則表達(dá)式在每次匹配成功時(shí),會(huì)得到一個(gè)Match對(duì)象,作為參數(shù)傳給委托方法,做一定處理后,返回替換文本,替換匹配到的子串。

2、委托和匿名方法

在正則替換中使用的委托,一般有兩種方式,顯式聲明的委托和匿名方法。下面以實(shí)例說(shuō)明兩種方式的使用方法。委托和匿名方法的區(qū)別和各自的特點(diǎn)不在這里介紹,請(qǐng)參考相關(guān)文獻(xiàn)或文章。

2.1委托

舉例:

源字符串: a=10, b=20, c=30

需求:將字符串中的數(shù)字加100。

//委托方法
private string regReplace(Match m)
{
     return (Convert.ToInt32(m.Value) + 100).ToString();
}
//聲明一個(gè)MatchEvaluator類(lèi)型委托
MatchEvaluator me = new MatchEvaluator(regReplace);
//正則替換應(yīng)用
string test = "a=10, b=20, c=30";
Regex reg = new Regex(@"(?i)(?<=[a-z]=)\d+");
string result = reg.Replace(test, me);
richTextBox2.Text = result;
/*--------輸出--------
a=110, b=120, c=130
*/

2.2匿名方法

事實(shí)上,對(duì)于以上這種簡(jiǎn)單的需求,不需要顯式的聲明委托,直接使用匿名方法即可,

string test = "a=10, b=20, c=30";
Regex reg = new Regex(@"(?i)(?<=[a-z]=)\d+");
string result = reg.Replace(test, delegate(Match m) { return (Convert.ToInt32(m.Value) + 100).ToString(); });
richTextBox2.Text = result;
/*--------輸出--------
a=110, b=120, c=130
*/

3、正則中委托的典型應(yīng)用場(chǎng)景

一個(gè)涉及到替換的需求,首先要進(jìn)行分析,是否能夠通過(guò)一個(gè)正則表達(dá)式進(jìn)行直接替換,如果不可以,那就要借助委托了。接下來(lái)就要找出可在委托方法中進(jìn)行處理的子串的規(guī)律,剩下的就是委托方法中最基本的字符串處理了。

正則中委托的典型應(yīng)用場(chǎng)景一般可歸納為以下幾種:

1、替換子串需進(jìn)行非string類(lèi)型的處理,如計(jì)算等;

2、替換子串需經(jīng)過(guò)條件或邏輯判斷來(lái)決定處理方式;

3、多種條件組合的替換。

以上分類(lèi)方式或許有重疊的地方,但是都比較有代表性,所以單獨(dú)進(jìn)行舉例說(shuō)明。

3.1非string類(lèi)型處理

替換子串非string類(lèi)型處理,最典型的就是以上舉例中的計(jì)算。還有比較典型的就是涉及計(jì)數(shù)的問(wèn)題。

舉例:

源字符串:<a href="http://www.sina.com.cn/">新浪 </a> <a href="http://www.sohu.com/">搜狐 </a> <a href="http://www.qq.com/">騰訊QQ </a> <a href="http://www.163.com/">網(wǎng)易163 </a>

需求:在每個(gè)鏈接后面加編號(hào),結(jié)果

<a href="http://www.sina.com.cn/">新浪 </a>01 <a href="http://www.sohu.com/">搜狐 </a>02 <a href="http://www.qq.com/">騰訊QQ </a>03 <a href="http://www.163.com/">網(wǎng)易163 </a>04

代碼實(shí)現(xiàn):

string test = "<a href=\"http://www.sina.com.cn/\">新浪</a><a href=\"http://www.sohu.com/\">搜狐</a><a href=\"http://www.qq.com/\">騰訊QQ</a><a href=\"http://www.163.com/\">網(wǎng)易163</a>";
Regex reg = new Regex(@"(?is)<a[^>]*>(?:(?!</?a\b).)*</a>");
int i = 1;
string result = reg.Replace(test, delegate(Match m) { return m.Value + (i++).ToString("00"); });
richTextBox2.Text = result;
/*--------輸出--------
<a  rel="external nofollow" >新浪</a>01<a  rel="external nofollow" >搜狐</a>02<a  rel="external nofollow" >騰訊QQ</a>03<a  rel="external nofollow" >網(wǎng)易163</a>04
*/

這個(gè)需求是在鏈接后加編號(hào),只要匹配到<a…>…</a>標(biāo)簽,在后面加上編號(hào)即可,但是由于編號(hào)是要根據(jù)a標(biāo)簽的個(gè)數(shù)來(lái)計(jì)數(shù)的,所以是動(dòng)態(tài)變化的,這樣直接替換就做不到了。而正則中的委托,是每次匹配成功后都會(huì)調(diào)用委托方法,而匹配是從左向右按順序匹配的,所以調(diào)用委托方法也是按匹配的先后順序進(jìn)行調(diào)用的,這樣就可以先用正則匹配出a標(biāo)簽,然后在委托方法中動(dòng)態(tài)進(jìn)行計(jì)數(shù)了。

3.2邏輯判斷

如果待替換的子串,需要根據(jù)當(dāng)前匹配子串的內(nèi)容,經(jīng)過(guò)判斷后決定如何替換,一般無(wú)法直接通過(guò)replace()實(shí)現(xiàn),需求在委托方法里進(jìn)行判斷。

舉例1:

源字符串:源字符串規(guī)律為“字母=數(shù)字”,用“&”相連

a=12&b=34&c=56&d=78

a=98&b=76&d=54

需求:如果源字符串有“c=數(shù)字”,就替換為“c=12”,否則在字符串結(jié)尾添加“&c=98”。

代碼實(shí)現(xiàn):

string[] test = new string[]{"a=12&b=34&c=56&d=78", "a=98&b=76&d=54"};
Regex reg = new Regex(@"(?is)(?<=^(?:(?!c=).)*)(?(c=[^&]+)c=[^&]+|$)");
foreach(string s in test)
{
      richTextBox2.Text += "字符串: " + s + "\n";
      richTextBox2.Text += "替換后: " + reg.Replace(s, delegate(Match m) { return m.Value == "" ? "&c=98" : "c=12"; }) + "\n\n";
}
/*--------輸出--------
字符串: a=12&b=34&c=56&d=78
替換后: a=12&b=34&c=12&d=78
字符串: a=98&b=76&d=54
替換后: a=98&b=76&d=54&c=98
*/

還有一個(gè)類(lèi)似的需求實(shí)例。

舉例2(一個(gè)可能很簡(jiǎn)單的正式表達(dá)式求助):

源字符串:要處理的字符有可能是

""(空)

"p=1"

"ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a"

"ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a&p=2"

"ID=e2798a59&xx=79d5&p=4&bb=4833-9c57&cc=87d46a8&bb=b907a"

需求:對(duì)上述任何一種字符串的可能,查找是否有p=x,如果找不到,為字符串加上"p=0" ,如果找到,還要得到x的值,讓y=x+1之后,再把"p=y"替換之前的p=x。

代碼實(shí)現(xiàn):

string[] test = new string[] { "", "p=1", "ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a", "ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a&p=2", "ID=e2798a59&xx=79d5&p=4&bb=4833-9c57&cc=87d46a8&bb=b907a" };
foreach (string s in test)
{
     richTextBox2.Text += "原始字符串: \t" + s + "\n";
     richTextBox2.Text += "替換后字符串: \t" + Regex.Replace(s, @"(?is)p=(?<v>\d+)|(?<!p=\d+.*)$", delegate(Match m) { if (m.Groups["v"].Value != "") return "p=" + (Convert.ToInt32(m.Groups["v"].Value) + 1); return "p=0"; }) + "\n\n";
}
/*--------輸出--------
原始字符串:   
替換后字符串: p=0
原始字符串:    p=1
替換后字符串: p=2
原始字符串:    ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a
替換后字符串: ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907ap=0
原始字符串:    ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a&p=2
替換后字符串: ID=e2798a59&xx=79d5&bb=4833-9c57&cc=87d46a8&bb=b907a&p=3
原始字符串:    ID=e2798a59&xx=79d5&p=4&bb=4833-9c57&cc=87d46a8&bb=b907a
替換后字符串: ID=e2798a59&xx=79d5&p=5&bb=4833-9c57&cc=87d46a8&bb=b907a
*/

這個(gè)需求中,既涉及到了對(duì)替換子串的邏輯判斷,又涉及到了數(shù)字運(yùn)算,直接替換做不到,所以要考慮使用委托。先通過(guò)正則匹本出p=x,再在委托方法中進(jìn)行邏輯判斷和運(yùn)算。

3.3 多條件組合替換

當(dāng)需求中的條件多于一個(gè)時(shí),可能無(wú)法在一個(gè)正則表達(dá)式中進(jìn)行判斷,或者即使能夠在一個(gè)正則表達(dá)式中判斷,由于正則表達(dá)式非常復(fù)雜,會(huì)降低匹配效率,所以還是要在委托方法中進(jìn)行替換。

舉例1:

源字符串:第一個(gè)測(cè)試...<a href=\"www.test.com\">又一個(gè)測(cè)試</a>...第三個(gè)測(cè)試...<a href=\"www.test.com\" title=\"測(cè)試\" >第幾個(gè)測(cè)試了?</a>...這是最后一個(gè)測(cè)試了...

需求:為字符串中的“測(cè)試”加鏈接,已有鏈接的不加。

這個(gè)需求,首先是要進(jìn)行替換,但又加了一個(gè)附加條件,已有鏈接的不替換,這樣如果在一個(gè)正則表達(dá)式中實(shí)現(xiàn),正則太復(fù)雜,不但降低匹配效率,擴(kuò)展起來(lái)也很困難,可讀性也差,所以還是用正則委托來(lái)實(shí)現(xiàn)比較好。

先分析一下需求,在<a…>…</a>標(biāo)簽內(nèi)的關(guān)鍵字不進(jìn)行替換,那換個(gè)角度,只要先找出a標(biāo)簽外的字符串,對(duì)關(guān)鍵字進(jìn)行替換就可以滿(mǎn)足需求了。所以就是寫(xiě)正則,匹配出a標(biāo)簽外的子串,在委托方法中對(duì)關(guān)鍵字加鏈接,再替換回原字符串就可以了。

代碼實(shí)現(xiàn):

string test = "第一個(gè)測(cè)試...<a href=\"www.test.com\">又一個(gè)測(cè)試</a>...第三個(gè)測(cè)試...<a href=\"www.test.com\" title=\"測(cè)試\" >第幾個(gè)測(cè)試了?</a>...這是最后一個(gè)測(cè)試了...";
Regex reg = new Regex(@"(?is)^((?!</?a).)+|</a>((?!</?a).)+");
string result = reg.Replace(test, delegate(Match m) { return m.Value.Replace("測(cè)試", "<a href=\"www.test.com\">測(cè)試</a>"); });
richTextBox2.Text = result;
/*--------輸出--------
第一個(gè)<a href="www.test.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >測(cè)試</a>...<a href="www.test.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >又一個(gè)測(cè)試</a>...第三個(gè)<a href="www.test.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >測(cè)試</a>...<a href="www.test.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  title="測(cè)試" >第幾個(gè)測(cè)試了?</a>...這是最后一個(gè)<a href="www.test.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >測(cè)試</a>了...
*/

當(dāng)然,這個(gè)例子并不嚴(yán)謹(jǐn),因?yàn)槠渌鼧?biāo)簽中也可能出現(xiàn)關(guān)鍵字,而這些關(guān)鍵通常也是不應(yīng)該被替換的,這時(shí)也可以在委托方法中進(jìn)行判斷,以確定是否應(yīng)該被替換。

舉例2(正則去除不包含特定字符串的A標(biāo)簽~):

源字符串:<a href=www.abc.com>abc </a>啊啊啊 <a href=bcd.com>abc </a>啊啊啊 <a href="www.abc.com" class="t1">abc </a>啊啊啊 <a href=def.com>abc </a>啊啊啊 <a href=efg.com>abc </a>

需求:把鏈接中不包含“abc”的超鏈接過(guò)濾掉。

這個(gè)需求,實(shí)際上也是兩個(gè)條件,首先是要做替換,然后附加了一個(gè)條件,鏈接中不包含“abc”的替換。類(lèi)似于這種符合某一規(guī)律的子串,部分替換,部分保留的情況,通常比較適合用正則委托來(lái)解決。

當(dāng)然,這個(gè)需求還是可以直接通過(guò)一個(gè)正則表達(dá)式來(lái)處理的,先看一下這種處理方式的代碼。

string test = "<a href=www.abc.com>abc </a>啊啊啊 <a href=bcd.com>abc </a>啊啊啊 <a href=\"www.abc.com\" class=\"t1\">abc </a>啊啊啊 <a href=def.com>abc </a>啊啊啊 <a href=efg.com>abc </a> ";
Regex reg = new Regex(@"(?is)<a(?:(?!href=).)*href=(['""]?)(?:(?!abc|['""\s>]).)+\1(?:\s[^>]*)?>((?:(?!</?a\b).)*)</a>");
string result = reg.Replace(test, "$2");
richTextBox2.Text = result;
/*--------輸出--------
<a href=www.abc.com>abc </a>啊啊啊 abc 啊啊啊 <a href="www.abc.com" rel="external nofollow"  rel="external nofollow"  class="t1">abc </a>啊啊啊 abc 啊啊啊 abc 
*/

可以看到,這種處理方式,是先進(jìn)行判斷,再進(jìn)行匹配。在正則表達(dá)式中,對(duì)鏈接子串的每一個(gè)字符用“(?!abc|['""\s>]).”進(jìn)行判斷,所以有多少個(gè)字符,就要判斷多少次,在這種情況下,通常需要使用“|”來(lái)對(duì)不同的條件取“或”,而“|”的效率一般是比較低的。

另一種處理方式,是先把鏈接匹配出來(lái),然后在委托方法中進(jìn)行判斷,以決定是否替換。

代碼實(shí)現(xiàn):

string test = "<a href=www.abc.com>abc </a>啊啊啊 <a href=bcd.com>abc </a>啊啊啊 <a href=\"www.abc.com\" class=\"t1\">abc </a>啊啊啊 <a href=def.com>abc </a>啊啊啊 <a href=efg.com>abc </a> ";
Regex reg = new Regex(@"(?is)<a(?:(?!href=).)*href=(['""]?)([^'""\s>]+)\1[^>]*>((?:(?!</?a\b).)*)</a>");
string result = reg.Replace(test, delegate(Match m) { if (m.Groups[2].Value.IndexOf("abc") > -1) return m.Value; return m.Groups[3].Value; });
richTextBox2.Text = result;
/*--------輸出--------
<a href=www.abc.com>abc </a>啊啊啊 abc 啊啊啊 <a href="www.abc.com" rel="external nofollow"  rel="external nofollow"  class="t1">abc </a>啊啊啊 abc 啊啊啊 abc 
*/

這種處理方式,是先進(jìn)行匹配,再進(jìn)行判斷。先通過(guò)正則把每一個(gè)鏈接都匹配出來(lái),作為參數(shù)傳給委托方法,在委托方法中判斷是否包含“abc”,以決定是否替換。這種方式因?yàn)槠ヅ溥^(guò)程中不需要進(jìn)行判斷,所以匹配的速度是很快的,然后在委托方法中只執(zhí)行一次判斷即可。兩種處理方式的效率,在字符較少時(shí)區(qū)別不大,在字符較多,調(diào)用較頻繁的情況下,還是委托方法的效率比較高。

類(lèi)似于這種需求,在效率、可讀性、可擴(kuò)展性等方面綜合考慮,還是使用委托方法要好一些。

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

相關(guān)文章

  • 匹配價(jià)格的正則表達(dá)式

    匹配價(jià)格的正則表達(dá)式

    網(wǎng)上找了一些關(guān)于價(jià)格的正則表達(dá)式,但是限定整數(shù)范圍的貌似都沒(méi)什么效果,今天把兩個(gè)表達(dá)式拼了一下,拼成一個(gè)
    2009-11-11
  • 最新密碼驗(yàn)證正則表達(dá)式

    最新密碼驗(yàn)證正則表達(dá)式

    這篇文章主要為大家分享了最新密碼驗(yàn)證正則表達(dá)式,密碼形式可以根據(jù)開(kāi)發(fā)需求進(jìn)行設(shè)定,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • javascript中正則表達(dá)式反向引用示例介紹

    javascript中正則表達(dá)式反向引用示例介紹

    這篇文章主要介紹了javascript中正則表達(dá)式反向引用,需要的朋友可以參考下
    2014-03-03
  • 利用js給DropdownList賦值實(shí)例

    利用js給DropdownList賦值實(shí)例

    本文主要分享了利用js給DropdownList賦值的實(shí)例,代碼清晰,圖文并茂,有利于理解與掌握,需要的朋友可以看下
    2016-12-12
  • JavaScript正則表達(dá)式解析URL的技巧

    JavaScript正則表達(dá)式解析URL的技巧

    本文的宗旨在于教你如何理解URL的正則表達(dá)式,以達(dá)到理解正則表達(dá)式,以及能夠在日后的工作中寫(xiě)出相對(duì)簡(jiǎn)單的正則。對(duì)js正則表達(dá)式解析url相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • js正則表達(dá)式基本語(yǔ)法(精粹)

    js正則表達(dá)式基本語(yǔ)法(精粹)

    本篇文章給大家介紹正則表達(dá)式基本語(yǔ)法,學(xué)習(xí)正則表達(dá)式的基本語(yǔ)法是學(xué)習(xí)編程的基礎(chǔ),正則表達(dá)式在程序中應(yīng)用非常廣泛,有需要的朋友跟著腳本之家的小編一起學(xué)習(xí)吧
    2015-09-09
  • JavaScript  正則表達(dá)式備忘單實(shí)例代碼

    JavaScript 正則表達(dá)式備忘單實(shí)例代碼

    正則表達(dá)式或“regex”用于匹配字符串的各個(gè)部分,下面是我創(chuàng)建正則表達(dá)式的備忘單,需要的朋友可以參考下
    2019-04-04
  • 判斷用戶(hù)輸入的銀行卡號(hào)是否正確的方法(基于Luhn算法的格式校驗(yàn))

    判斷用戶(hù)輸入的銀行卡號(hào)是否正確的方法(基于Luhn算法的格式校驗(yàn))

    下面小編就為大家?guī)?lái)一篇判斷用戶(hù)輸入的銀行卡號(hào)是否正確的方法(基于Luhn算法的格式校驗(yàn))。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • js去掉首位空格的正則表達(dá)式

    js去掉首位空格的正則表達(dá)式

    去掉首位空格的方法有很多,在本文為大家介紹下使用正則表達(dá)式來(lái)完成,具體寫(xiě)法如下,喜歡的朋友可以參考下
    2013-11-11
  • EditPlus中的正則表達(dá)式實(shí)戰(zhàn)(6)

    EditPlus中的正則表達(dá)式實(shí)戰(zhàn)(6)

    這篇文章主要介紹了EditPlus中的正則表達(dá)式及語(yǔ)義分析,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2016-12-12

最新評(píng)論