正則表達式基本用法

說到正則表達式,你們就會想到那像火星文同樣的正則表達式字符串。雖然看起來很奇怪,可是一個個都搞清楚那些東西分別表示什麼意思的時候,會發現這東西其實也不難。說幹就幹,咱們來一個個的理解。正則表達式

先弄點數據spa

string input = "http://www.tansea.cn/23 233【我的博客】23333【http©雙子宮殿】";
List<string> pattern = new List<string>();

先來個最簡單的開個味,太深了都沒有興趣往下看了code

pattern.Add("http");//常量匹配 result = 2

沒有任何的正則表達式的元字符(也就是保留字),http在input裏面有2個,因此匹配到了2條blog

基礎篇

1、基本語義描述符字符串

一、\d(數字字符)與\D(非數字字符)input

pattern.Add("233\\d");//匹配233+數字字符 result=1
pattern.Add("233\\D");//匹配233+非數字字符 result=1

二、\w(字母數字下劃線)與\W(非字母數字下劃線)博客

pattern.Add("\\w");//匹配字母+數字+下劃線 result=36
pattern.Add("\\W");//不匹配字母+數字+下劃線 result=11

注意:實測\w是能匹配到中文的string

三、\s(空白字符)與\S(非空白字符)it

空白字符包括製表符、換行符、垂直製表符、換頁符、回車符io

複製代碼
pattern.Add("\t");//匹配製表符 等價於\x09
pattern.Add("\n");//匹配換行符 等價於\x0A
pattern.Add("\v");//匹配垂直製表符 等價於\x0B
pattern.Add("\f");//匹配換頁符 等價於\x0C
pattern.Add("\r");//匹配回車符 等價於\x0D
pattern.Add("\\s");//匹配任何空白字符 等價於[\t\n\v\f\r]
pattern.Add("\\S");//匹配任何非空白字符 等價於[\t\n\v\f\r]
複製代碼

到這裏就須要說明一下了,\和\\的區別

\是C#的轉義符,若是要讓C#把\當字符處理,要使用\\

或者在字符串前使用@告訴C#這個字符串的反斜槓都當字符處理

pattern.Add(@"\s");

注意:若是一個字符串裏面有多個\,有表示轉義符,也有表示字符的,那就不能在字符串以前用@,只能用\\來區分

四、.(任何字符,除\n)

pattern.Add(".");//匹配除 "\n" 以外的任何字符 result=49

五、\xXX(單字節)與\uXXXX(雙字節)

\xXX單字節字符,字符對應轉義值能夠查ASCII碼錶

pattern.Add("\x61");//匹配單字節字符(x61=a) result=2
pattern.Add("\x20");//匹配單字節字符(x20=空格) result=1

\uXXXX雙字節字符,除經常使用字符以外的全部字符,包括各類不經常使用字符和各國語言字符等等

pattern.Add("\u00A9");//匹配雙字節(u00A9=©) result=1
pattern.Add("[\u4e00-\u9fa5]");//匹配雙字節([\u4e00-\u9fa5]=漢字) result=8

2、定位描述符

一、^ (匹配字符串的開始位置)

pattern.Add("^http");//開始位置匹配 result = 1
pattern.Add("^tansea");//開始位置匹配 result = 0

input確實是以http開頭的,因此匹配到了1條,而下面那條語句沒有匹配到記錄

二、$(匹配字符串的結束位置)

pattern.Add("】$");//結束位置匹配 result = 1

三、\b(空格)與\B(非空格)

pattern.Add("23\\b");//匹配23+空格 result=1
pattern.Add("23\\B");//匹配23+非空格 result=2

3、重複描述符

一、*(匹配0-∞次  等價於{0,})

pattern.Add("233*");//以23開頭,後面接0到n個3匹配 result=3

匹配到2三、23三、23333三條記錄

二、+(匹配1-∞次  等價於{1,})

pattern.Add("233+");//以23開頭,後面接1到n個3匹配 result=2

匹配到23三、23333兩條記錄

三、?(匹配0-1次  等價於{0,1})

pattern.Add("233?");//以23開頭,後面接0到1個3匹配 result=3

匹配到2三、23三、233(23333前面部分)三條記錄

四、{n}(匹配n次,n>0)

pattern.Add("233{1}");//以23開頭,後面接1個3匹配 result=2

匹配到23三、233(23333前面部分)兩條記錄

五、{n,}(匹配n-∞次,n>0)

pattern.Add("233{1,}");//以23開頭,後面接1到無限個3匹配 result=2

匹配到23三、23333兩條記錄

六、{n,m}(匹配n-m次,n>0 且 n<=m)

pattern.Add("233{2,3}");//以23開頭,後面接2到3個3匹配 result=1

匹配到23333一條記錄

4、選擇描述符

一、|(或操做)

pattern.Add("com|cn|net");//或條件 result=1

二、[](IN操做,匹配所包含的任意一個字符)

pattern.Add("[人從衆]");//IN條件 result=1

IN條件與或條件的區別:或條件是支持多字符,將一個段作爲一個總體而IN條件只支持單字符

pattern.Add("[^人從衆]");//NOT IN條件 result=46
pattern.Add("[o-t]");//BETWEEN條件 匹配小寫o到小寫t result=8
pattern.Add("[^o-t]");//NOT BETWEEN條件 匹配非小寫o到小寫t result=39

5、組(...)與非捕獲組(?:...)

正則表達式會將刮號裏的內容單獨保存成一個組,而且匹配到的組能夠反向引用,\n是引用第n組

pattern.Add("\\.(.{1,6})");//.開頭取6個字符 result=2

結果:Group[0]=.tansea Group[1]=tansea 

          Group[0]=.cn/23  Group[1]=cn/23 

注意:/23後面是有一個空格的,是取了6個字符

若是不想把刮號裏的內容保存到組,能夠用非捕獲組

pattern.Add("\\.(?:.{1,6})");

6、貪婪與非貪婪

正則表達式默認爲貪婪模式,能夠在重複描述符後加上?改爲非貪婪模式

pattern.Add(".*233");//結果爲"http://www.tansea.cn/23 233【我的博客】233"一條記錄
pattern.Add(".*?233");//結果爲"http://www.tansea.cn/23 233"、"【我的博客】233"兩條記錄

7、回溯與非回溯

正則表達式默認爲回溯模式,能夠(?>...)改爲非回溯模式

在貪婪模式狀況下,非回溯模式不會再從新去匹配,而是接着繼續匹配

pattern.Add("(.*)233");//結果爲"http://www.tansea.cn/23 233【我的博客】233"
pattern.Add("(?>.*)233");//結果爲空

8、正向預搜索(?=...)與反向預搜索(?<=...)

一、正向預搜索

pattern.Add("\\d{3}(?=【我的博客】)");//匹配3個數字開頭後面是"【我的博客】"
pattern.Add("\\d{3}(?!=【我的博客】)");//匹配3個數字開頭後面不是"【我的博客】"

二、反向預搜索

pattern.Add("(?<=【我的博客】)\\d{3}");//匹配"【我的博客】"開頭後面是3個數字
pattern.Add("(?!<=【我的博客】)\\d{3}");//匹配不是"【我的博客】"開頭後面是3個數字

能夠看出來,當判斷條件在後面時,咱們用的是正向預搜索,反之則相反。

預搜索刮號內的內容不會匹配

來看看結果吧

複製代碼
pattern.ForEach(p =>
{
    MatchCollection matches = Regex.Matches(input, p);
    Console.WriteLine("Count:" + matches.Count);
    foreach (Match item in matches)
        //Console.WriteLine("Value:" + item.Groups[0].Value);
        Console.WriteLine("Value:" + item.Groups[0].Value + "=>" + item.Groups[1].Value);
});
複製代碼

實戰篇

1、Escape和Uescape

複製代碼
string input = @"\dhttp://www.tansea.cn2017";
string pattern = "\\d";
string replacement = "X";
string split = ":|/|\\.";
//\d是元符號,將元符號轉換成原義解釋
string escapePattern = Regex.Escape(pattern);
Console.WriteLine(Regex.Match(input, escapePattern).Groups[0].Value);//result=\d
//\\d是原義,將原義轉換成元符號解釋
string unescapePattern = Regex.Unescape(escapePattern);
Console.WriteLine(Regex.Match(input, unescapePattern).Groups[0].Value);//result=2
複製代碼

2、IsMatch

Regex.IsMatch(input, pattern);//是否找到匹配項

3、Match

Match match = Regex.Match(input, pattern);//返回匹配到的第一項
Console.WriteLine(match.Value);

4、Matches

MatchCollection matches = Regex.Matches(input, pattern);//返回匹配到的全部項
foreach (Match item in matches)
    Console.WriteLine(item.Value);

5、Replace

複製代碼
Console.WriteLine(Regex.Replace(input, pattern, replacement));//用指定的字符串替換匹配到的項
Console.WriteLine(Regex.Replace(input, pattern, m =>
{
    string result = string.Empty;
    switch (m.Value)
    {
        case "2": result = "貳"; break;
        case "0": result = "零"; break;
        case "1": result = "壹"; break;
        case "7": result = "柒"; break;
    }
    return result;
}));//用委託返回的字符串替換匹配到的項
複製代碼

6、Split

List<string> inputs = Regex.Split(input, split).ToList();//以匹配到的項的位置爲基本,拆分字符串
inputs.ForEach(i => Console.WriteLine(i));
相關文章
相關標籤/搜索