簡單入門正規表示式 第四章 單字元的匹配

2021-04-21 04:27:15 字數 3428 閱讀 5790

正規表示式中,最簡單的匹配就是單字元匹配了,這就像我們利用文字工具在文件中查詢乙個字元一樣簡單。下面我們使用 emeditor 來做個小實驗,在字串「regular expression」中查詢字元「e」。

ctrl+f 開啟查詢對話方塊,然後在「查詢」框內鍵入字元「s」,並選用「匹配大小寫」和「使用正規表示式」模式,然後進行查詢操作。從上圖的效果來看,同時有兩個「s」被匹配到了,但實際上這是執行了兩次匹配操作的結果,每次操作只匹配了乙個字元「s」,操作順序是自左向右。讓我們再嘗試使用 expresso 就能看出其中的奧秘,如下圖所示:

在「regular expression」的選項卡下輸入「s」,「sample input data」區域中輸入字串「regular expression」,在單擊「run match」按鈕就能看到匹配結果。在上圖的右下角出現了兩個「s」,這是發生了兩次匹配操作,每次都有乙個結果的緣故。

當我們使用計算機時,經常需要開啟和儲存檔案,這就免不了要與開啟/儲存對話方塊打交道,其中涉及到的檔案型別都採用 * 點副檔名這種形式。比如說 html 檔案,它所對應的檔案型別就是 *.html 或 *.htm,星號就是乙個萬用字元,表示與任意字元匹配,而在正規表示式中,也有這麼乙個萬用字元「.」,它可以與任意單字元相匹配,但通常不包括換行符。

接著上面的例子,我們把正規表示式樣式修改為p.e.s,這時的萬用字元「.」就分別與目標字串的「r」和「s」相匹配,結果為「regular expression」。

在匹配目標字串時,有時候可能會有些特殊需求,比方說我們要對片語「regular expression」或者「regular expressions」進行匹配,無論哪種形式的片語,我們都想能夠成功匹配。這時,單詞「expression」後面的「s」就是可選的,在正規表示式中,問號表示它所指定的樣式出現的次數為零次或一次,所以,我們可以編寫正規表示式regular expressions? 來進行匹配。

到目前為止,常規字元我們都可以成功地進行匹配,但是,還有一種情況就是像問號這樣在正規表示式中含有特殊意義的字元,對於這些字元來說,我們是無法直接利用它們進行匹配操作,那該如何對這些符進行轉義呢?跟許多程式語言一樣,正規表示式也提供了乙個轉義的處理機制,我們可以使用轉義操作符反斜桿「/」。所以,如果我們想匹配問號和點,使用「/?」和「/.」就可以。同樣,對於轉義符「/」來說,它對自身也可以實現轉義功能,連續的兩個「/」代表了乙個字元「/」。

修改上面的正規表示式為regular expression/?,它就能與字串「regular expression?」相匹配了。在編寫正規表示式時,如果碰到了要匹配特殊字元的情況,那就一定要使用轉義操作。

同「?」和「.」一樣,「*」和「+」也是具有特殊含義的字元,它們的作用是讓某個指定了的正規表示式樣式進行多次重複匹配。「*」的重複次數是從零開始的,規定其前導內容必須在目標字串中出現零次或更多次;而「+」所對應的重複次數是從一開始的,規定其前導內容必須在目標字串中出現一次或更多次。它們的重複次數都沒有上限值限制,也就是說它們的前導內容可以在目標字串中不斷地重複出現。

正規表示式abc9*表示乙個以「abc」開頭,後面為零個或多個連續「9」的字串。這樣,它就能與字串「abc」、「abc9」、「abc99」和「abc999」等內容相匹配了。

我們先來分析一下對字串「abc」的匹配,當正規表示式引擎對abc匹配結束後,下乙個參與匹配的字元就應該是「9」,但根據「*」的零次匹配原則,「9」是可以不出現的,所以,字串「abc」就成功地被匹配了。

再來看一下字串「abc999」,對字元「c」的匹配結束後,碰到的下乙個字元就是「9」,成功匹配之後,繼續下乙個字元,一直到最後乙個字元為止,字元「9」出現的次數與「*」的多次匹配原則保持一致,所以字串「abc999」也能夠被成功匹配。

上面介紹了如何讓我們的匹配內容進行無限次的迴圈匹配,現在,我們學習一下怎麼樣精確地控制迴圈匹配次數。正規表示式提供了一種使用花括號的方法控制迴圈匹配次數,語法形式有、、三種,其中 m 和 n 都是非負整數,且 m 的值小於 n值。

代表了被指定的匹配樣式必須在目標物件中重複出現 n 次;表示被指定的匹配樣式在目標物件中至少要重複出現 n 次,但無上限值限制;指定了迴圈次數的範圍,至少要重複出現 m 次,至多重複出現 n 次,如果 m 值比 n 大,的作用就相當於。

現在,我們思考乙個問題,「*」和「+」同樣能夠對重複匹配的次數做出限定,那麼,如何用花括號形式表示呢?由於「*」表示指定的匹配樣式要重複出現 0 或多次,所以,我們可以先用滿足重複出現 0 次的要求。但是如又何滿能夠足重複多次的要求呢,由於最終重複出現的次數是不固定的,我們就不能採用這種形式,現在也只有採用最後一種形式,「*」對應的花括號表現形式為。同理可推「+」對應的花括號表現形式為,相對於用於可選匹配的「?」來說,用來替換即可。

當我們使用含有次數限制的匹配語法時,常常會碰到正規表示式中的貪婪式與懶惰式的概念。那它們到底是什麼意思呢?先看一下下面兩種對html標記進行匹配的例子,構造正規表示式<.+>來匹配字串「w3c a to z」,如下圖所示:

為什麼<.+>並沒有像我們預想的那樣匹配每乙個html標記,而是一次性「吃掉」了所有的內容呢?這就是貪婪的匹配模式!讓我們分析一下正規表示式引擎的匹配機制,就會明白其中的道理了。首先要匹配的字元是「<」(匹配過程01),這個一點問題也沒有,然後輪到萬用字元「.」上場了,因為它後面緊跟著乙個「+」,這就能讓它毫無顧忌的乙個勁兒匹配下去,當匹配到字串「w3c a to z」最後乙個字元「>」時,引擎發現無法找到相匹配的字串,就嘗試著回退,把最後一次機會讓給「>」。結果當然是匹滿足條件的了,這就是為什麼匹配結果是整個目標字串而不是「」和「」。

匹配過程01 => <

匹配過程02 => w3c a to z

匹配過程03 => w3c a to zbacktrack

匹配過程04 => w3c a to z w3c a to z

匹配過程06 => match found

接下來,我們再分析一下採用懶惰模式的正規表示式<.+?>,貪婪模式與懶惰模式的語法區別在於重複限定修飾符的後面是否有問號,有的話就是懶惰模式,否則就是貪婪模式。

懶惰模式下匹配的結果有兩個,「」和「」。對於前者的匹配過程是,首先匹配首字元「<」;然後再將「.」與「a」相匹配,這時「.」已經滿足了「+」的匹配次數至少要達到一次的要求,由於懶惰模式的緣故,「+」只要能滿足匹配條件就不會繼續執行下去;接下來要參與匹配的字元就是「>」,這時恰好滿足整個正規表示式的要求。對於後者來說要稍微複雜一點,當第二步「.」與「/」匹配後,第三步就要直接用「>」進行匹配,但「>」並不能與「a」相匹配,所以只能放棄,繼續由「.」再次擔任匹配任務;與「a」匹配完畢後,重新嘗試用「>」進行匹配操作,這次匹配成功並且目標字串再沒有可以參與匹配操作的字串,整個匹配過程順利結束,結果就是「」。

<

match found

<

match found

不光是「*」和「+」有貪婪與懶惰兩種模式,花括號語法同樣存在相同的情況。如果用正規表示式(as)來匹配字串「asasasasas」,結果就是「asasasasas」,有四組「as」被匹配;要是換成(as)?,結果就是「asasasasas」,有三組「as」被匹配。

正規表示式第四章

正規表示式的其他方法 match方法,進行驗證,獲得驗證後的返回值 正規表示式中 g代表全域性模式匹配 var str 中國移動 10086,中國聯通 10010,中國電信 10000 var array str.match d g 獲取全域性模式匹配項 console.log array 1008...

第四章 表示式

左值,用的是物件的身份 記憶體中的位置 右值,用的是物件的值 解引用生成 左值,取位址生成乙個 右值 bool b true bool c b c為true,因為 bool值在計算的時候被轉換成整型號int,所以b被轉換成 1,不為0,所以賦值給c的時候,為true int b while b ge...

第四章 表示式

這個概念暫時很模糊,打算學完這一章再總結。目前的理解是,左值有名字,可以通過名字訪問記憶體,右值沒有名字,一般是運算的中間結果或者字面值常量等。const修飾的變數是常量左值 如果decltype 函式的括號中表示式結果是左值,則得到乙個引用型別。例如在下面這段 中,b是int型別,c是int 型別...