C 中的正規表示式

2021-04-07 06:26:38 字數 4139 閱讀 3947

c#中的正規表示式

jeffrey e.f. friedl寫了一本關於正規表示式的書《精通正規表示式》。作者為了使讀者更好的理解和掌握正規表示式,編造了乙個故事。該書的語言以perl為主。據我所知c#中的正規表示式也是基於perl5。所以它們應該有許多的共同之處。

其實,我並不打算原封不動的對該書的內容進行翻譯,一則這本書內容太多了,我根本就不勝任翻譯這項工作;二則如果我真的把這本書翻譯過來,同時把裡面的**換成c#,在沒有徵得原作者的情況下,可能有侵權的嫌疑了。所以,權當作讀書筆記好了。

略過冗長的前言,我們可以直接進入第一章:

介紹正規表示式

作者說這一章是為正規表示式的絕對菜鳥而準備的,目的是為以後的章節打下堅實的基礎。那麼如果你是不是菜鳥,你可以忽略這一章。

故事場景:

接受任何數量要檢查的檔案,報告每個檔案中帶有重複單詞的那些行,突出顯示這些重複的單詞,同時確保原檔名稱和這些行出現在報表中。

跨行檢查,找到一行的最後乙個單詞和下一行開頭第乙個單詞出現重複的情況。

找出重複的單詞,不管他們是否大小寫不同(如:the the),以及允許在這些重複單詞之間含有不同數量的空白字元(空格、製表符、新行等)

找出重複的單詞,甚至這些單詞被html標籤隔開。(如:…it is very very important.)

要解決上述的實際問題,我們首先要做的就是寫出正規表示式,找到我們想要的文字,忽略我們不需要的文字,然後使用我們的c#**對獲取的文字進行處理。

在使用正規表示式之前,你也許多少已經知道什麼是正規表示式。甚至你不知道,你幾乎可以肯定已經熟悉它的基本概念了。

檔名稱得模式匹配,使用了有限的匹配符。還有當前網路上的搜尋引擎也允許使用某些指定的匹配符來進行內容搜尋。正規表示式採用豐富的匹配字元,可以處理各種複雜的問題。

首先我們介紹兩個位置匹配符:

^ : 表示一行文字的開始位置

$ : 表示一行文字的結束位置

如:表示式:"^cat", 匹配的單詞cat出現在行的開始處,注意^是乙個位置字元,不是要匹配字元的本身。

同樣,表示式:"cat$" 匹配的單詞cat出現來一行的結尾處。

接下來,我們介紹表示式中的方括號"", 它表示匹配括號中字元中的乙個。如:

表示式:"[0123456789]"將匹配數字0到9的任何乙個。

例如:我們要查詢文字中,所有包含gray或者grey,那麼表示式可以這麼寫:"gr[ea]y"

[ea]表示匹配ea中的乙個,而不是整個ea。

如果我們要匹配html中的的標籤,我們可以寫表示式:

"",但是如果我們要匹配所有字元中的乙個呢?哈,問題就來了,在方括號中寫出所有的字元?很幸運,我們不必這麼做,我們引進範圍符號"-";

使用範圍符號,我們只需要給出乙個範圍的邊界字元即可,上面的html例子,我們可以寫成:""

而表示式:"[0-9a-za-z]"的意思現在清楚了吧?它匹配數字字元,小寫26個字母和大寫26個字母中的乙個。

出現在中的"^"符號

如果你看到表示式如:"[^0-9]",此時,"^"不再是前面說的位置符號,這裡它是否定符號,表示排除的意思,上面的表示式,表示不包含數字0到9的字元。

思考1:表示式"q[^u]"的意思。假如有下列的單詞,那些將被匹配?

iraqi

iraqian

miqra

qasida

qintar

qoph

zaqqum

除了範圍字元的表示之外,還有乙個是點字元".",點字元出現在表示式中,表示匹配任何字元。

如表示式:"07.04.76"將匹配:

形如:07/04/76, 07-04-76,07.04.76。

如果我們需要在某些字元中可選擇,我們可以採用選項字元"|":

選項字元有「或"的意思,比如表示式:"[bob|robert]"則表示bob或者robert將被匹配。

現在看我們前面提到的表示式:"gr[ea]y" ,利用選項字元我們可以寫作"grey|gray",它們是相同的。

圓括號的使用:圓括號在表示式中也是被作為元字元使用,如前面的表示式,我們可以寫成:"gr(e|a)y",這裡的圓括號是必須的,如果沒有圓括號,那麼表示式"gre|ay"將匹配gre或者ay,這不是我們想要的結果。如果你還不是很清楚,讓我們看一下下面的例子:

在電子郵件中查詢所有以from:或者subject:或者date:開頭的行,我們比較下面的兩個表示式:

表示式1:"^from|subject|data: "

表示式2:"^(from|subject|data): "

哪乙個是我們想要的?

很明顯,表示式1的結果不是我們想要的結果,它匹配的將是:from或者subjec或者data: ,表示式2使用圓括符,就能滿足我們的需要。

單詞邊界

我們已經可以匹配出現在行首和行尾的字元,那麼如果我們想定位的不僅僅是行首或者行尾呢?我們需要引入單詞邊界符號,單詞邊界符號是:"/b",斜槓不可省略,否則變成匹配字母b。使用單詞邊界符號,我們可以定位匹配的位置必須出現在乙個單詞的開始或者結尾部分,而不是在單詞的中間。例如:"/bis/b"表示式在字串"this is a cat."中將匹配單詞"is"而不會匹配單詞"this"中的"is"。

字串邊界符號

除了上述的位置符號,如果我們要匹配的是整個字串(含多個單詞)那麼我們可以使用下面的兩個符號:

/a :表示字串的開始處;

/z :表示字串的結束處。

表示式:"/athis is a cat/z"將匹配這個字串"this is a cat"。

使用邊界定位符號,這裡要提到乙個重要的概念,那就是單詞字元,單詞字元表示可以構成單詞的字元,它們是[a-za-z0-9]中的任意乙個字元。所以上面的表示式也會在句子"this is a cat."得到匹配。匹配的結果不包含句號。

重複數量符號

讓我們看表示式:"colou?r", 這個表示式中出現了我們還沒有見過的問號,(這個問號和檔名稱匹配的問號意義不同),它表示符號前面的乙個字元可以被重複的次數,"?"表示0次或者1次,前面的表示式中問號表示u可以出現0或1次,所以它將匹配"color"或者"colour"。

下面是其他的重複數量符號:

+ :表示1次或者多次

* :表示0次或者多次

例如我們要表示一或多個空格,我們可以寫表示式:" +";

如果要表示具體次數呢?我們引入花括符{}。

: n是具體的數字,表示重複n次。

: 表示最少那次,最多m次。

這些符號都限定了符號前面乙個字元的匹配次數。但是如果你想重複多個字元,比如乙個單詞,那麼怎麼辦?我們再次使用圓括號,前面我們把圓括號作為選項的範圍符號,這裡是圓括的另外一種使用方法,它被表示為乙個組,例如表示式:「(this)"這裡的this就是乙個組,那麼問題就好辦了,重複數量符號可以用來表示它前面乙個組的重複次數。

現在回到查詢重複單詞的問題,假如我們要找到「the the」,根據我們迄今為止學到的知識,我們可以寫出表示式:

"/bthe +the/b"

表示式的意思是匹配兩個the中間有乙個或多個空格隔開。

同樣,我們還可以寫成:

"/b(the +)"

但是如果要找全部可能的重複單詞呢?我們目前的知識還不足以解決這個問題,下面我們引進反向引用的概念,我們已經看到圓括號可以作為組的邊界,乙個表示式中可以有多個被圓括號限定的組,根據它們出現的次序,這些組預設的被分配了乙個組號,第乙個出現的組號為1號,依次類推。那麼反向引用就是可以在之後的表示式的位置上是使用"/n"來引用這個組,這裡n是被引用的組號。反向引用就像是程式中的變數一樣,下面我們看具體的例子:

前面的單詞重複表示式,現在我們採用反向引用可以寫做:

"/b(the) +/1/b"

現在,如果我們要匹配所有的重複單詞,我們就可以改寫表示式為:

"/b([a-za-z]+) +/1/b"

最後乙個問題是,如果我們要匹配的字元是正規表示式中的符號,怎麼辦?對,使用轉義符號"/", 例如如果你要匹配乙個小數點,那麼你可以:"/.",還要注意的是如果在程式中使用表示式那麼"/"也要按照字串的規定變成"//"或者在表示式前面加@。

本章僅僅是提供給菜鳥乙個關於正規表示式的基礎知識,它只是其中的部分,我們還有許多東西要學習,這將在後面的章節中一一介紹。其實,正規表示式的學習並不難,你需要的是耐心和實踐,如果你想精通它的話。或許有人說:「我不想知道汽車的細節,我只想學會怎麼開車。」如果你也是這樣想的,那麼,你永遠也不知道怎麼使用正規表示式來解決你的問題,進而,你也永遠不會懂得正規表示式的真正的強大

C 中的正規表示式

字元 描述 將下乙個字元標記為乙個特殊字元 或乙個原義字元 或乙個 向後引用 或乙個八進位制轉義符。例如,n 匹配字元 n 匹配乙個換行符。序列 匹配 而 則匹配 匹配輸入字串的開始位置。如果設定了 regexp 物件的 multiline 屬性,也匹配 或 之後的位置。匹配輸入字串的結束位置。如果...

C 中的正規表示式

位置匹配符 表示一行文字的開始位置 表示一行文字的結束位置 如 表示式 cat 匹配的單詞cat出現在行的開始處,注意 是乙個位置字元,不是要匹配字元的本身。同樣,表示式 cat 匹配的單詞cat出現來一行的結尾處。方括號 它表示匹配括號中字元中的乙個 例如 我們要查詢文字中,所有包含 gray或者...

C 中的正規表示式

正規表示式 是一種匹配文字的模式。匹配必須出現在字串開頭或者行的開頭 匹配必須出現在字串結尾或者行的結尾 string str i am april.string str2 regex.replace str,hi,str2 hi,i am april.string str3 regex.repla...