標籤:
概述
Regex,主要是用符號描述了一類特定的文本(模式)。而Regex引擎則負責在給定的字串中,尋找到這一特定的文本。
本文主要是列出常用的Regex符號,加以歸類說明。本文僅僅是快速理解了Regex相關元字元,作一個備忘,供以後理解更複雜運算式的參考,以後關於Regex的相關內容會持續更新本文。樣本語言用C#
概述
一般字元
字元集合
速記的字元集合
指定重複次數的字元
匹配位置字元
分支替換字元
匹配特殊字元
組,反向引用,非擷取的群組
貪婪與非貪婪
回溯與非回溯
正向預搜尋、反向預搜尋
最後
一般字元
最簡單的一種文本描述,就是直接給出要匹配內容。 如要在”Generic specialization, the decorator pattern, chains of responsibilities, and extensible software.” 找到pattern,那麼正則式就直接是”heels”即可
View Code
字元集合
將字元放在中括弧中,即為字元集合。通過字元集合告訴正則式引擎從字元集合中的字元,僅匹配出一個字元。
| 字元 |
匹配的字元 |
樣本 |
| [...] |
匹配括弧中的任一字元 |
[abc]可以匹配單個字元a,b或c,但不能匹配其它字元 |
| [^...] |
匹配非括弧中的任一字元 |
[^abc]可以匹配任一個除a,b,c的一個字元,如d,e,f |
比如單詞灰色gray(英)和grey(美),在一段文本中匹配出gray或grey,那麼通過正則式gr[ae]y 就可以了;又比如要在一段文本中找到me和my,正則式是m[ey]
我們還可以在字元集合中使用連字號 – 來表示一個範圍,比如 [0-9] 表示匹配一個0到9數字;[a-zA-Z] 表示匹配英文字母;[0-9 a-zA-Z]表示匹配一個0到9的數字或英文字母
View Code
速記的字元集合
我們常常要匹配一個數字,一個字母,一個空白符,雖然可以用普通的字元類來表示,但不夠方便,所以正則式提示了一些常用的字元集合的速記符
| 字元 |
匹配的字元 |
樣本 |
| \d |
從0到9的任何一個數字 |
\d\d 可以匹配72,但不能匹配me或7a |
| \D |
非數字元 |
\D\D 可以匹配me,但不能匹配7a或72 |
| \w |
任一個單詞字元,如A-Z, a-z, 0-9和底線 |
\w\w\w\w可以匹配aB_2,但不能匹配[email protected] |
| \W |
非單詞字元 |
\W 可以匹配@,但不能匹配a |
| \s |
任一空白字元,包括了定位字元,分行符號,斷行符號符,換頁符和垂直定位字元 |
匹配所有傳統的空白字元 |
| \S |
任一非空白字元 |
\S 可以匹配任一非空白字元,如~!@#& |
| . |
任一字元 |
匹配任一字元,分行符號除外 |
View Code
指定重複次數的字元
指定重複匹配前面的字元多少次:匹配重複的次數,不匹配內容。比如說,要在一系列電話號碼中找到以158開始的11位手機號,如果我們沒有學過下面的內容,Regex為158\d\d\d\d\d\d\d\d;但如果我們學習了下面的知識,則Regex為158\d{8}
| 字元 |
匹配的字元 |
樣本 |
| {n} |
匹配前面字元n次 |
x{2},可以匹配xx,但不能匹配xxx |
| {n,} |
匹配前面字元n次或更多 |
x{2,}可以2個或更多的x,比如可以匹配xx,xxx,xxxx,xxxxxx |
| {n,m} |
匹配前面字元最少n次,最多m次。如果n為0,則可以不指定 |
x{2,4},匹配了xx,xxx,xxxx,但不能匹配x,xxxxx |
| ? |
匹配前面的字元0次或1次,相當於{0,1} |
x? 匹配x或空 |
| + |
匹配前面的字元1次或多次, 相當於{1,} |
x+ 匹配x,xx,或xxx |
| * |
匹配前面的字元0次或多次 |
x* 匹配0個或多個x |
View Code
匹配位置的字元
現在我們已經學會了使用字元集合,字元集合的速記符來匹配大部分的文本了。但是如果我們遇到以下的情況,怎麼辦?
要求匹配文本的第一個單詞為google
要求匹配文本以bye結束
要求匹配文本每一行的第一個單詞為數字
要求匹配一個單詞以hel開頭
上面的這種匹配一個位置,但不匹配任何內容的需求很正常。在Regex中也提供了一些特殊的字元來匹配位置(不匹配內容)。如用^匹配文本的開始位置, 用$匹配文本的結束位置,\b匹配一個單詞的邊界
| 字元 |
匹配的字元 |
樣本 |
| ^ |
其後的模式必須在字串的開始處,如果是一個多行字串,應位於任一行的開始。對於多行文本(有斷行符號符),需要設定Multiline標識 |
|
| $ |
前面的模式必須在字串的結尾處,如果是一個多行字串,應該在任一行的末尾 |
|
| \b |
匹配一個單詞的邊界, |
|
| \B |
匹配一個非單詞的邊界,並不在一個單詞的開始或結尾處 |
|
| \A |
前面的模式必須在字串的開始,並忽略多行標識 |
|
| \z |
前面的模式必須在字串的末尾,並忽略多行標識 |
|
| \Z |
前面的模式必須在字串的末尾,或是位於分行符號前 |
|
View Code
分支替換字元
在字元集合中,我們可以在用中括弧來指定匹配中括弧中的任一字元,即模式中可以列出多種字元情景,被匹配的文本只要有符合其中的任一情景就可以被匹配出來。 那有沒有這樣的一種機制,同一個正則式中有多個模式,只有滿足其中的任一模式就可以被匹配出來。再配合分組,就可以把一個複雜的正則式分成多個相對簡單子的正則式來做。類似於邏輯符號OR的意思吧。
| 字元 |
匹配的字元 |
樣本 |
| | |
選擇匹配符,匹配前面或後面的任一模式 |
cat|mouse 可以匹配出cat 或mouse |
View Code匹配特殊字元
到現在,我們已經知道了字元集合,一些速記的字元集合,匹配位置的字元,指定匹配次數的字元,分支匹配。我們用的這些符號,在Regex中代表了各種特定的意義。那當我們要匹配這些字元本身,我們應該怎麼辦?在特殊字元前加上\, 以下是一些常用特殊字元的逸出字元的列表
| 字元 |
匹配的字元 |
樣本 |
| \\ |
匹配字元\ |
|
| \. |
匹配字元. |
|
| \* |
匹配字元* |
|
| \+ |
匹配字元+ |
|
| \? |
匹配字元? |
|
| \| |
匹配字元| |
|
| \( |
匹配字元( |
|
| \) |
匹配字元) |
|
| \{ |
匹配字元{ |
|
| \} |
匹配字元} |
|
| \^ |
匹配字元^ |
|
| \$ |
匹配字元$ |
|
| \n |
匹配字元n |
|
| \r |
匹配字元r |
|
| \t |
匹配字元t |
|
| \f |
匹配字元f |
|
| \nnn |
匹配一個三位八位元指定的ASCII字元,如\103匹配一個大寫的C |
|
| \xnn |
匹配一個二位十六進位數指定的ASCII字元,如\x43匹配C |
|
| \xnnnn |
匹配一個四位十六進位數指定的unicode字元 |
|
| \cV |
匹配一個控制字元,如,\cV匹配Ctrl+V |
|
View Code組,反向引用,非擷取的群組
組,可以用圓括弧,將Regex的部分括起來並獨立使用,在圓括弧之間的正則式叫做一個組。可以將匹配次數的字元和分支匹配字元應用到組。
1 樣本: public void Set, public void SetValue
正則式Set(Value)? , 其中(Value)是一個組,匹配次數的字元?將應用於整個組(Value),可以匹配到Set或SetValue
2 樣本:Out of sight, out of mind
正則式: “(out of) sight, \1 mind”
Regex引擎會將 “()”中匹配到的內容儲存起來,作為一個“組”,並且可以通過索引的方式進行引用。運算式中的“\1”,用於反向參考資料表達式中出現的第一個組。 同時在c#中,也可以通過組來訪問捕獲到的組的內容。注意,Groups[0]是整個匹配的字串,組的內容從索引1開始
View Code
3 可根據組名進行索引。使用以下格式為標識一個組的名稱(?<groupname>…)
正則式: “(?<Group1>out of) sight, \1 mind”
View Code
4在運算式外引用,對於索外用$索引,或組名用${組名}
樣本:Out of of sight, out of mind
正則式 “(?<Group1>[a-z]+) \1”
View Code
5非擷取的群組,在組前加上?: 因為有的組表達的僅僅是一個選擇替換,當我們不想用浪費儲存時,以用不捕獲該組
"(?:out of) sight"
View Code
| 字元 |
匹配的字元 |
樣本 |
| (?<groupname>exp) |
匹配exp,並捕獲文本到名稱為name的組裡 |
|
| (?:exp) |
匹配exp,不捕獲匹配的文本,也不給此分組分配組號 |
|
貪婪與非貪婪
Regex的引擎預設是貪婪,只要模式允許,它將匹配儘可能多的字元。通過在“重複描述字元(*,+等)”後面添加“?”,可以將匹配模式改成非貪婪。貪婪與非貪婪與指定重複次數的字元的內容密切相關。
| 字元 |
匹配的字元 |
樣本 |
| ? |
如果是跟在量詞(即指定匹配次數的字元)後面,那麼Regex則採用非貪婪模式 |
|
樣本 out of sight, out of mind
貪婪正則式 : .* of 輸出out of sight, out of
非貪婪正則式 : .*? of 輸出 out of
另外一個樣本
輸入:The title of cnblog is <h1>code changes the world</h1>
目標:匹配HTML標記
正則式1:<.+>
正則式1的輸出: <h1>code changes the world</h1>
正則式2:<.+?>
正則式2的輸出: <h1> </h1>
View Code回溯與非回溯
使用“(?>…)”方式進行非回溯聲明。由於Regex引擎的貪婪特性,導致它在某些情況下,將進行回溯以獲得匹配,請看下面的樣本:
樣本:Live for nothing, die for something
正則式(預設非回溯): “.*thing,” 輸出Live for nothing 。“.*”由於其貪婪特性,將一直匹配到字串的最後,隨後匹配“thing”,但在匹配“,”時失敗,此時引擎將回溯,並在“thing,”處匹配成功
正則式(回溯):”(?>.*)thing,” 匹配不到任何東西。由於強制非回溯,所以整個運算式匹配失敗
View Code
| 字元 |
匹配的字元 |
樣本 |
| (?>...) |
匹配組內運算式時,不回溯 |
|
正向預搜尋、反向預搜尋
匹配特定的模式,並聲明前面或後面的內容。意思跟匹配位置差不多
| 字元 |
匹配的字元 |
樣本 |
| (?=exp) |
左邊的模式後面必須緊跟著exp,聲明本身不作為匹配結果的一部分 |
|
| (?!exp) |
左邊的模式的後面不能緊跟著exp,聲明本身不作為匹配結果的一部分 |
|
| (?<=exp) |
右邊的模式的前面必須是exp,聲明本身不作為匹配結果的一部分 |
|
| (?<!exp) |
右邊的模式的前面不能是exp,聲明本身不作為匹配結果的一部分 |
|
View Code
最後
參考地址:
Regex30分鐘入門教程
Regular Expressions Tutorial
NET Framework Regular Expressions
.NET進階系列之一:C#Regex整理備忘
C#_Regex