(轉載) 正則表達式 經典教程

  • 35836
  • 0

摘要:(轉載) 正則表達式 經典教程

作者:ET Dreams http://blog.csdn.net/etmonitor/

Regular Expressions (1) ---- What is Regular Expressions?

 

正則表達式是常見常忘,所以還是記下來比較保險,於是就有了這篇筆記。

希望對大家會有所幫助。J

1是正表達式.............................................................................................................................................................. 2

2表達式的起源............................................................................................................................................................. 2

3. 表達式使用........................................................................................................................................................ 3

3.1基本.............................................................................................................................................................................. 3

3.1.1普通字符..................................................................................................................................................................... 3

3.1.2非打印字符................................................................................................................................................................. 3

3.1.3特殊字符..................................................................................................................................................................... 3

3.1.4字符集........................................................................................................................................................................... 4

3.1.5在字符集中使用元字符............................................................................................................................................. 5

3.1.6預定義字符集.............................................................................................................................................................. 5

3.1.7 限定符........................................................................................................................................................................... 6

3.1.8定位符........................................................................................................................................................................... 6

3.1.9 「.」元字符...................................................................................................................................................................... 7

3.1.10 「|」表示選擇.......................................................................................................................................................... 8

3.1.11()表示分組.................................................................................................................................................. 8

3.1.12?的補充說明.......................................................................................................................................................... 8

3.1.13給正則表達式添加注......................................................................................................................................... 8

3.1.14操作符的運算優先級............................................................................................................................................... 8

3.2 級話題............................................................................................................................................................................... 9

3.2.1反向引用..................................................................................................................................................................... 9

3.2.2在正則表達式中指定模式option........................................................................................................................... 9

3.2.3 Lookaround斷言..................................................................................................................................................... 10

4. 表達式基本法索引............................................................................................................................................ 11

5.   表達式高級語法索引.............................................................................................................................................. 15

6.   參考資料................................................................................................................................................................................. 17

7.   推薦工具................................................................................................................................................................................. 17

 

 

 

 

 

 

 

 

 

 

 

 

 

1是正表達式

 

簡單的說,正則表達式是一種可以用於文字模式匹配和替換的強有力的工具。是由一系列普通字符和特殊字符組成的能明確描述文本字符串的文字匹配模式。

正 則表達式並非一門專用語言,但也可以看作是一種語言,它可以讓用戶通過使用一系列普通字符和特殊字符構建能明確描述文本字符串的匹配模式。除了簡單描述這 些模式之外,正則表達式解釋引擎通常可用於遍歷匹配,並使用模式作為分隔符來將字符串解析為子字符串,或以智能方式替換文本或重新設置文本格式。正則表達 式為解決與文本處理有關的許多常見任務提供了有效而簡捷的方式。

正則表達式具有兩種標準:

·         基本的正則表達式(BRE – Basic Regular Expressions)

·         擴展的正則表達式(ERE – Extended Regular Expressions)

ERE包括BRE功能和另外其它的概念。

 

正則表達式目前有兩種解釋引擎:

·         基於字符驅動(text-directed engine)

·         基於正則表達式驅動(regex-directed engine)

Jeffery Friedl把它們稱作DFANFA解釋引擎。

 

約定:

為了描述起來方便,在本文中做一些約定:

1.      本文所舉例的所有表達時都是基於NFA解釋引擎的。

2.      正則表達式,也就是匹配模式,會簡寫為Regex

3.      Regex的匹配目標,也就是目標字符串,會簡寫為String

4.      匹配結果用會用黃色底色標識。

5.      1\+1=2 括起來的表示這是一個regex

6.      舉例會用以下格式:

Regex

Target String

Description

test

This is a test

會匹配testtestcase

 

2表達式的起源

正則表達式的祖先可以一直上溯至對人類神經系統如何工作的早期研究。Warren McCulloch Walter Pitts 這兩位神經生理學家研究出一種數學方式來描述這些神經網絡。

1956 , 一位叫 Stephen Kleene 的美國數學家在 McCulloch Pitts 早期工作的基礎上,發表了一篇標題為神經網事件的表示法的論文,引入了正則表達式的概念。正則表達式就是用來描述他稱為正則集的代數的表達式,因此採用正則表達式這個術語。

隨後,發現可以將這一工作應用於使用Ken Thompson 的計算搜索算法的一些早期研究,Ken ThompsonUnix 的主要發明人。正則表達式的第一個實用應用程序就是 Unix 中的qed 編輯器。從那時起直至現在正則表達式都是基於文本的編輯器和搜索工具中的一個重要部分。具有完整語法的正則表達式使用在字符的格式匹配方面上,後來被應用到熔融信息技術領域。自從那時起,正則表達式經過幾個時期的發展,現在的標準已經被ISO(國際標準組織)批准和被Open Group組織認定。

3. 表達式使用

最簡單的正則表達式相信大家都已熟悉並且經常使用,那就是文字字符串。特定的字符串可通過文字本身加以描述;像 test這樣的Regex模式可精確匹配輸入的字符串test,但是它也可以匹配this is a testcase,這就不是我們想要得結果。

當然,使用正則表達式匹配等於它自身的精確字符串是沒有價值的實現,不能體現正則表達式的真正作用。但是,假如要查找的不是test,而是所有以字母 t 開頭的單詞,或所有4個字母的單詞,那該怎麼辦?這超出了文字字符串的合理範圍。所以我們才需要深入地研究正則表達式。

3.1基本

雖然正則表達式並非一門專用語言,但它也有一些特殊的規定,也可以稱之為基本語法。

正則表達式是由普通字符(例如字符 a z)以及特殊字符(稱為元字符)組成的文字模式。該模式描述在查找文字主體時待匹配的一個或多個字符串。正則表達式作為一個模板,將某個字符模式與所搜索的字符串進行匹配。

構造正則表達式的方法和創建數學表達式的方法一樣。也就是用多種元字符與操作符將小的表達式結合在一起來創建更大的表達式。

可以通過在一對分隔符之間放入表達式模式的各種組件來構造一個正則表達式。

3.1.1普通字符

由所有那些未顯式指定為元字符的打印和非打印字符組成。這包括所有的大寫和小寫字母字符,所有數字,所有標點符號以及一些符號。

3.1.2非打印字符

非打印字符也是普通字符,單獨列出來便於參考。

Symbol

Description

\cx

匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回符。x 須為 A-Z a-z 之一。否,將 c 視為一個原 'c' 字符。

\f

匹配一個換頁符。等價於 \x0c \cL

\n

匹配一個行符。等價於 \x0a \cJ

\r

匹配一個回符。等價於 \x0d \cM

\s

匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]

\S

匹配任何非空白字符。等價於 [^ \f\n\r\t\v]

\t

匹配一個製表符。等價於 \x09 \cI

\v

匹配一個垂直製表符。等價於 \x0b \cK

 

Regex中可以使用非打印字符。\t會匹配一個tab字符(ASC||)\r 會匹配一個回車(0x0D)\n 會匹配一個換行符(0x0A)。應該注意的是:Windows使用\r\n表示一行的結束,而UNIX使用\n

同樣,我們可以在Regex中使用16進制的ASCⅡ碼或者ANSI標準碼。在拉丁語中,版權符號的代碼是0xA9,所以我們也可以這樣來匹配版權符號 \xA9 。另外一個匹配tab的寫法是:\x09 。但是注意,第一位的「0」必須去掉。

 

3.1.3特殊字符

特殊字符也叫做元字符,保留字符(Metacharactor),在Regex中表示特殊的意義,大部分的意思在不同的上下文中的意義是不同的,這裡只列出最普遍的意義。

特殊字符共有11個:

Symbol

Description

$

匹配入字符串的尾位置。如果置了 RegExp 象的 Multiline 屬性, $ 也匹配 '\n' '\r'要匹配 $ 字符本身,使用 \$

( )

標記一個子表達式的始和束位置。子表達式可以取供以後使用。要匹配些字符,使用 \( \)

*

匹配前面的子表達式零次或多次。要匹配 * 字符,使用 \*

+

匹配前面的子表達式一次或多次。要匹配 + 字符,使用 \+

.

匹配除行符 \n之外的任何字符。要匹配 .使用 \

[

標記一個中括號表達式的始。要匹配 [使用 \[

?

匹配前面的子表達式零次或一次,或指明一個非婪限定符。要匹配 ? 字符,使用 \?

\

將下一個字符標記為或特殊字符、或原字符、或反向引用、或八轉義符。例如, 'n' 匹配字符 'n''\n' 匹配行符。序列 '\\' 匹配 "\",而 '\(' 匹配 "("

^

匹配入字符串的始位置,除非在方括號表達式中使用,此它表示不接受字符集合。要匹配 ^ 字符本身,使用 \^

{

標記限定符表達式的始。要匹配 {使用 \{

|

指明兩之間的一個選擇。要匹配 |,請使用 \|

 

在元字符前加 \ 轉義符,可以把特殊字符當作普通字符來使用。

比如:如要要匹配 1+1=2 ,正確的正則表達式應該為1\+1=2。否則, + 會被當作特殊字符對待。

除了特殊字符,所有的其他字符都不應該加 \ 。因為 \ 也是一個特殊字符。\ 和普通字符組合在一起也可以創造一種特殊的意義。比如 \d 表示匹配所有的數字。

作為程序員,單引號和雙引號不是特殊字符會也許讓我們感到很驚訝。但這是正確的。因為我們在編程的時候,編程語言會知道引號之間的哪些字符表示特殊意義,編譯器在把字符串x傳遞給regex解釋引擎之前,會把它們處理成regex。比如,在C#中,如果我們要匹配  1\+1=2 ,在程序中我們要這樣寫: 「1\\+1=2」 C#編譯器會把 「\\」 ,處理為一個「\」  。同樣,如果要匹配 C:\Temp ,首先,正則表達式要這樣寫 C:\\Temp,然後在程序中我們應該這樣寫:「 C:\\\\temp」

3.1.4字符集

            字符集描述了一組字符,Regex解釋器會認為匹配字符集中的一個字符就可以認為匹配成功。

字符集用[ ]括起來即可。

            比如gr[ae]y就可以匹配gray或者grey

            字符集只能匹配一個字符,gr[ae]y就不能和graey匹配。字符集中的字符順序是任意的,得到的結果都是唯一的。

            可以在字符集中用連字符「-」來表示一個範圍。[0-9]的結果和[0123456789]的匹配結果都是相同的。字符集中的範圍可以有多種。比如[0-9a-fA-F]表示匹配所有的16進制,包括大小寫。也可以把範圍和單個字符組合在一起用,[0-9a-fxA-FX]表示匹配所有的16進制或者一個字符X。字符集的順序不會影響結果。

            在字符集的開始標誌「[」後面加上一個「^」符號,表示否定,表示匹配除字符集中定義的字符以外的所有字符。包括非打印字符和行結束符。

            注意:字符集匹配的一個字符,而不是一個位置。所以。q[^u]的意義不是「q後面的字符不是u」。而是「q後面的字符可以是除了u以外的所有字符

            q[^u]不會和Iraq匹配。

但是會和Iraq is a country匹配,因為q後面的空格字符是一個不是u的字符

3.1.5在字符集中使用元字符

字符集中的元字符只能是 『]』, 『\』, 『^』, 『-『

其他元字符在字符集中都失去了特殊意義,表示的只是一個普通字符。也不需要用加「\」

比如:

匹配一個「*」或者「+」,用[*+]就足夠了。即使給他們加上「\」regex解釋器也會把他們忽略掉。

 

四種特殊字符的處理:

在字符集中要表示「]」「^」「-」需要在後面加上轉義符「\」,來表示它們代表的分別是普通字符「]」「^」「-」

也可以把它們放在一個不能表示特殊意義的位置,後一個方法比較好,因為他們不會影響可讀性。

  • 「^」

要想匹配一個「^」,可以把它放在除了緊跟「[」的任意一個位置。

Regex

String

Description

[x^]

A string with x and ^.

匹配x或者「^」

 

  •  「]」

可以把「]」放在緊跟著「[」的位置,或者使用否定字符集。

Regex

String

Description

[]x]

A string with x and ]

匹配x或者「]」

[^]x]

A string with x and ]

匹配除了x」] 」以外的所有字符

  •  「\」

要想把「\」當作一個普通字符來匹配,而不是一個特殊字符,必須把「\」再用一個「\」括起來。

Regex

String

Description

[\\x]

A string with x and \

匹配x或者「\」

 

  •  「-」

連字符可以放在緊跟著「[」的後面,或者正好「]」的前面,或者緊跟著「^」的後面。

Regex

String

Description

[-x]

A string with x and -

匹配x或者「-」

[x-]

A string with x and -

匹配x或者「-」

3.1.6預定義字符集

因為很多字符集是經常使用的,所以Regex解釋器預定義了一些常用字符集:

Regex

Meaning

Description

\d

[0-9]

所有數字

\w

[a-zA-Z]

表示所有的字符,和文化字體有關

\s

[ \t\r\n]

空格,回車和tab。和文化字體有關

 

預訂一字符集可以既可以用在字符集裡面,也可以用在字符集外面。

Regex

String

Description

\s\d

1<space>+<space>2<space>=<space>3

匹配後面緊跟著一個數字的空白符

[\s\d]

1<space>+<space>2<space>=<space>3

匹配一個單獨的字符或者一個數字或者一個空白符

[\da-fA-F][0-9a-fA-F]的匹配結果是一樣的。

 

同樣,在預定義字符集前面加一個「^」符號表示否定。它們也有預先定義好的表示:

Regex

Meaning

Description

\D

[^\d]

非數字

\W

[^\w]

非字符,和文化字體有關

\S

[^\s]

非空格,回車和tab。和文化字體有關

 

「[]」使用否定預訂一字符集時要特別心。[\D\S]不等於[\^d\s][\^d\s]會匹配除了數字和空白符以外的所有字符。而[\D\S]會匹配要麼不是一個數字,要麼是空白符。因為數字不是空白符,空白符也不是數字,所以[\D\S]會匹配任意的字符。

3.1.7 限定符

限定符提供了一種簡單方法,用於指定在模式中允許特定字符或字符集自身重複出現的次數。限定符始終引用限定符前(左邊)的模式,通常是單個字符,除非使用括號創建模式組。

限定符有*+?{n}{n,}{n,m}6種。

Symbol

Description

Description

?

0次獲1

 

*

0次或n

 

+

1次或n

 

{min, max}

最少min次,最多max

Max必須大於等於min

{min<不指定> }

最少min次,或者n

 

{min}

精確的重複min

 

在字符集後面使用 「?」」*」」+」,表示重複。會重複整個的字符集,而不是重複匹配的那個字符。

Regex

String

意義

[0-9]+

846111

匹配數字

([0-9))+

846111

匹配數字相同的數字

[0-9]+會匹配846,也會匹配111

如果想要重複的只是匹配的那個字符,而不是整個字符集,則必須使用反向引用

([0-9])\1+ 只會匹配111,而不會匹配846

(第二部分高級話題會講道)

如果目標string 811116。則1111會被匹配。如果不想這樣,則需要使用

lookaheadlookbehind

(第二部分高級話題會講道)

3.1.8定位符

到現在為止,我們已經熟悉了普通字符、特殊字符(元字符)和字符集。在這兩種情況下,Regex匹配的都是一個字符。

定位符是另外一種,它不匹配字符,相反,它匹配的是一個位置。

定位符有幾種:

Regex

Function

Description

^

第一個字符之前的位置

包含換行符

$

最後一個字符後面的位置

包含換行符

\A

總是匹配string的第一個位置

不包含換行符

\Z

總是匹配string的最後一個位置

不包含換行符

 

Regex

String

意義

^

Abc

匹配A之前的位置

$

Abc

匹配c後面的位置

^A

Abc

匹配A

^b

Abc

不能匹配

c$

Abc

匹配c

A$

Abc

不能匹配

 

詞的邊界

還有一種定位符匹配的是一個詞(word)的邊界。用\b表示。

詞(word)是由可以組成詞的字符組成(「word characters」),「word characters」就是可以組成詞的字符,不包括非打印字符和回車換行。

有四種不同的位置被認為是詞的邊界:

  1. 第一個字符之前的位置,如果第一個字符是一個「word character」
  2. 最後一個字符之後的位置,如果最後一個字符是一個「word character」
  3. 介於詞和非詞之間的緊跟著詞的位置。
  4. 介於非詞和詞之間的緊跟著非詞的位置

所有的word characters都可以用\w來表示。

所有的non-word characters都可以用\W來表示。

 

\b匹配一個詞的邊界。

\B表示一個非詞的邊界的位置,它能匹配任意一個不是次的邊界的位置。

3.1.9 「.」元字符

在正則表達式中,「.」是用的最多的一個元字符,同時,它也是最容易用錯的一個。所以我們單獨來講。

「.」幾乎匹配任何字符。唯一的一個例外是換行符。

這個例外存在是有歷史原因的。第一個用正則表達式的工具是基於換行符的。它從文件中讀取一行字符,然後用去匹配。因為在這些工具中,string中永遠不可能有換行符,所以「.」也永遠不會和換行符匹配。

現代的工具可以用正則表達式去和很大的一個string甚至整個文件去匹配。所以現在的Regex解釋器都含有一個選項,激活以後就可以讓「.」去匹配所有的字符,包括換行符。

 「.」是一個非常強大的元字符。它可以讓我們偷懶。但是我們要慎重的使用。我們看一個例子:

我們要匹配一個mm/dd/yy的格式的日期。但是我們可以讓用戶指定日期的分割符。一個簡單的Regex是:\d\d.\d\d.\d\d這個看起來可以實現。它會很好的匹配04/09/07。問題是: 04409407也會被匹配。因為第三個4和第五個4都會被「.」匹配。這不是我們想要得結果。

\d\d[-/.]\d\d[-/.]\d\d是一個比上面的好的一個方法,用戶可以指定「-」,「.」,「/」作為日期的分割符。因為.在字符集中不表示一個特殊字符,所以我們不需要在.之前加」\」

但這個方法還不完美,它會匹配 99/99/99 , [0-1]\d[-/.][0-3]\d[-/.]\d\d也許會好一些。雖然它仍舊會匹配19/39/99, 方法夠用就好了,不必追求完美,如果這個是用來驗證用戶需求,可能還需要改進,如果只是用來分析一段code,或許已經足夠了。

如果我們要匹配一段帶雙引號的字符串。聽起來很容易,我們可以在兩個雙引號之間放任意多個任意字符。Regex可能會這麼寫:「.*」,這個會匹配put  a 「string」 between double quotes.結果是對的,但是如果去匹配「"string one」 and 「string two」」則得到的結果會是 「string one」 and 「string two」 。這不是我們要的結果。

所以這裡我們可以用否定字符集來代替「[^」\r\n]*」

3.1.10 「|」表示選擇

前面已經講過,用字符集可以匹配很多字符其中的一個,替換的作用稍有不同。

如果需要匹配 cat 或者 dog,可以這樣寫:cat|dog,也可以添加很多:cat|dog|mouse|fish

但是注意:「|」是正則表達式中優先級最低的操作符。Regex解釋器在匹配的時候,要麼匹配「|」左邊的所有,要麼匹配「|」右邊的所有。

3.1.11()表示分組

可以使用圓括號來限制選擇的範圍。

上面的例子,如果想要限制替換,可以使用()符號。

比如:

如果我們要匹配整個詞而不是一個詞的一部分。Regex可以這樣寫:\b(cat|dog)\b

這告訴regex解釋器先去尋找一個邊界,然後要麼是cat,要麼是dog,然後在去尋找一個邊界。如果忽略掉括號,regex解釋器會這樣來匹配:要麼是cat跟在一個邊界的後面,要麼是dog後面有一個邊界。

3.1.12?的補充說明

除了表示重複之外,還表示可選。

例如:colou?r,會匹配colorcolour

用括號括起來的表示這組是一個可選的項目。

例如:Nov(ember)?會匹配NovNovember

 

標記起來,等於告訴regex解釋器有兩種選項:要麼匹配括起來的,要麼不匹配。但是,Regex解釋器總會首先去匹配括起來的部分,只有當這個失敗了,才會當做忽略處理。

效果就是,如果用Feb 23(rd)?去匹配Today is Feb 23rd, 2004,結果總是Feb 23rd,而不是Feb 23

 也稱作懶元字符」,因為它總是儘可能的少的去匹配。

3.1.13給正則表達式添加注

可以這樣給正則表達式添加註釋:

?#comment here

3.1.14操作符的運算優先級

Symbol

Function

Memo

\

轉義符

 

(), (?:), (?=), []

括號

 

*, +, ?, {n}, {n,}, {n,m}

限定符

 

^, $, \anymetacharacter

定位符

 

|

 

 

3.2 級話題

裡會討論一些稍微複雜一些的主,比如backreference(反向引用)lookroundifelsethen等等。

3.2.1反向引用

()除了把regex括起來以外,還可以創建反向引用。對一個正則表達式模式或部分模式兩邊添加圓括號將導致相關匹配存儲到一個臨時緩衝區中,所捕獲的每個子匹配都按照在正則表達式模式中從左至右所遇到的內容存儲。存儲子匹配的緩衝區編號從 1 開始,連續編號直至最大 99 個子表達式。每個緩衝區都可以使用 '\n' 訪問,其中 n 為一個標識特定緩衝區的一位或兩位十進制數。
  可以使用非捕獲元字符 '?:', '?=', or '?!' 來忽略對相關匹配的保存。

例如:

Set(Value)?會匹配SetSetValue。第一種情況下,\1的反向引用會是空,因為set沒有匹配value。第二種情況下,\1的反向引用的值會變為value

如果不想創建反向引用,可以使用特殊符號,比如Set(?:Value)?

使用反向引用

例如:我們要匹配一個html標記,和兩個標記之間的內容。

我們可以這樣寫:<([A-Z][A-Z0-9]*)[^>]*>.*?</\1>

首先創建一個[A-Z][A-Z0-9]的引用,然後後面用到這個引用。

注意:引用中不能引用自己。

 

正則表達式一個最重要的特性就是將匹配成功的模式的某部分進行存儲供以後使用這一能力。請回想一下,對一個正則表達式模式或部分模式兩邊添加圓括號將導致這部分表達式存儲到一個臨時緩衝區中。可以使用非捕獲元字符 '?:', '?=', or '?!' 來忽略對這部分正則表達式的保存。

所捕獲的每個子匹配都按照在正則表達式模式中從左至右所遇到的內容存儲。存儲子匹配的緩衝區編號從 1 開始,連續編號直至最大 99 個子表達式。每個緩衝區都可以使用 '\n' 訪問,其中 n 為一個標識特定緩衝區的一位或兩位十進制數。

反向引用一個最簡單,最有用的應用是提供了確定文字中連續出現兩個相同單詞的位置的能力。請看下面的句子:

Is is the cost of of gasoline going up up?

根據所寫內容,上面的句子明顯存在單詞多次重複的問題。如果能有一種方法無需查找每個單詞的重複現象就能修改該句子就好了。下面的正則表達式就可以實現這一功能。

\b([a-z]+) \1\b

在這個示例中,子表達式就是圓括號之間的每一項。所捕獲的表達式包括一個或多個字母字符,即由[a-z]+ 所指定的。該正則表達式的第二部分是對前面所捕獲的子匹配的引用,也就是由附加表達式所匹配的第二次出現的單詞。'\1'用來指定第一個子匹配。單詞邊界元字符確保只檢測單獨的單詞。如果不這樣,則諸如 "is issued" "this is" 這樣的短語都會被該表達式不正確地識別。

3.2.2在正則表達式中指定模式option

可以在正則表達式中指定匹配模式

Symbol

Function

Memo

i

區分大小寫

前面加「-」表示關閉選項

s

單行模式匹配

 

M

多行模式匹配

 

 

語法為(?ism)

可以只對表達式的一部分使用模式,有效範圍為從這個位置起直到碰到下一個模式符為止。

也可以在前面加上「-」表示關閉這個選項。

比如(?i-sm),表示區分大小寫,關閉單行模式,打開多行模式。

3.2.3 Lookaround斷言

Perl5新引了一構造,分別為LookaheadLookbeehind。它也被稱作「0度斷言「0是因和定位符差不多,都匹配的是一行或一個始或束。不同的地方是LookahaedLookbehind匹配的是一個字符,而不是一個位置,但是卻返回的不是匹配的字符果,而是返回匹配的果:匹配是不匹配。也是稱作它斷言。它心匹配果是什,它只用來斷言個匹配果有沒有可能。

正向和反向的Lookahead

正向Lookahead:(?=Regex

反向Lookahead:(?!Regex

前面我的例子q[^u]表示的意是:『q'後面的字符可以是除了u以外的所有字符。但是,如果我要得到的果是:『q'後面不是』u',注意,不是:』q'後面的字符不是』u'。(q後面可以什也沒有,而字符集必匹配一個字符),在這種情況下,我就必使用反向lookahead斷言。可以這樣寫:q(?!u)。它的匹配果就是: 『q'後面不是』u'

正向lookahead斷言q(?=u)匹配的果就是:『q'後面是』u'

重要:

可以在lookahead中使用任何合法的正表達式,但是在lookbehind中就不可以。

Lookahead然被()括起來,但它並不建反向引用。如果想要把斷言中的匹配果存起來,必須單獨使用(),像這樣(?=(regex))

 

正向和反向的Lookbehind

正向Lookbehind:(?<=Regex

反向Lookbehind:(?<!Regex

』<』來區分是LookaheadLookbehind

 

Lookbehindlookahead有作用是相同的,但是它作用在string後面。它告Regex暫時lookbehind,先去匹配lookbehind後面的是否匹配,如果後面的匹配了,才去檢查lookbehind中的斷言。

(?<!a)b會匹配:』b'前面不是』a'。它不會匹配cab,但是會匹配一個獨的b或者beddebt

(?<=a)會匹配cab,但是不會匹配beddebt

重要:

不可以在Lookbehind中就不可以。

Lookbehind是定的。所以『?』『*』『+』不可以使用。


4. 表達式基本法索引

Regular Expression Basic Syntax Reference

Characters

Character

Description

Example

Any character except [\^$.|?*+()

All characters except the listed special characters match a single instance of themselves.

a matches a

\ (backslash) followed by any of [\^$.|?*+()

A backslash escapes special characters to suppress their special meaning.

\+ matches +

\xFF where FF are 2 hexadecimal digits

Matches the character with the specified ASCII/ANSI value, which depends on the code page used. Can be used in character classes.

\xA9 matches © when using the Latin-1 code page.

\n, \r and \t

Match an LF character, CR character and a tab character respectively. Can be used in character classes.

\r\n matches a DOS/Windows CRLF line break.

Character Classes or Character Sets [abc]

Character

Description

Example

[ (opening square bracket)

Starts a character class. A character class matches a single character out of all the possibilities offered by the character class. Inside a character class, different rules apply. The rules in this section are only valid inside character classes. The rules outside this section are not valid in character classes, except \n, \r, \t and \xFF

 

Any character except ^-]\ add that character to the possible matches for the character class.

All characters except the listed special characters.

[abc] matches a, b or c

\ (backslash) followed by any of ^-]\

A backslash escapes special characters to suppress their special meaning.

[\^\]] matches ^ or ]

- (hyphen) except immediately after the opening [

Specifies a range of characters. (Specifies a hyphen if placed immediately after the opening [)

[a-zA-Z0-9] matches any letter or digit

^ (caret) immediately after the opening [

Negates the character class, causing it to match a single character not listed in the character class. (Specifies a caret if placed anywhere except after the opening [)

[^a-d] matches x (any character except a, b, c or d)

\d, \w and \s

Shorthand character classes matching digits 0-9, word characters (letters and digits) and whitespace respectively. Can be used inside and outside character classes

[\d\s] matches a character that is a digit or whitespace

\D, \W and \S

Negated versions of the above. Should be used only outside character classes. (Can be used inside, but that is confusing).)

\D matches a character that is not a digit

Dot

Character

Description

Example

. (dot)

Matches any single character except line break characters \r and \n. Most regex flavors have an option to make the dot match line break characters too.

. matches x or (almost) any other character

Anchors

Character

Description

Example

^ (caret)

Matches at the start of the string the regex pattern is applied to. Matches a position rather than a character. Most regex flavors have an option to make the caret match after line breaks (i.e. at the start of a line in a file) as well.

^. matches a in abc\ndef. Also matches d in "multi-line" mode.

$ (dollar)

Matches at the end of the string the regex pattern is applied to. Matches a position rather than a character. Most regex flavors have an option to make the dollar match before line breaks (i.e. at the end of a line in a file) as well. Also matches before the very last line break if the string ends with a line break.

.$ matches f in abc\ndef. Also matches c in "multi-line" mode.

\A

Matches at the start of the string the regex pattern is applied to. Matches a position rather than a character. Never matches after line breaks.

\A. matches a in abc

\Z

Matches at the end of the string the regex pattern is applied to. Matches a position rather than a character. Never matches before line breaks, except for the very last line break if the string ends with a line break.

.\Z matches f in abc\ndef

\z

Matches at the end of the string the regex pattern is applied to. Matches a position rather than a character. Never matches before line breaks.

.\z matches f in abc\ndef

Word Boundaries

Character

Description

Example

\b

Matches at the position between a word character (anything matched by \w) and a non-word character (anything matched by [^\w] or \W) as well as at the start and/or end of the string if the first and/or last characters in the string are word characters.

.\b matches c in abc

\B

Matches at the position between two word characters (i.e the position between \w\w) as well as at the position between two non-word characters (i.e. \W\W).

\B.\B matches b in abc

Alternation

Character

Description

Example

| (pipe)

Causes the regex engine to match either the part on the left side, or the part on the right side. Can be strung together into a series of options.

abc|def|xyz matches abc, def or xyz

| (pipe)

The pipe has the lowest precedence of all operators. Use grouping to alternate only part of the regular expression.

abc(def|xyz) matches abcdef or abcxyz

Quantifiers

Character

Description

Example

? (question mark)

Makes the preceding item optional. Greedy, so the optional item is included in the match if possible.

abc? matches ab or abc

??

Makes the preceding item optional. Lazy, so the optional item is excluded in the match if possible. This construct is often excluded from documentation because of its limited use.

abc?? matches ab or abc

* (star)

Repeats the previous item zero or more times. Greedy, so as many items as possible will be matched before trying permutations with less matches of the preceding item, up to the point where the preceding item is not matched at all.

".*" matches "def" "ghi" in abc "def" "ghi" jkl

*? (lazy star)

Repeats the previous item zero or more times. Lazy, so the engine first attempts to skip the previous item, before trying permutations with ever increasing matches of the preceding item.

".*?" matches "def" in abc "def" "ghi" jkl

+ (plus)

Repeats the previous item once or more. Greedy, so as many items as possible will be matched before trying permutations with less matches of the preceding item, up to the point where the preceding item is matched only once.

".+" matches "def" "ghi" in abc "def" "ghi" jkl

+? (lazy plus)

Repeats the previous item once or more. Lazy, so the engine first matches the previous item only once, before trying permutations with ever increasing matches of the preceding item.

".+?" matches "def" in abc "def" "ghi" jkl

{n} where n is an integer >= 1

Repeats the previous item exactly n times.

a{3} matches aaa

{n,m} where n >= 1 and m >= n

Repeats the previous item between n and m times. Greedy, so repeating m times is tried before reducing the repetition to n times.

a{2,4} matches aa, aaa or aaaa

{n,m}? where n >= 1 and m >= n

Repeats the previous item between n and m times. Lazy, so repeating n times is tried before increasing the repetition to m times.

a{2,4} matches aaaa, aaa or aa

{n,} where n >= 1

Repeats the previous item at least n times. Greedy, so as many items as possible will be matched before trying permutations with less matches of the preceding item, up to the point where the preceding item is matched only n times.

a{2,} matches aaaaa in aaaaa

{n,}? where n >= 1

Repeats the previous item between n and m times. Lazy, so the engine first matches the previous item n times, before trying permutations with ever increasing matches of the preceding item.

a{2,}? matches aa in aaaaa

 


5.   表達式高級語法索引

Regular Expression Advanced Syntax Reference

Grouping and Backreferences

Syntax

Description

Example

(regex)

Round brackets group the regex between them. They capture the text matched by the regex inside them that can be reused in a backreference, and they allow you to apply regex operators to the entire grouped regex.

(abc){3} matches abcabcabc. First group matches abc.

(?:regex)

Non-capturing parentheses group the regex so you can apply regex operators, but do not capture anything and do not create backreferences.

(?:abc){3} matches abcabcabc. No groups.

\1 through \9

Substituted with the text matched between the 1st through 9th pair of capturing parentheses. Some regex flavors allow more than 9 backreferences.

(abc|def)=\1 matches abc=abc or def=def, but not abc=def or def=abc.

Modifiers

Syntax

Description

Example

(?i)

Turn on case insensitivity for the remainder of the regular expression. (Older regex flavors may turn it on for the entire regex.)

te(?i)st matches teST but not TEST.

(?-i)

Turn off case insensitivity for the remainder of the regular expression.

(?i)te(?-i)st matches TEst but not TEST.

(?s)

Turn on "dot matches newline" for the remainder of the regular expression. (Older regex flavors may turn it on for the entire regex.)

 

(?-s)

Turn off "dot matches newline" for the remainder of the regular expression.

 

(?m)

Caret and dollar match after and before newlines for the remainder of the regular expression. (Older regex flavors may apply this to the entire regex.)

 

(?-m)

Caret and dollar only match at the start and end of the string for the remainder of the regular expression.

 

(?i-sm)

Turns on the options "i" and "m", and turns off "s" for the remainder of the regular expression. (Older regex flavors may apply this to the entire regex.)

 

(?i-sm:regex)

Matches the regex inside the span with the options "i" and "m" turned on, and "s" turned off.

(?i:te)st matches TEst but not TEST.

Atomic Grouping and Possessive Quantifiers

Syntax

Description

Example

(?>regex)

Atomic groups prevent the regex engine from backtracking back into the group (forcing the group to discard part of its match) after a match has been found for the group. Backtracking can occur inside the group before it has matched completely, and the engine can backtrack past the entire group, discarding its match entirely. Eliminating needless backtracking provides a speed increase. Atomic grouping is often indispensable when nesting quantifiers to prevent a catastrophic amount of backtracking as the engine needlessly tries pointless permutations of the nested quantifiers.

x(?>\w+)x is more efficient than x\w+x if the second x cannot be matched.

?+, *+, ++ and {m,n}+

Possessive quantifiers are a limited yet syntactically cleaner alternative to atomic grouping. Only available in a few regex flavors. They behave as normal greedy quantifiers, except that they will not give up part of their match for backtracking.

x++ is identical to (?>x+)

Lookaround

Syntax

Description

Example

(?=regex)

Zero-width positive lookahead. Matches at a position where the pattern inside the lookahead can be matched. Matches only the position. It does not consume any characters or expand the match. In a pattern like one(?=two)three, both two and three have to match at the position where the match of one ends.

t(?=s) matches the second t in streets.

(?!regex)

Zero-width negative lookahead. Identical to positive lookahead, except that the overall match will only succeed if the regex inside the lookahead fails to match.

t(?!s) matches the first t in streets.

(?<=text)

Zero-width positive lookbehind. Matches at a position to the left of which text appears. Since regular expressions cannot be applied backwards, the test inside the lookbehind can only be plain text. Some regex flavors allow alternation of plain text options in the lookbehind.

(?<=s)t matches the first t in streets.

(?<!text)

Zero-width negative lookbehind. Matches at a position if the text does not appear to the left of that position.

(?<!s)t matches the second t in streets.

Continuing from The Previous Match

Syntax

Description

Example

\G

Matches at the position where the previous match ended, or the position where the current match attempt started (depending on the tool or regex flavor). Matches at the start of the string during the first match attempt.

\G[a-z] first matches a, then matches b and then fails to match in ab_cd.

Conditionals

Syntax

Description

Example

(?(?=regex)then|else)

If the lookahead succeeds, the "then" part must match for the overall regex to match. If the lookahead fails, the "else" part must match for the overall regex to match. Not just positive lookahead, but all four lookarounds can be used. Note that the lookahead is zero-width, so the "then" and "else" parts need to match and consume the part of the text matched by the lookahead as well.

(?(?<=a)b|c) matches the second b and the first c in babxcac

Comments

Syntax

Description

Example

(?#comment)

Everything between (?# and ) is ignored by the regex engine.

a(?#foobar)b matches ab

 

6.   參考資料

表達式 http://www.regexlib.com/

表達式 Blog http://blogs.regexadvice.com/

Mastering Regular Expressions (O'Reilly),作者 Jeffrey Friedl http://www.regex.info/

.NET 表達式參考

 http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextRegularExpressions.asp

Jscript 表達式

http://www.msdn.microsoft.com/library/en-us/script56/html/js56jsgrpRegExpSyntax.asp

表達式信息 http://www.regular-expressions.info/

7.   推薦工具

本文所有的例子都是在EditPad Pro下驗證的。

這個工具做的很好,有語法檢查和高亮顯示功能,對寫出正確的表達式很有幫助。極力推薦J

下載地址:http://www.editpadpro.com/

 

另一個工具是:The Regulator.

這個工具是針對。NET平台的,用的是.NET實現的正則表達式類庫。如果要在.NET中驗證表達式,這個工具不可或缺。

下載地址:http://royo.is-a-geek.com/iserializable/regulator/

 

也可以在這裡找到:\\xafile\Share\Public\Bond\Regex

Regular Expressions (2) ---- Common Used Samples

 說明:

以下所有的例子都在EditPad Pro下經過驗證,如果不能用,可能和特定的解釋引擎有關,稍稍修改就可以了。J (看得頭都暈了~~

更多的例子:http://www.regexlib.com

 

驗證... 2

簡單驗證電件地址... 2

驗證電件地址... 2

數字驗證... 2

大於零的Decimal數字... 2

任何Decimal數字... 2

0-99999999或不逗號的數字... 3

0-65535的值... 3

字符串驗證... 3

HTMLXML表姐... 3

ISBN格式的字符串... 3

GUID. 4

信用卡號... 4

連在一起的兩個相同的單詞... 4

雙引號括起來的詞... 4

標記... 5

驗證html中的16位顏色值... 5

驗證包含JSP事件的html代碼... 5

驗證一對封閉的xml標記... 5

驗證HTML中所有合法的on事件... 5

查找html中的註釋... 6

查找html中的特定文件(swf.jpg.gif…... 6

日期和時間驗證... 6

日期驗證... 6

日期和時間驗證... 6

標準ANSI SQL日期驗證... 7

其他... 7

匹配字體... 7

匹配MD5哈西字符串... 7

 


驗證

簡單驗證電件地址

表達式

(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})

描述

簡單符合<name>@xxx.com即可。

粗略驗證

匹配的例子

[foo@bar.com], [foobar@foobar.com.au]

不匹配的例子

[foo@bar], [$$$@bar.com]

 

驗證電件地址

表達式

^(([^<>;()[\]\\.,;:@"]+(\.[^<>()[\]\\.,;:@"]+)*)|(".+"))@((([a-z]([-a-z0-9]*[a-z0-9])?)|(#[0-9]+)|(\[((([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\.){3}(([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\]))\.)*(([a-z]([-a-z0-9]*[a-z0-9])?)|(#[0-9]+)|(\[((([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\.){3}(([01]?[0-9]{0,2})|(2(([0-4][0-9])|(5[0-5]))))\]))$

描述

所有符合RFC 821http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc0821.html#page-30)規定的格式的郵件地址

匹配的例子

blah@[10.0.0.1]|||a@b.c

不匹配的例子

non@match@.

數字驗證

大於零的Decimal數字

表達式

(^\d*\.?\d*[1-9]+\d*$)|(^[1-9]+\d*\.\d*$)

描述

大於零的Decimal數字

匹配的例子

0.050

5.0000

5000

不匹配的例子

0

0.0

.0

 

任何Decimal數字

表達式

^(\d|-)?(\d|,)*\.?\d*$

描述

匹配:

純數字

負數

逗號分割的數字

點分割的decimal格式

匹配的例子

5,000

-5,000

100.044

.2

不匹配的例子

abc

1.3.4

 

0-99999999或不逗號的數字

表達式

^(\d|-)?(\d|,)*\.?\d*$

描述

匹配:

0-99999999的帶或不帶逗號的數字

匹配的例子

5,000

100044

不匹配的例子

123,888,888

1.1

 

0-65535的值

表達式

^([0-5]?\d?\d?\d?\d|6[0-4]\d\d\d|65[0-4]\d\d|655[0-2]\d|6553

[0-5])$

描述

0-65535數字

匹配的例子

5000

100

不匹配的例子

66666

-2

字符串驗證

HTMLXML標記

表達式

<[^>]+>

描述

所有的htmlxml標記

匹配的例子

<b>

</b>

5.0000

5000

不匹配的例子

http://www.regexlib.com/Add.aspx

 

ISBN格式的字符串

表達式

<[^>]+>

描述

ISBN格式的字符串。

詳細定義:http://www.isbn.org/standards/home/isbn/international/html/usm4.htm

 

匹配的例子

ISBN 0 93028 923 4

ISBN 1-56389-668-0

ISBN 1-56389-016-X

不匹配的例子

http://www.regexlib.com/Add.aspx

 

GUID

表達式

^[{|\(]?[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}[\)|}]?$

描述

以下格式的32GUID:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)

匹配的例子

914D226A-2F5B-4944-934D-96BBE6571977

{914D226A-2F5B-4944-934D-96BBE6571977}

不匹配的例子

914D226A-2F5B-4944-XXXX-96BBE6571977

{914D226A-2F5B-4944-XXXX-96BBE6571977}

 

信用卡號

表達式

^[{|\(]?[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}[\)|}]?$

描述

16位數字

16位數字用連字符或者空格或者分割

匹配的例子

1234343425262837

1111-2323-2312-3434

1111 2323 2312 3434

不匹配的例子

1111 2323 2312-3434

 

連在一起的兩個相同的單詞

表達式

(\w+)\s+\1

描述

驗證連在一起的兩個相同的單詞

匹配的例子

abc abc

不匹配的例子

abc abcd

 

雙引號括起來的詞

表達式

"((\\")|[^"(\\")])+"

描述

驗證用雙引號括起來的詞

匹配的例子

「Abc」

「abc」sff」

不匹配的例子

「sdfsdfsdf

標記

驗證html中的16位顏色值

表達式

 

^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$

 

描述

驗證html中的16進制的顏色值

#是可選的。

匹配的例子

#00ccff

ffffcc

不匹配的例子

blue

0x000000

 

驗證包含JSP事件的html代碼

表達式

<[a-zA-Z][^>]*\son\w+=(\w+|'[^']*'|"[^"]*")[^>]*>

描述

驗證包含JSP事件的html代碼

匹配的例子

<IMG onmouseover="window.close()">

不匹配的例子

IMG src="star.gif"

 

驗證一對封閉的xml標記

表達式

 

^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$

 

描述

驗證一對括起來的xml標記。

匹配的例子

<body> text<br/>More Text </body>

<a href="link.html" _fcksavedurl="link.html">Link</a>

不匹配的例子

blue

0x000000

 

驗證HTML中所有合法的on事件

表達式

(?i:on(blur|c(hange|lick)|dblclick|focus|keypress|(key|mouse

)(down|up)|(un)?load|mouse(move|o(ut|ver))|reset|s(elect|ubm

it)))

描述

驗證HTML中所有合法的on事件

匹配的例子

onclick

onmouseover

不匹配的例子

Click

Move

 

查找html中的註釋

表達式

<!\-\-.*?\-\->

描述

查找html中的註釋

匹配的例子

<!-- <h1>this text has been removed</h1> -->

不匹配的例子

<h1>this text has been removed</h1>

 

查找html中的特定文件(swf.jpg.gif…

表達式

<[^>]*\n?.*=("|')?(.*\.jpg)("|')?.*\n?[^<]*>

描述

查找html中的特定文件(swf.jpg.gif…

jpg換為gif,即是查找所有的gif文件。

匹配的例子

<td background="../img/img.jpg" >

不匹配的例子

= img.jpg

日期和時間驗證

日期驗證

表達式

^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$

描述

驗證格式為y/m/d的日期從1600/1/1 - 9999/12/31的日期

匹配的例子

04/2/29

2002-4-30

02.10.31

不匹配的例子

2003/2/29

02.4.31

00/00/00

 

日期和時間驗證

表達式

^(?=\d)(?:(?:(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})|(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2}))($|\ (?=\d)))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$

描述

驗證所有合法的日期和時間

匹配的例子

20:20

04/2/29

02.4.31

02.10.312002-4-30

02.10.31

不匹配的例子

2003/2/29

00/00/00

 

標準ANSI SQL日期驗證

表達式

^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$

描述

匹配ANSI SQL的日期格式:YYYY-mm-dd hh:mi:ss am/pm

包括檢查從1901-2099是否是閏年。

匹配的例子

2004-2-29

2004-02-29 10:29:39 pm

2004/12/31

不匹配的例子

04-2-29

04-02-29 10:29:39 pm

04/12/31

其他

匹配字體

表達式

^(\d)(\d)*( )*(px|PX|Px|pX|pt|PT|Pt|pT|)$

描述

查找字體的後綴

 

匹配的例子

1px

100 PT

20Px

不匹配的例子

1abc

px

1 sdfs

 

匹配MD5哈西字符串

表達式

^(\d)(\d)*( )*(px|PX|Px|pX|pt|PT|Pt|pT|)$

描述

^([a-z0-9]{32})$

匹配的例子

790d2cf6ada1937726c17f1ef41ab125

不匹配的例子

790D2CF6ADA1937726C17F1EF41AB125

Regex的相關工具和word文檔可以在這裡找到。\\xafile\Share\Public\Bond\Regex

 

 

PS

這個列表會一直更新的,希望大家也能多多支持。把看到的有用的Regex都貼進來。

J

Regular Expressions (3) ---- Using Regex in .NET

看這篇文章之前,假定你已經瞭解了有關正則表達式的一些知識,並且知道如何去應用它。本篇文章只介紹如何在.NET中使用正則表達式。

 最後是一個應用正則表達式的給VB程序語法加亮的小程序。

 

 

名稱空間和相關的類

.NET中所有和正則表達式相關的類都定義在System.Text.RegularExpressions名稱空間下。

分別是:

Class

Description

Regex

不可變的(只讀)的正則表達式的實例,包括一些靜態方法

Capture

包含單個子表達式匹配的結果,不能實例化,必須通過GroupMatch來訪問。

CaptureCollection

Capture的序列

Group

一組表達式匹配的結果,由Capture繼承而來

GroupCollection

Group的序列

Match

一個正則表達式的匹配結果,由Group繼承而來

MatchCollection

Match的序列

 下面用圖和例子說明各個類之間的關係:

例:

如上圖:

匹配的字符串是:xgraygreyxgreyxgray

正則表達式是:(gr[ae])y

表示匹配」gray」或者」grey」一次或n次。

 從生成的匹配樹可以看到:

總共找到了三個匹配。每個匹配的值分別為:graygraygraygrey

以第一個匹配為例:

匹配一中共包括兩個組:每個組的值分別為:graygreygrey

第一個組只有一個捕獲結果,就是graygrey

第二組有兩個捕獲結果,分別為graygrey

下面說明這些類的詳細作用:

Match

Match表示的是一個正則表達式的匹配操作。

如上例:

(Gr[ae]y)+得到三個Match結果。分別是graygreygraygrey

這等於是正則表達式解釋器把(gr[ae]y)+吃拆成了(gr[ae]y)+(gray)+(grey)+三個單獨的子表達式。

每個子表達式對應一個Match結果。

Regex

Result

(gr[ae]y)+

Graygrey

(gray)+

Gray

(grey)+

Grey

MatchCollection

MatchCollection表示的就是所有的字表達式的Match結果的集合。

可以通過遍歷Matchs的集合來訪問各個子表達式的Match結果。

For each m as Match in Regex.Matches(graygrey」, (gr[ae]y)+」)

            『 Use match result here.

Next

Group

每個子表達式默認就是一個組。所以子表達式的所有組的結果都保存在第一個組中,這也是為什麼每個Match的結果和第一個Group的結果是一樣的,因為它們就是一個。

.NET中,用括號括起來的子表達式表示這是一個組。

可以通過(?<groupName><子表達式>)來顯示的給組命名。

比如:

Regex r = new Regex(「(?abc)+」)。就定義了一個組,名字為g1

在程序中,我們可以通過組命來訪問組的匹配結果。

Dim m As Match = r.Match("xxabcabc")

Dim g1 As Group = m.Groups(「g1」)

GroupCollection

GroupCollection表示一個MatchGroup的集合。

可以通過組命或者索引來訪問一個組。

 Catpure

Capture中保存的是每一個子表達式的最小匹配結果,它相當於是原子匹配,比如a匹配a,則結果a就保存在capture中,group的結果只是所的capture結果的組合。

所以如果一個匹配只有一個group,這個group中又只有一個capture,則這個capture的結果就是整個Match的結果。

CaptureCollection

Capture的序列。

VBHightDemo

下面介紹一下這個應用正則表達式給VB語法加亮的程序。

這個程序的原理就是根據正則表達式分析每一行字符串,根據匹配結果,把相應的字符的顏色改變。

關鍵的地方就是拿到組建的正則表達式。

Private VBImports As Regex = New Regex("(?RegexOptions.Compiled)

    Private QuotedString As Regex = New Regex("""" & "[^""]*" & """", RegexOptions.Compiled)

    Private VBComment As Regex = New Regex("'.*")

    Private EmptyLine As Regex = New Regex("^\\s*\\Z", RegexOptions.Compiled)

    Private VBRegion As Regex = New Regex("(#region|#end region){1}", RegexOptions.Compiled)

     '-- use lookbehind, keywords can not follow by a '.' or a characotr

    Dim aa As String = "(?<![\.\w])(as|boolean|break|byte|byval|byref|" _

                                & "case|catch|char|checked|class|const|continue|" _

                                & "decimal|dim|default|delegate|double|else|" _

                                & "enum|end|event|exit|explicit|extern|false|each|" _

                                & "float|friend|for|goto|if|implicit|inherits|" _

                                & "integer|interface|internal|is|lock|long|" _

                                & "namespace|new|next|overrides|overloads|object|operator|out|" _

                                & "override|params|private|protected|" _

                                & "public|readonly|ref|return|sbyte|sealed|" _

                                & "short|static|string|sub|" _

                                & "structure|switch|me|mybase|throw|true|try|typeof|" _

                                & "uint|ulong|unchecked|ushort|using|" _

                                & "while|withevents){1}[^\w]"

    Private VBKeyWords As Regex = New Regex(aa, RegexOptions.Compiled)

    Private SystemKeyWords As Regex = New Regex("(application|console|environment|gc|threadpool|math){1}", RegexOptions.Compiled)

Private Brackets As Regex = New Regex("(\{|\[|\(|\}|\]|\))", RegexOptions.Compiled)

在匹配的時候,可以給指定匹配的選項,比如忽略大小寫,單行還是多行等等。

然後遍歷並加亮匹配的結果就可以了。

For Each m As Match In regex.Matches(s)

       Me.ColorString(start + m.Groups(0).Index, m.Groups(0).Length, color)

Next

因為組中保存的就是所有capture的組合的結果,所以只加亮groups(0)中的字符串就夠了,不需要再重複處理groupcaptures的值。

 

不正之處還請多多指正。

:)

 

If the source code needed, plase mail to me: etmonitor@msn.com.

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo