正則表達式括號的作用
1、限制多選項的范圍 (Fri|1)st 這樣寫會匹配Frist或1st 如果去掉,則 Fri|1st就是匹配 Fri或1st
2、將若干個字符進行組合,受量詞的同時作用。例如 th+ 表示匹配 th thh thhh(h無數次),如果是(th)+,則匹配的是th thth ththth(th無數次)
3、反向引用,即前面括號匹配到的東西記憶與后面,常用於匹配重復單詞。
4、分組
常用元字符
代碼 說明
. 匹配除換行符以外的任意字符
\w 匹配字母或數字或下划線或漢字
\s 匹配任意的空白符
\d 匹配數字
\b 匹配單詞的開始或結束
^ 匹配行的開始
$ 匹配行的結束
常用反義元字符
代碼 說明
\W 匹配任意不是字母,數字,下划線,漢字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非數字的字符
\B 匹配不是單詞開頭或結束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou這幾個字母以外的任意字符
常用重復限定符
代碼 說明
* 重復零次或更多次
+ 重復一次或更多次
? 重復零次或一次
{n} 重復n次
{n,} 重復n次或更多次
{n,m} 重復n到m次
正則表達式之元字符
一、最易理解的元字符。
脫字符 ^ :表示匹配行首的文本
美元符 $ :表示匹配行尾的文本
例如:
^cat //匹配以c作為一行的第一個字符是c,然后是一個a,緊接着一個t的文本
以上正則表達式匹配的是:
例如一個行 catdogcat 上面正則表達式匹配第一個cat。
特殊正則說明:
^cat$ //匹配行開頭是cat,然后就是行末尾的cat,說白了就是一行中僅僅只包含cat的行,沒有其他字符。 ^$ //匹配行開頭,然后就是行末尾了,說白了就是匹配一個空行(沒有任何字符,也沒有空白字符) ^ //匹配行的開頭,每一行都匹配
下面用C#說明:
static void Main(string[] args) { Regex reg = new Regex("^cat"); reg.Match("catdog"); Console.WriteLine(reg.Match("catdog")); //輸出 cat Console.WriteLine(reg.Match("dogcat")); //輸出 空白(啥都不輸出) Regex reg2 = new Regex("cat$"); Console.WriteLine(reg2.Match("catdog")); //輸出 空白(啥都不輸出) Console.WriteLine(reg2.Match("dogcat")); //輸出 cat Console.ReadKey(); }
二、字符組
匹配若干字符之一
[] //字符串用中括號括起來,表示匹配其中的任一字符,相當於或的意思
例如:
gr[ea]y //匹配grey或gray
其中連字符 - 表示一個范圍,例如<h[1-6]> 與 <h[123456]>的作用一致。其他類似的還有[a-z],[A-Z]。
這里必須要注意的是只有在字符組內部連字符 - 才是元字符,否則它就只匹配普通的連字符 - 。
static void Main(string[] args) { Regex reg = new Regex("<h[1-6]>"); string str = "<div><h1>你在他鄉還好嗎?</h1></div>"; Console.WriteLine(reg.Match(str)); //輸出 <h1> Console.ReadKey(); }
三、排除型字符組
用[^...]取代[...]這個字符組就會匹配任何未列出的字符。
[^...] //[^...]表示匹配所有方括號里未列出的字符
例如:
r[^abc]r //匹配出rar,rbr,rcr之外的任意r*r文本
下面的例子要注意下,例如正則表達式 q[^u] 不會匹配 Qantas 和 Iraq 這又是為什么呢?
因為正則表達式是區分大小寫的。其次q[^u]要求q后面跟一個非u的字符,即必須包含一個字符。
static void Main(string[] args) { Regex reg = new Regex("a[^123456]"); Console.WriteLine(reg.Match("a1a2a3a4a5a6a7")); //輸出 a7 Console.ReadKey(); }
在特別強調,排除型字符組表示“匹配一個未列出的字符”而不是“不要匹配列出的字符”。區別在於前者必須要匹配一個。
另外還要強調一點,在[]里面是沒有元字符的,都代表本身的含義,例如[.]就表示匹配一個點.的意思。
四、點號.匹配任意字符
元字符.是用來匹配任意字符的字符組的漸變寫法。
. //匹配任意字符的字符組簡便寫法
例如:
.a //匹配 Aa 1a ga 等等
例子:
static void Main(string[] args) { Regex reg = new Regex(".c"); Console.WriteLine(reg.Match("abcdefg")); //輸出 bc Console.ReadKey(); }
五、多選結構
| 是一個非常簡捷的元字符,它的意思是或。依靠它,我們能夠把不同的子表達式組合成一個總的表達式,而這個總表達式又能夠匹配任意的子表達式。
| //或 多選分支 選擇兩者中的一個 注意|將左右兩邊分為兩部分,而不管左右兩邊有多長多亂
例如:
gray|grey //既可匹配gray又可匹配grey 相當於gr[ae]y
如果將|寫在中括號[]里面,那么 | 就不是元字符,它和a e一樣,只代表本身字符。
對於表達式gr(a|e)來說,括號是必須的,如果沒有括號,那么gra|ey的意思就成了 gra | ea 即匹配gry或匹配ey。
再比如 Frist|1st 與 (Fri|1)st 表示的是同一個意思
C#DEMO:
static void Main(string[] args) { Regex reg = new Regex("abc|def"); Console.WriteLine(reg.Match("bcdefg")); //輸出 def Console.ReadKey(); }
另外要特別注意下,下面的這個例子
^from|subject|date: 與 ^(from|subject|date): 之間的區別
對於前者:只能匹配 ^from 或 subject 或 date:
對於后者: 能夠匹配 ^from: 或 ^subject: 或 ^date:
六、忽略大小寫
當然忽略大小寫你可以用 [Aa]bc 取代 abc ,但是這樣不方便。正則表達式提供一個 -i 。用於忽略大小寫匹配。
之前寫的是 -i 后來發現是錯的,應該是?i (?i)放在前面就可以了
(?i) //用於忽略大小寫匹配
我測試過(?i)寫在前面,但是無法匹配,要忽略大小寫貌似要通過構造函數的屬性設定:
static void Main(string[] args) { Regex reg = new Regex("Abc",RegexOptions.IgnoreCase); Console.WriteLine(reg.Match("abcdefg")); //輸出 abc Console.ReadKey(); }
七、單詞分界符
\b 表示單詞分界符
\b //匹配單詞的開始或結束
代碼示例:
static void Main(string[] args) { Regex reg = new Regex(@"\bLove\b"); Console.WriteLine(reg.Match("I Love You!")); //輸出 Love Console.ReadKey(); }
八、可選項元素
? 代表可選項,把他加在一個字符的后面,就表示此處容許出現這個字符,不過它的出現並非匹配成功的必要條件。
? //跟在一個字符后面,容許此字符出現0次或1次
例如:
colou?r //可以匹配colour或color
C#Demo:
static void Main(string[] args) { Regex reg = new Regex(@"colou?r"); Console.WriteLine(reg.Match("what is color?")); //輸出 color Console.WriteLine(reg.Match("what is colour?")); //輸出 colour Console.ReadKey(); }
然后來說一下結合其他元字符使用的情況:
例如:
July|Jul 可縮短為 July?
4th|4 可縮短為 4(th)?
九、重復出現
加號+和星號*的作用與問號類似,的作用都是限定字符出現的次數。因此問號?加號+星號*這3個元字符統稱量詞。
? //可以出現0次或1次 + //至少要出現1次,可以出現無數次 * //可以出現0次或出現無數次
Demo:
static void Main(string[] args) { Regex reg = new Regex(@"colo*r"); Console.WriteLine(reg.Match("colooor")); //輸出 colooor Regex reg2 = new Regex(@"colo*r"); Console.WriteLine(reg2.Match("colr")); //輸出 colr Regex reg3 = new Regex(@"colo+r"); Console.WriteLine(reg3.Match("colr")); //輸出 空白(啥都不輸出,這就是+和*的區別了) Console.ReadKey(); }
十、規定重現次數的范圍:區間
{min,max} 大括號內的數字用於表示某字符允許出現的次數區間。
{min,max} //大括號內的數字用於表示某字符允許出現的次數區間。
C# Demo:
static void Main(string[] args) { Regex reg = new Regex(@"colo{3,5}r"); Console.WriteLine(reg.Match("colooor")); //輸出 colooor Regex reg2 = new Regex(@"colo{3,5}r"); Console.WriteLine(reg2.Match("coloor")); //輸出 空白(啥都不輸出) 至少3個,但是字符串里只有兩個,因此不符合 Console.ReadKey(); }
這里要記住,{}里面的參數不一定要寫全兩個,也可以僅僅寫一個,這樣代表僅僅匹配指定的字符數,例如\b{6}\b匹配剛剛6個字母的單詞。
{n,} 匹配n次或更多次, {5,} 匹配5次以上
十一、括號以及反向引用
前面已經說過括號的兩個作用:限制多選項的范圍,將若干字符組合為一個單元,受問號或星號之類的量詞作用。現在在來說一種括號的用法,分組,此東西具有記憶的功能,即在正則表達式內部仍然能夠回憶上次匹配到的是什么。這個東西用語言說不明白,書本上又是畫圖又是線的,這里僅僅用一個例子:
static void Main(string[] args) { Regex reg = new Regex(@"(\b[A-Za-z]+ +)\1\b"); Console.WriteLine(reg.Match("red color color red")); //輸出 color color Console.ReadKey(); }
例子解析:首先說明一下括號里面代表什么意思,
(\b[A-Za-z]+ +) 匹配單詞的開始,然后是大小寫字母至少1次,然后空格至少1次。說白了就是 空格然后是匹配不區分大小寫的一寸字母然后是任意個空格
OK,再來說下\1\b \b當然就是單詞的結尾了,那么\1呢?這個就是分組的作用了,\1代表的就是前面括號里面的東西,也就是一個單詞。
因此,整個正則表達式的意思是,匹配間隔了N個空格的重復的單詞。不懂也沒辦法了。
十二、神奇的轉義
\ 轉義符它的作用是使元字符失去它的意義,僅僅代表其日常輸入中字符的意義。
C#例子:
static void Main(string[] args) { Regex reg = new Regex(@".c"); Console.WriteLine(reg.Match("(acdefg")); //輸出 ac Regex reg2 = new Regex(@"\.c"); Console.WriteLine(reg2.Match("(acdefg")); //輸出 空白(啥都不輸出,說明.已失去了它元字符,代表任意字符的意義) Regex reg3 = new Regex(@"\.c"); Console.WriteLine(reg3.Match("(.cdefg")); //輸出 .c 它字表它自己,就匹配一個點.了 Console.ReadKey(); }
例如,我要匹配字符 . 字符* 就需要在前面加反斜杠,\. \*去除它元字符的含義。
一些需要轉義的字符列表 \ * + ? | { [ ( ) ^ $ . # 和 空白
十三、一些其他的元字符
\w 匹配字母,漢字,數字,下划線
\W 匹配非字母,非漢字,非數字,非下划線
\s 匹配空白符
\S 匹配非空白符
\d 匹配數字
\D 匹配非數字
static void Main(string[] args) { Regex reg = new Regex(@"\w?"); MatchCollection mcoll = reg.Matches("@你s_5"); foreach (Match mat in mcoll) { Console.WriteLine(mat.Value); //輸出 空白 你 s _ 5 果然是匹配漢字、字母、下划線、數字 } Regex reg2 = new Regex(@"\s"); MatchCollection mcoll2 = reg2.Matches("abc def"); foreach (Match mat in mcoll2) { Console.WriteLine(mat.Index); //輸出 3 這里要注意一個問題了,在用Matches時,當匹配不到時,會返回Empty,因此,可以認為每次都是匹配到的,但是匹配到空 } Regex reg3 = new Regex(@"\d"); //匹配數字 Match m2 = reg3.Match("abc5def"); Console.WriteLine(m2.Value); //輸出 5 //以下代碼為完全復制上面的代碼,只是改了命名與正則 Regex reg4 = new Regex(@"\W?"); MatchCollection mcoll3 = reg4.Matches("@你s_5"); foreach (Match mat in mcoll2) { Console.WriteLine(mat.Value); //輸出 @ } Regex reg5 = new Regex(@"\S"); //匹配非空格 MatchCollection mcoll4 = reg5.Matches("abc def"); foreach (Match mat in mcoll4) { Console.WriteLine(mat.Value); //輸出 abcdef 這里要注意一個問題了,在用Matches時,當匹配不到時,會返回Empty,因此,可以認為每次都是匹配到的,但是匹配到空 } Regex reg6 = new Regex(@"\D"); //匹配非數字 Match m3 = reg6.Match("abc5def"); Console.WriteLine(m3.Value); //輸出 a Match就是只匹配第一個 Console.ReadKey(); }
還有,既然學習了正則表達式,就千萬不要忘記這一個用法: