正則表示式 第五篇:C# 正則表示式
本文整理C#正則表示式的元字元,正則表示式是由字元構成的表示式,每個字元代表一個規則,表示式中的字元分為兩種型別:普通字元和元字元。普通字元是指字面含義不變的字元,按照完全匹配的方式匹配文字,而元字元具有特殊的含義,代表一類字元。
把文字看作是字元流,每個字元放在一個位置上,例如,正則表示式 “Room\d\d\d”,前面四個字元Room是普通字元,後面的字元\是轉義字元,和後面的字元d組成一個元字元\d,表示該位置上有任意一個數字。
用正則表示式的語言來描述是:正則表示式 “Room\d\d\d”共捕獲7個字元,表示“以Room開頭、以三個數字結尾”的一類字元,我們把這一類字元稱作一個模式(Pattern),也稱作是一個正則。
一,轉義字元
轉義字元是\,把普通字元轉義為具有特殊含義的元字元,常用的轉義字元有:
- \t:水平製表符
- \v:垂直製表符
- \r:回車
- \n:換行
- \\:表示字元 \,也就說,把轉義字元 \ 轉義為普通的字元 \
- \":表示字元 ",在C#中,雙引號用於定義字串,字串包含的雙引號用 \" 來表示
二,字元類
在進行正則匹配時,把輸入文字看作是有順序的字元流,字元類元字元匹配的物件是字元,並會捕獲字元。所謂捕獲字元是指,一個元字元捕獲的字元,不會被其他元字元匹配,後續的元字元只能從剩下的文字中重新匹配。
常用的字元類元字元:
- [ char_group]:匹配字元組中的任意一個字元
- [^char_group]:匹配除字元組之外的任意一個字元
- [first-last]:匹配從first到last的字元範圍中的任意一個字元,字元範圍包括first和last。
- . :萬用字元,匹配除\n之外的任意一個字元
- \w:匹配任意一個單詞(word)字元,單詞字元通常是指A-Z、a-z和0-9
- \W:匹配任意一個非單詞字元,是指除A-Z、a-z和0-9之外的字元
- \s:匹配任意一個空白字元
- \S:匹配任意一個非空白字元
- \d:匹配任意一個數字字元
- \D:匹配任意一個非數字字元
注意,轉義字元也是字元,在進行正則匹配時,也會捕獲字元。
三,定位符
定位符,根據字串中的當前位置來判斷匹配是否成功,定位符匹配的是位置、不會消耗字元,是零寬的(寬度為0)。
- ^:預設情況下,匹配字串的開始位置;在多行模式下,匹配每行的開始位置;
- $:預設情況下,匹配字串的結束位置,或 字串結尾的\n之前的位置;在多行模式下,匹配每行結束之前的位置,或者每行結尾的\n之前的位置。
- \A:匹配字串的開始位置;
- \Z:匹配字串的結束位置,或 字串結尾的\n之前的位置;
- \z:匹配字串的結束位置;
- \G:匹配上一個匹配結束的位置;
- \b:匹配一個單詞的開始或結束的位置;
- \B:匹配一個單詞的中間位置;
四,量詞、貪婪和懶惰
量詞是指限定前面的一個正則出現的次數,量詞分為兩種模式,貪婪模式和懶惰模式,貪婪模式是指匹配儘可能多的字元,而懶惰模式是指匹配儘可能少的字元。預設情況下,量詞是貪婪模式,在量詞的後面加上?來啟用懶惰模式。
- *:出現0次或多次
- +:出現1次或多次
- ?:出現0次或1次
- {n}:出現n次
- {n,}:出現至少n次
- {n,m}:出現n到m次
注意,出現多次是指前面的元字元出現多次,例如,\d{2} 等價於 \d\d,只是出現兩個數字,不要求兩個數字是相同的。要表示相同的兩個數字,必須使用分組來實現。
五,分組和捕獲字元
() 括號不僅確定表示式的範圍,還建立分組,()內的表示式就是一個分組,引用分組表示兩個分組匹配的文字是完全相同的。
(pattern)
所謂捕獲字元是指:一個元字元捕獲的字元,不會被其他元字元匹配,後續的元字元只能從剩下的文字中重新匹配。
1,分組編號和命名
預設情況下,每個分組自動分配一個組號,規則是:從左向右,按分組左括號的出現順序進行編號,第一個分組的組號為1,第二個為2,以此類推。也可以為分組指定名稱,例如,為分組指定名稱的格式是:
(?<
name>
pattern)
通常來說,分組分為命名分組和編號分組,引用分組的方式有:
- 通過分組名稱來引用分組:\k<name>
- 通過分組編號來引用分組:\number
注意,分組只能後向引用,也就是說,從輸入文字的左邊開始,分組必須先定義,然後才能引用。
在正則表示式裡引用分組的語法為“\number”,比如“\1”代表與分組1 匹配的子串,“\2”代表與分組2 匹配的字串,以此類推。
例如,對於 "<(.*?)>.*?</\1>" 可以匹配 <h2>valid</h2>,在引用分組時,分組對應的文字是完全相同的。
2,分組構造器
分組構造方法如下:
- (pattern):捕獲匹配的子表示式,併為分組分配一個組號
(?<
name>
pattern):把匹配的子表示式捕獲到命名的分組中
(?:pattern):非捕獲的分組,並未分組分配一個組號
(?>
pattern):貪婪分組
3,貪婪分組
貪婪分組也稱作非回溯分組,該分組禁用了回溯,正則表示式引擎將盡可能多地匹配輸入文字中的字元。如果無法進行進一步的匹配,則不會回溯嘗試進行其他模式匹配。
(?> pattern )
六,零寬斷言
零寬是指寬度為0,匹配的是位置,因為匹配的子串不會出現在匹配結果中,而斷言是指判斷的結果,只有斷言為真,才算匹配成功。
對於定位符,可以匹配一句話的開始、結束(^ $)或者匹配一個單詞的開始、結束(\b),這些元字元只匹配一個位置,指定這個位置滿足一定的條件,而不是匹配某些字元,因此,它們被成為 零寬斷言。所謂零寬,指的是它們不與任何字元相匹配,而匹配一個位置;所謂斷言,指的是一個判斷,正則表示式中只有當斷言為真時才會繼續進行匹配。零寬斷言可以精確的匹配一個位置,而不僅僅是簡單的指定句子或者單詞。
正則表示式把文字看作從左向右的字元流,向右叫做後向(Look behind),向左叫做前向(Look ahead)。對於正則表示式,只有當匹配到指定的模式(Pattern)時,斷言為True,叫做肯定式,把不匹配模式為True,叫做否定式。
按照匹配的方向和匹配的定性,把零寬斷言分為四種類型:
(?=
pattern):前向、肯定斷言
(?!
pattern):前向、否定斷言
(?<=
pattern):後向、肯定斷言
(?<!
pattern):後向、否定斷言
1,前向肯定斷言
前向肯定斷言定義一個模式必須存在於文字的末尾(或右側),但是該模式匹配的子串不會出現在匹配的結果中,前向斷言通常出現在正則表示式的右側,表示文字的右側必須滿足特定的模式:
(?=
subexpression)
使用前向肯定斷言可以定一個模糊匹配,字尾必須包含特定的字元:
\b\w+(?=\sis\b)
對正則表示式進行分析:
- \b:表示單詞的邊界
- \w+:表示單詞至少出現一次
- (?=\sis\b):前向肯定斷言,\s 表示一個空白字元, is 是普通字元,完全匹配,\b 是單詞的邊界。
從分析中,可以得出,匹配該正則表示式的文字中必須包含 is 單詞,is是一個單獨的單詞,不是某一個單詞的一個部分。舉個例子
Sunday is a weekend day 匹配該正則,匹配的值是Sunday,而The island has beautiful birds 不匹配該正則。
2,後向肯定斷言
後向肯定斷言定義一個模式必須存在於文字的開始(或左側),但是該模式匹配的子串不會出現在匹配的結果中,後向斷言通常出現在正則表示式的左側,表示文字的左側必須滿足特定的模式:
(?<= subexpression )
使用後向肯定斷言可以定一個模糊匹配,字首必須包含特定的字元:
(?<=\b20)\d{2}\b
對正則表示式進行分析:
- (?<=\b20):後向斷言,\b表示單詞的開始,20是普通字元
- \d{2}:表示兩個數字,數字不要求相同
- \b:單詞的邊界
該正則表示式匹配的文字具備的模式是:文字以20開頭、以兩個數字結尾。
參考文件:
C#中正則表示式的使用
C# 正則表示式 菜鳥教程
Regular Expression Language - Quick Refer