正則表達式—RegEx(RegularExpressio)(二)

今日隨筆,繼續寫一些關於正則表達式的東西。java

 

首先補一點昨天的內容:c++

昨天少說了一個貪婪模式,什麼是貪婪模式,好比像+或者*這樣的元字符匹配中,會以最大匹配值匹配,這句話是什麼意思呢,例如:正則表達式

定義一個正則表達式模式:ab+ ,而後又這樣一個字符串"csddabbbbbbbbbbbbaaaa" 那麼他匹配出來的字符串就是abbbbbbbbbbbb,而不是ab或者abbbb等等。都是匹配的符合的最大的字符串長度。數據庫

那何時終結貪婪模式呢? 就是在+或者*這樣的元字符後面加一個「?」,還拿上面的例子說明 若是定義的正則表達式模式:「ab+?」,那麼字符串"csddabbbbbbbbbbbbaaaa"與其匹配的結果就是ab,這樣就看出終結貪婪模式的意思了吧,正酣和貪婪模式相反,是匹配的符合的最小的字符串長度。服務器

 

好了,上一節主要介紹了Regex類的IsMatch方法,其方法主要是判斷字符串是否與正則表達式匹配,主要是在一些驗證中用到,好比在網頁註冊中驗證輸入的郵箱地址啊,生分證號是否正確等等(這裏要說一下,正則表達式是不分語言的,不如^、$、[]等這些元字符在c++中java或者js語言中都是這麼用的)。網站

那麼,如今老闆有這樣一個需求,給你一些網頁,讓你收集這些網頁上的全部emai地址,而後記錄下來查到數據庫中,方便之後給這些郵箱發送我電商網站的促銷信息。spa

怎麼辦? 去這些網頁裏面一個一個找到email?而後一個一個的查到數據庫?,我勒個去,太恐怖了吧。3d

可是,若是你懂得正則表達式的匹配,你就會發現,Is so easy。。。code

啥都不說,先上一個例子,好比我要收集這樣的一個網頁中的email:server

//------第一個要求,查找一個網頁上的全部email地址,而且提取出來
            string str = File.ReadAllText("你們留下email交友吧_email_天涯社區.htm");

            //string regex = @"\w+@\w+(\.\w+){1,3}";
            string regex = @"[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+){1,3}";//這個就不用我解釋了吧,看過上一章的小夥伴們應該都明吧
            MatchCollection coll = Regex.Matches(str, regex);
            foreach (Match item in coll)
            {
                Console.WriteLine(item.Value);

            }

顯示結果:

 

如今讓咱們來解釋一下代碼吧,首先用一個string變量str接受要收集網頁的全部內容,而後又定義了email的正則表達式模式regex,這裏要注意一下,這個模式和上個模式中少了^$,這裏爲何不加這兩個元字符了呢,其實想一想也知道,我只要在網頁中找到其中能夠匹配的regex就能夠了,而不是讓整個str字符串與regex。

而後咱們調用了Regex類的Matchs方法,這個方法表示 在指定的輸入字符串中搜索指定的正則表達式的全部匹配項,返回結果:搜索操做找到的System.Text.RegularExpressions.Match隊形的集合,類型是MatchCollection,而後循環這個集合,調用Match的value屬性就能獲得匹配的email地址。

恩。。。 ,還有一些其餘屬性和方法小夥伴們能夠本身去看一下,很簡單的 相信你們一看就能明吧。

是否是感受很簡單,哈,那麼,如今老闆又有要求了,他說把提取出的每一個email作個對比,看看哪域名的email用的最多。

額。。。email的域名是什麼? 就是像@gmail.com這樣的東東啦。

該怎麼作呢,用字符串截取?固然能夠,並且也很好實現,可是要是也是用正則表達式的知識呢?

解決這個問題以前,讓咱們再來了解一正則表達式中「提取組」這個麼個東西,什麼是提取組,其實就是在正則表達式模式中加入「()」個東西包起來就是一個提取組,例如:

定義一個表達式模式regex = "name=(\w+)age=(\d{0,2})",咱們能夠看出在名字的地方有了「()」給包了起來,這就是一個組,在年齡的地方又用"()"包了起來,這又是一個組。,那說了這麼多,這個組到時是幹啥用的呢,

那麼我如今有着樣一個字符串與其匹配:str ="name=小強age=23":代碼以下:

string regex = @"name=(\w+)age=(\d{0,2})";
            string str = "name=小強age=23";
            Match match = Regex.Match(str, regex);

            Console.WriteLine("name:{0},age:{1}", match.Groups[1].Value, match.Groups[2].Value);

            //輸出結果 name:小強,age:23

Match類中有一個Groups屬性,它就是一個組的集合,他的索引是從0開始的,可是索引是0的值是匹配regex模式的在字符串的自己,在這裏match.Groups[0].Value得值就是"name=小強age=23",在regex模式中,有兩個組,一個是(\w+),一個是(\d{0.3}),怎麼判斷它的順序呢,哪一個是第一組,哪一個是第二種,現這種的還很好判斷從左到又唄,可是像(a((b)c(d))ef(g))這樣的,怎麼判斷呢,其實很簡單,從左到右看「(」第幾個出現就是第幾組。

這樣,咱們就能夠在匹配完成後的字符串中繼續按着本身的意願分組獲得相應的結果(這裏我獲得的是名字和年齡)。

好了,如今讓咱們回到老闆的第二個需求,那麼我只須要在正則表達式模式中給域名的那一本分用"()"包起來,分紅一個組,而後遍歷的時候給它放到字典中做爲key值,其value值設爲0,若是下次再出現的時候,我就讓他的value加一上1

代碼:

//------第二個要求 我但願把提取出的每一個email作個對比,看看哪域名的email用的最多
            string str = File.ReadAllText("你們留下email交友吧_email_天涯社區.htm");
            string regex = @"[a-zA-Z0-9_]+@([a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+){1,3})";
            MatchCollection coll = Regex.Matches(str, regex);
            Dictionary<string, int> dic = new Dictionary<string, int>();
            foreach (Match item in coll)
            {
                if (!dic.ContainsKey(item.Groups[1].ToString().ToLower()))
                {
                    dic.Add(item.Groups[1].ToString().ToLower(), 1);
                }
                else
                {
                    dic[item.Groups[1].ToString().ToLower()]++;
                }
            }
            //遍歷字典
            foreach (var item in dic)
            {
                Console.WriteLine("域名:" + item.Key + " 使用的個數:" + item.Value);
            }
            //---------------end----------------------

輸出結果:

 

而後再和你們分享幾個例子:

#region "192.168.10.5[port=21,type=ftp]",這個字符串表示ip地址是192.168.10.5的服務器的21號端口提供ftp服務,其中若果ftp被省略,則默認是http服務,請解析此字符串而後打印出「IP地址是。。。端口是。。。提供的服務是。。。」
            string regex = @"^((\d{1,3}\.){3}\d{1,3})\[port=(\d{2,6})(,type=(\w+))?\]$";
            while (true)
            {
                string ipCode = Console.ReadLine();
                Match match = Regex.Match(ipCode, regex);
                if (match.Success)//這裏也是判斷是否匹配成功
                {
                    string ip = match.Groups[1].Value;
                    string port = match.Groups[3].Value;
                    string serverType = "http";
                    if (match.Groups[5].Success) serverType = match.Groups[5].Value;
                    //string serverType = string.IsNullOrEmpty(match.Groups[5].Value) ? "http" : match.Groups[5].Value;
                    Console.WriteLine("IP地址是{0},端口是{1},提供的服務是{2}", ip, port, serverType);
                }
                else
                {
                    Console.WriteLine("輸入的不是正確的ip地址");
                }
            }
#endregion


#region 字符串替換 將aaaaaaabbbbbbbbbccccccccc 變成abc string str = "aaaaaaabbbbbbbbbccccccccc"; Console.WriteLine(Regex.Replace(str, @"aa|bb|cc", "")); #endregion

 

 

好啦 今天就寫到這吧,而後呢仍是但願你們能給出各類建議,不對的地方請指出,我會很是感謝的而且虛心改正,若是今天和昨天的那些例子住有的小夥伴不明白的,也請留言具體指出哪一個還不太理解,我也會盡力給予解答,最後但願個人隨筆能夠給你們帶來一些收穫。 晚安,小夥伴們。

相關文章
相關標籤/搜索