為了避免以后這樣的情況,在此記錄下正則表達(dá)式的一些基本使用方法附帶小的實(shí)例。讓以后在使用時(shí)能一目了然知道他的使用,為開發(fā)節(jié)約時(shí)間,同時(shí)也分享給大家
正則元字符
在說正則表達(dá)式之前我們先來看看通配符,我想通配符大家都用過。通配符主要有星號(hào)(*)和問號(hào)(?),用來模糊搜索文件。winodws中我們常會(huì)使用搜索來查找一些文件。如:*.jpg,XXX.docx的方式,來快速查找文件。其實(shí)正則表達(dá)式和我們通配符很相似也是通過特定的字符匹配我們所要查詢的內(nèi)容信息。已下代碼都是區(qū)分大小寫。
常用元字符
代碼 | 說明 |
. | 匹配除換行符以外的任意字符。 |
/w | 匹配字母或數(shù)字或下劃線或漢字。 |
/s | 匹配任意的空白符。 |
/d | 匹配數(shù)字。 |
/b | 匹配單詞的開始或結(jié)束。 |
[ck] | 匹配包含括號(hào)內(nèi)元素的字符 |
^ | 匹配行的開始。 |
$ | 匹配行的結(jié)束。 |
/ | 對(duì)下一個(gè)字符轉(zhuǎn)義。比如$是個(gè)特殊的字符。要匹配$的話就得用/$ |
| | 分支條件,如:x|y匹配 x 或 y。 |
反義元字符
代碼 | 說明 |
/W | 匹配任意不是字母,數(shù)字,下劃線,漢字的字符。 |
/S | 匹配任意不是空白符的字符。等價(jià)于 [^ /f/n/r/t/v]。 |
/D | 匹配任意非數(shù)字的字符。等價(jià)于 [^0-9]。 |
/B | 匹配不是單詞開頭或結(jié)束的位置。 |
[^CK] | 匹配除了CK以外的任意字符。 |
特殊元字符
代碼 | 說明 |
/f | 匹配一個(gè)換頁符。等價(jià)于 /x0c 和 /cL。 |
/n | 匹配一個(gè)換行符。等價(jià)于 /x0a 和 /cJ。 |
/r | 匹配一個(gè)回車符。等價(jià)于 /x0d 和 /cM。 |
/t | 匹配一個(gè)制表符。等價(jià)于 /x09 和 /cI。 |
/v | 匹配一個(gè)垂直制表符。等價(jià)于 /x0b 和 /cK。 |
限定符
代碼 | 說明 |
* | 匹配前面的子表達(dá)式零次或多次。 |
+ | 匹配前面的子表達(dá)式一次或多次。 |
? | 匹配前面的子表達(dá)式零次或一次。 |
{n} | n 是一個(gè)非負(fù)整數(shù)。匹配確定的 n 次。 |
{n,} | n 是一個(gè)非負(fù)整數(shù)。至少匹配n 次。 |
{n,m} | m 和 n 均為非負(fù)整數(shù),其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
懶惰限定符
代碼 | 說明 |
*? | 重復(fù)任意次,但盡可能少重復(fù)。 如 "acbacb" 正則 "a.*?b" 只會(huì)取到第一個(gè)"acb" 原本可以全部取到但加了限定符后,只會(huì)匹配盡可能少的字符 ,而"acbacb"最少字符的結(jié)果就是"acb" 。 |
+? | 重復(fù)1次或更多次,但盡可能少重復(fù)。與上面一樣,只是至少要重復(fù)1次。 |
?? | 重復(fù)0次或1次,但盡可能少重復(fù)。 如 "aaacb" 正則 "a.??b" 只會(huì)取到最后的三個(gè)字符"acb"。 |
{n,m}? | 重復(fù)n到m次,但盡可能少重復(fù)。 如 "aaaaaaaa" 正則 "a{0,m}" 因?yàn)樽钌偈?次所以取到結(jié)果為空。 |
{n,}? | 重復(fù)n次以上,但盡可能少重復(fù)。 如 "aaaaaaa" 正則 "a{1,}" 最少是1次所以取到結(jié)果為 "a"。 |
捕獲分組
代碼 | 說明 |
(exp) | 匹配exp,并捕獲文本到自動(dòng)命名的組里。 |
(?<name>exp) | 匹配exp,并捕獲文本到名稱為name的組里。 |
(?:exp) | 匹配exp,不捕獲匹配的文本,也不給此分組分配組號(hào)以下為零寬斷言。 |
(?=exp) | 匹配exp前面的位置。 如 "How are you doing" 正則"(?<txt>.+(?=ing))" 這里取ing前所有的字符,并定義了一個(gè)捕獲分組名字為 "txt" 而"txt"這個(gè)組里的值為"How are you do"; |
(?<=exp) | 匹配exp后面的位置。 如 "How are you doing" 正則"(?<txt>(?<=How).+)" 這里取"How"之后所有的字符,并定義了一個(gè)捕獲分組名字為 "txt" 而"txt"這個(gè)組里的值為" are you doing"; |
(?!exp) | 匹配后面跟的不是exp的位置。 如 "123abc" 正則 "/d{3}(?!/d)"匹配3位數(shù)字后非數(shù)字的結(jié)果 |
(?<!exp) | 匹配前面不是exp的位置。 如 "abc123 " 正則 "(?<![0-9])123" 匹配"123"前面是非數(shù)字的結(jié)果也可寫成"(?!</d)123" |
得到上面秘籍后我們可以小試牛刀...
小試牛刀
在C#中使用正則表達(dá)式主要是通過Regex類來實(shí)現(xiàn)。命名空間:using System.Text.RegularExpressions。
其中常用方法:
名稱 | 說明 |
IsMatch(String, String) | 指示 Regex 構(gòu)造函數(shù)中指定的正則表達(dá)式在指定的輸入字符串中是否找到了匹配項(xiàng)。 |
Match(String, String) | 在指定的輸入字符串中搜索 Regex 構(gòu)造函數(shù)中指定的正則表達(dá)式的第一個(gè)匹配項(xiàng)。 |
Matches(String, String) | 在指定的輸入字符串中搜索正則表達(dá)式的所有匹配項(xiàng)。 |
Replace(String, String) | 在指定的輸入字符串內(nèi),使用指定的替換字符串替換與某個(gè)正則表達(dá)式模式匹配的所有字符串。 |
Split(String, String) | 在由 Regex 構(gòu)造函數(shù)指定的正則表達(dá)式模式所定義的位置,拆分指定的輸入字符串。 |
在使用正則表達(dá)式前我們先來看看“@”符號(hào)的使用。
學(xué)過C#的人都知道C# 中字符串常量可以以@ 開頭聲名,這樣的優(yōu)點(diǎn)是轉(zhuǎn)義序列“不”被處理,按“原樣”輸出,即我們不需要對(duì)轉(zhuǎn)義字符加上 / (反斜扛),就可以輕松coding。如:
如要在一個(gè)用 @ 引起來的字符串中包括一個(gè)雙引號(hào),就需要使用兩對(duì)雙引號(hào)了。這時(shí)候你不能使用 / 來轉(zhuǎn)義爽引號(hào)了,因?yàn)樵谶@里 / 的轉(zhuǎn)義用途已經(jīng)被 @ “屏蔽”掉了。如:
字符串匹配:
在實(shí)際項(xiàng)目中我們常常需要對(duì)用戶輸入的信息進(jìn)行驗(yàn)證。如:匹配用戶輸入的內(nèi)容是否為數(shù)字,是否為有效的手機(jī)號(hào)碼,郵箱是否合法....等。
實(shí)例代碼:
string RegexStr = string.Empty;#region 字符串匹配RegexStr = "^[0-9]+$"; //匹配字符串的開始和結(jié)束是否為0-9的數(shù)字[定位字符]Console.WriteLine("判斷'R1123'是否為數(shù)字:{0}", Regex.IsMatch("R1123", RegexStr));Console.WriteLine("判斷'1123'是否為數(shù)字:{0}", Regex.IsMatch("1123", RegexStr));RegexStr = @"/d+"; //匹配字符串中間是否包含數(shù)字(這里沒有從開始進(jìn)行匹配噢,任意位子只要有一個(gè)數(shù)字即可)Console.WriteLine("'R1123'是否包含數(shù)字:{0}", Regex.IsMatch("R1123", RegexStr));Console.WriteLine("'博客園'是否包含數(shù)字:{0}", Regex.IsMatch("博客園", RegexStr));//感謝@zhoumy的提醒..已修改錯(cuò)誤代碼RegexStr = @"^Hello World[/w/W]*"; //已Hello World開頭的任意字符(/w/W:組合可匹配任意字符)Console.WriteLine("'HeLLO WORLD xx hh xx'是否已Hello World開頭:{0}", Regex.IsMatch("HeLLO WORLD xx hh xx", RegexStr, RegexOptions.IgnoreCase));Console.WriteLine("'LLO WORLD xx hh xx'是否已Hello World開頭:{0}", Regex.IsMatch("LLO WORLD xx hh xx", RegexStr,RegexOptions.IgnoreCase));//RegexOptions.IgnoreCase:指定不區(qū)分大小寫的匹配。#endregion
顯示結(jié)果:
字符串查找:
實(shí)例代碼:
string RegexStr = string.Empty; #region 字符串查找string LinkA = "<a href=/"http://www.baidu.com/" target=/"_blank/">百度</a>";RegexStr = @"href=""[/S]+"""; // ""匹配"Match mt = Regex.Match(LinkA, RegexStr);Console.WriteLine("{0}。", LinkA);Console.WriteLine("獲得href中的值:{0}。", mt.Value);RegexStr = @"<h[^23456]>[/S]+<h[1]>"; //<h[^23456]>:匹配h除了2,3,4,5,6之中的值,<h[1]>:h匹配包含括號(hào)內(nèi)元素的字符Console.WriteLine("{0}。GetH1值:{1}", "<H1>標(biāo)題<H1>", Regex.Match("<H1>標(biāo)題<H1>", RegexStr, RegexOptions.IgnoreCase).Value);Console.WriteLine("{0}。GetH1值:{1}", "<h2>小標(biāo)<h2>", Regex.Match("<h2>小標(biāo)<h2>", RegexStr, RegexOptions.IgnoreCase).Value);//RegexOptions.IgnoreCase:指定不區(qū)分大小寫的匹配。RegexStr = @"ab/w+|ij/w{1,}"; //匹配ab和字母 或 ij和字母Console.WriteLine("{0}。多選結(jié)構(gòu):{1}", "abcd", Regex.Match("abcd", RegexStr).Value);Console.WriteLine("{0}。多選結(jié)構(gòu):{1}", "efgh", Regex.Match("efgh", RegexStr).Value);Console.WriteLine("{0}。多選結(jié)構(gòu):{1}", "ijk", Regex.Match("ijk", RegexStr).Value);RegexStr = @"張三?豐"; //?匹配前面的子表達(dá)式零次或一次。Console.WriteLine("{0}。可選項(xiàng)元素:{1}", "張三豐", Regex.Match("張三豐", RegexStr).Value);Console.WriteLine("{0}。可選項(xiàng)元素:{1}", "張豐", Regex.Match("張豐", RegexStr).Value);Console.WriteLine("{0}。可選項(xiàng)元素:{1}", "張飛", Regex.Match("張飛", RegexStr).Value);/* 例如:July|Jul 可縮短為 July?4th|4 可縮短為 4(th)?*///匹配特殊字符RegexStr = @"Asp/.net"; //匹配Asp.net字符,因?yàn)?是元字符他會(huì)匹配除換行符以外的任意字符。這里我們只需要他匹配.字符即可。所以需要轉(zhuǎn)義/.這樣表示匹配.字符Console.WriteLine("{0}。匹配Asp.net字符:{1}", "Java Asp.net SQLServer", Regex.Match("Java Asp.net SQLServer", RegexStr).Value);Console.WriteLine("{0}。匹配Asp.net字符:{1}", "C# Java", Regex.Match("C# Java", RegexStr).Value);#endregion
顯示結(jié)果:
貪婪與懶惰
string f = "fooot";//貪婪匹配RegexStr = @"f[o]+";Match m1 = Regex.Match(f, RegexStr);Console.WriteLine("{0}貪婪匹配(匹配盡可能多的字符):{1}", f, m1.ToString());//懶惰匹配RegexStr = @"f[o]+?";Match m2 = Regex.Match(f, RegexStr);Console.WriteLine("{0}懶惰匹配(匹配盡可能少重復(fù)):{1}", f, m2.ToString());
顯示結(jié)果:
從上面的例子中我們不難看出貪婪與懶惰的區(qū)別,他們的名子取的都很形象。
貪婪匹配:匹配盡可能多的字符。
懶惰匹配:匹配盡可能少的字符。
(exp)分組
在做爬蟲時(shí)我們經(jīng)常獲得A中一些有用信息。如href,title和顯示內(nèi)容等。
string TaobaoLink = "<a href=/"http://www.taobao.com/" title=/"淘寶網(wǎng) - 淘!我喜歡/" target=/"_blank/">淘寶</a>";RegexStr = @"<a[^>]+href=""(/S+)""[^>]+title=""([/s/S]+?)""[^>]+>(/S+)</a>";Match mat = Regex.Match(TaobaoLink, RegexStr);for (int i = 0; i < mat.Groups.Count; i++){ Console.WriteLine("第"+i+"組:"+mat.Groups[i].Value);}
顯示結(jié)果:
在正則表達(dá)式里使用()包含的文本自動(dòng)會(huì)命名為一個(gè)組。上面的表達(dá)式中共使用了4個(gè)()可以認(rèn)為是分為了4組。
輸出結(jié)果共分為:4組。
0組:為我們所匹配的字符串。
1組:是我們第一個(gè)括號(hào)[href=""(/S+)""]中(/S+)所匹配的網(wǎng)址信息。內(nèi)容為:http://www.taobao.com。
2組:是第二個(gè)括號(hào)[title=""([/s/S]+?)""]中所匹配的內(nèi)容信息。內(nèi)容為:淘寶網(wǎng) - 淘!我喜歡。
這里我們會(huì)看到+?懶惰限定符。title=""([/s/S]+?)"" 這里+?的下一個(gè)字符為"雙引號(hào),"雙引號(hào)在匹配字符串后面還有三個(gè)。+?懶惰限定符會(huì)盡可能少重復(fù),所他會(huì)匹配最前面那個(gè)"雙引號(hào)。如果我們不使用+?懶惰限定符他會(huì)匹配到:淘寶網(wǎng) - 淘!我喜歡" target= 會(huì)盡可能多重復(fù)匹配。
3組:是第三個(gè)括號(hào)[(/S+)]所匹配的內(nèi)容信息。內(nèi)容為:淘寶。
說明:反義元字符所對(duì)應(yīng)的元字符都能組合匹配任意字符。如:[/w/W],[/s/S],[/d/D]..
(?<name>exp) 分組取名
當(dāng)我們匹配分組信息過多后,在某種場(chǎng)合只需取當(dāng)中某幾組信息。這時(shí)我們可以對(duì)分組取名。通過分組名稱來快速提取對(duì)應(yīng)信息。
string Resume = "基本信息姓名:CK|求職意向:.NET軟件工程師|性別:男|學(xué)歷:本專|出生日期:1988-08-08|戶籍:湖北.孝感|E - Mail:[email protected]|手機(jī):15000000000";RegexStr = @"姓名:(?<name>[/S]+)/|/S+性別:(?<sex>[/S]{1})/|學(xué)歷:(?<xueli>[/S]{1,10})/|出生日期:(?<Birth>[/S]{10})/|[/s/S]+手機(jī):(?<phone>[/d]{11})";Match matc = Regex.Match(Resume, RegexStr);Console.WriteLine("姓名:{0},手機(jī)號(hào):{1}", matc.Groups["name"].ToString(), matc.Groups["phone"].ToString());
顯示結(jié)果:
通過(?<name>exp)可以很輕易為分組取名。然后通過Groups["name"]取得分組值。
獲得頁面中A標(biāo)簽中href值
string PageInfo = @"<hteml> <div id=""div1""> <a href=""http://www.baidu.con"" target=""_blank"">百度</a> <a href=""http://www.taobao.con"" target=""_blank"">淘寶</a> <a href=""http://www.cnblogs.com"" target=""_blank"">博客園</a> <a href=""http://www.google.con"" target=""_blank"">google</a> </div> <div id=""div2""> <a href=""/zufang/"">整租</a> <a href=""/hezu/"">合租</a> <a href=""/qiuzu/"">求租</a> <a href=""/ershoufang/"">二手房</a> <a href=""/shangpucz/"">商鋪出租</a> </div> </hteml>";RegexStr = @"<a[^>]+href=""(?<href>[/S]+?)""[^>]*>(?<text>[/S]+?)</a>";MatchCollection mc = Regex.Matches(PageInfo, RegexStr);foreach (Match item in mc){ Console.WriteLine("href:{0}--->text:{1}",item.Groups["href"].ToString(),item.Groups["text"].ToString());}
顯示結(jié)果:
Replace 替換字符串
用戶在輸入信息時(shí)偶爾會(huì)包含一些敏感詞,這時(shí)我們需要替換這個(gè)敏感詞。
string PageInputStr = "靠.TMMD,今天真不爽....";RegexStr = @"靠|TMMD|媽的";Regex rep_regex = new Regex(RegexStr);Console.WriteLine("用戶輸入信息:{0}", PageInputStr);Console.WriteLine("頁面顯示信息:{0}", rep_regex.Replace(PageInputStr, "***"));
顯示結(jié)果:
對(duì)一些敏感詞直接替換成***代替。
Split 拆分字符串
string SplitInputStr = "1xxxxx.2ooooo.3eeee.4kkkkkk.";RegexStr = @"/d";Regex spl_regex = new Regex(RegexStr);string[] str = spl_regex.Split(SplitInputStr);foreach (string item in str){ Console.WriteLine(item);}
顯示結(jié)果:
根據(jù)數(shù)字截取字符串。
首先,我們先看幾個(gè)實(shí)際的例子:
1. 驗(yàn)證輸入字符是否
javascript:
var ex = "^//w+$";
var re = new RegExp(ex,"i");
return re.test(str);
VBScript
Dim regEx,flag,ex
ex = "^/w+$"
Set regEx = New RegExp
regEx.IgnoreCase = True
regEx.Global = True
regEx.Pattern = ex
flag = regEx.Test( str )
C#
System.String ex = @"^/w+$";
System.Text.RegularExpressions.Regex reg = new Regex( ex );
bool flag = reg.IsMatch( str );
2. 驗(yàn)證郵件格式
C#
System.String ex = @"^/w+@/w+/./w+$";
System.Text.RegularExpressions.Regex reg = new Regex( ex );
bool flag = reg.IsMatch( str );
3. 更改日期的格式(用 dd-mm-yy 的日期形式代替 mm/dd/yy 的日期形式)
C#
String MDYToDMY(String input)
{
return Regex.Replace(input,
"http://b(?//d{1,2})/(?//d{1,2})/(?//d{2,4})//b",
"${day}-${month}-${year}");
}
4. 從 URL 提取協(xié)議和端口號(hào)
C#
String Extension(String url)
{
Regex r = new Regex(@"^(?/w+)://[^/]+?(?:/d+)?/",
RegexOptions.Compiled);
return r.Match(url).Result("${proto}${port}");
}
這里的例子可能是我們?cè)诰W(wǎng)頁開發(fā)中,通常會(huì)碰到的一些正則表達(dá)式,尤其在第一個(gè)例子中,給出了使用javascript,vbScript,C#等不同語言的實(shí)現(xiàn)方式,大家不難看出,對(duì)于不同的語言來說,正則表達(dá)式?jīng)]有區(qū)別,只是正則表達(dá)式的實(shí)現(xiàn)類不同而已。而如何發(fā)揮正則表達(dá)式的公用,也要看實(shí)現(xiàn)類的支持。
(摘自msdn: Microsoft .NET 框架 SDK 提供大量的正則表達(dá)式工具,使您能夠高效地創(chuàng)建、比較和修改字符串,以及迅速地分析大量文本和數(shù)據(jù)以搜索、移除和替換文本模式。ms-help://MS.VSCC/MS.MSDNVS.2052/cpgenref/html/cpconregularexpressionslanguageelements.htm)
下面我們逐個(gè)來分析這些例子:
1-2,這兩個(gè)例子很簡(jiǎn)單,只是簡(jiǎn)單的驗(yàn)證字符串是否符合正則表達(dá)式規(guī)定的格式,其中使用的語法,在第一篇文章中都已經(jīng)介紹過了,這里做一下簡(jiǎn)單的描述。
第1個(gè)例子的表達(dá)式: ^/w+$
^ -- 表示限定匹配開始于字符串的開始
/w
主站蜘蛛池模板:
精品一区二区久久久久久按摩
|
日本一区二区不卡在线观看
|
看免费毛片
|
精品久久久久久久久亚洲
|
嫩草影院在线观看网站成人
|
一级在线|
农村少妇吞精夜夜爽视频
|
久久久久成人免费
|
h视频免费看
|
在线看一区二区三区
|
99久久婷婷国产综合精品青牛牛
|
欧美精品videos
|
午夜av男人的天堂
|
中文在线日韩
|
午夜精品小视频
|
hd日本xxxx|
国产亚洲小视频
|
日韩视频一
|
精品国产一区在线
|
jizzjizz中国少妇中文
|
国产精品久久久久网站
|
久久亚洲国产精品
|
婷婷亚洲一区二区三区
|
国产一区二区视频精品
|
一边吃奶一边插下面
|
少妇色诱麻豆色哟哟
|
黄色大片网站在线观看
|
在线播放免费视频
|
夜夜夜精品视频
|
免费a级黄色毛片
|
午夜久久久久
|
手机在线看片国产
|
久久婷婷一区二区三区
|
精品免费国产一区二区三区
|
日本不卡视频在线观看
|
亚洲国产馆
|
色妞妞视频
|
国产做爰全免费的视频黑人
|
久久久久亚洲a
|
久草视频中文
|
www.777含羞草|