1.正規表示式是什麼
正規表示式(regular expression)描述了一個字串匹配的模式,可以用來:含有符合某個
(1) 檢查一個字串中是否含有符合某個規則的字串,並且可以得到這個字串;
(2) 根據符合規則對字串進行靈活的替換操作。
正規表示式學習起來其實是很簡單的,不多的幾個較為抽象的概念也很容易理解。之所以很多人感覺正規表示式比較複雜,一方面是因為大多數文檔沒有做到由淺入深的講解,概念上沒有註意先後順序,給對著的理解帶來困難;另一方面,各種引擎自帶的文檔一般都要介紹它特有的功能,然而這部分特有的功能並不是我們首先要理解的。
相關課程:布林教育正規表示式影片教學
2 .正規表示式怎麼用
2.1 普通字元
字母、數字、漢字、底線、以及後邊章節中沒有特殊定義的標點符號,都是普通字元。表達式中的普通字符,在匹配一個字串的時候,匹配與之相同的一個字符。
範例1:表達式 c ,在匹配字串 abcdef 時,匹配結果是:成功;匹配到的內容是:c ;匹配到的位置是:開始於2,結束於3。 (註:下標從0開始還是從1開始,因目前程式語言的不同而可能不同)。
範例2:表達式 bcd ,在匹配字串 abcde 時,匹配結果是:成功;匹配到的內容是:bcd ;匹配到的位置是:開始於1,結束於4。
2.2 簡單的轉義字符
#一些不便書寫的字符,採用前面加 \ 的方法。這些字符其實我們都已經熟知了。
還有其他一些在後邊章節中有特殊用處的標點符號,前面加上 \ 後,就代表符號本身。例如:^,$ 都有特殊意義,如果想要皮詬字串中的 ^ 和 $ 字符,正規表示式就需要寫成 \^ 和 \$ 。
這些轉義字元的匹配方法與 普通字元 是類似的。也是匹配與之相同的字元。
範例:表達式 \$d ,在符合字串 abc$de 時,配對結果是:成功;符合的內容是:$d ;符合到的位置是:開始於3,結束於5.
2.3 能夠與'多種字元' 匹配的表達式
正規表示式中的一些表示方法,可以匹配 多種字符 其中的任一個字符。例如,表達式 \d 可以符合任一個數字。雖然可以匹配其中任意字符,但只能是一個,不是多個。這就好比玩撲克牌的時候,大小王可以代替任一張牌,但是中能代替一張牌。
範例1:表達式 \d\d ,在配對 abc123 時,配對結果為:成功;符合的內容為:12 ;符合的位置是:開始於3,結束於5.
舉例2:表達式 a.\d ,在配對 aaa100 ,配對結果為:成功;配對的內容為: aa1 ;符合的位置是:開始於1,結束於4。
2.4 自訂能夠匹配'多種字符'的表達式
#使用方括號 [] 包含一系列字符,並且能夠匹配其中任意一個字元。用 [^] 包含一系列字符,則能夠匹配其中字符之外的任意一個字符。同樣的道理,雖然可以匹配其中任一個,但是只能是一個,不是多個。
範例1:表達式 [bcd][bcd] 配對 abc123 時,配對的結果是:成功;配對的內容為:bc ;符合的位置是:開始於1,結束於3。
範例2:表達式 [^abc] 配對 abc123 時,配對的結果是:成功;符合的內容是:1 ;符合的位置是:開始於3,結束於4。
2.5 修飾符合次數的特殊符號
#前面章節中講到的表達式,無論是只能符合一種字元的表達式,或是可以符合多種字元的表達式,都只能符合一次。如果使用表達式再加上修飾符合次數的特殊符號,那麼不用重複書寫表達式就可以重複配對。
使用方法是:「次數修飾」放在被修飾的表達式的後面。例如:[bcd][bcd] 可以寫成 [bcd]{2} 。
舉例1:表達式 \d+/.?\d* 在符合 it costs $12.5 時,符合的結果是:成功;符合的內容是:12.5 ;配對到的位置是:開始於10,結束於14。
範例2:表達式 go{2, 8}gle 在符合 Ads by goooooogle 時,配對的結果是:成功;符合的內容是:goooooogle ;符合的位置是:開始於7,結束於17。
2.6 其他一些代表抽象意義的符號
#有些符號在表達式中代表抽象的特殊意義:
進一步的文字說明仍然比較抽象,因此,舉例幫助大家理解。
範例1:表達式 ^aaa 在符合 xxx aaa xxx 時,配對的結果是:失敗。因為 ^ 要求與字串開始的地方匹配,因此只有當 aaa 位於字串開頭的時候,^aaa 才能匹配,例如:aaa xxx xxx 。
範例2:表達式 aaa$ 在符合 xxx aaa xxx 時,配對結果為:失敗。因為 $ 要求與字串結束的地方匹配,因此,只有當 aaa 位於字串的結尾的時候,aaa$ 才能匹配,例如:xxx xxx aaa 。
範例3:表達式 .\b. 在配對 @@@abc 時,配對結果為:成功;符合的內容是:@a ;符合的位置是:開始於2,結束於4。
進一步說明:\b 與 ^ 和 $ 類似,本身不符任何字符,但是它要求它在匹配結果中所處位置的兩邊,其中一邊是 \w 範圍,另一邊是非 \w 範圍。
範例4:表達式 \bend\b 在符合 weekend,endfor,end 時,配對結果是:成功;配對的內容是:end ;符合到的位置是:開始於15,結束於18。
一些符號會影響表達式內部子表達式之間的關係:
#範例5:表達式 Tom|Jack 在符合字串 I' m Tom,he is Jack 時,匹配結果是:成功;匹配到的內容是:Tom;匹配到的位置是:開始於4,結束於7.匹配下一個時,匹配結果是:成功;匹配到的內容是:Jack ;配對到的位置是:開始於15,結束於19。
範例6:表達式 (go\s*)+ 在符合 Let's go go go! 時,配對結果為:成功;配對的內容為:go go go ;符合的位置是:開始於6,結束於14。
範例7:表達式 ¥(\d+\.?\d) 在配對 $10.9,¥20.5 時,配對的結果是:成功;符合的內容為:¥20.5 ;符合的位置是:開始於6,結束於10。單獨取得括號範圍所符合的內容是:20.5 。
3.正規表示式中的一些高階用法
3.1 配對次數中的貪婪與非貪婪
#貪婪模式:
##在使用修飾配對次數的特殊符號時,有幾種表示方法可以同時使同一個表達式能夠匹配不同的次數,例如:”{m, n}” ,”{m,}” ,? ,* ,+ ,具體匹配次數隨被匹配的字串而定。這種重複匹配不定次數的表達式在匹配過程中,總是盡可能多的匹配。例如,針對文本 dxxxdxxxd ,舉例如下: #由此可見,\w+ 在匹配的時候,總是盡可能多的匹配符合它規則的字符。雖然第二個舉例中,它沒有符合最後一個 d ,但那也是為了讓整個表達式匹配成功。同理,帶 * 和 “{m, n}” 的表達式都是盡可能多的匹配,帶 ? 的表達式在可匹配可不匹配的視乎,也是盡可能的 “要匹配” 。這種匹配原則就叫做 貪婪 模式。非貪婪模式:
在修飾匹配次數的特殊符號後再加上 ? 號,則可以使匹配次數不定的表達式盡可能少的匹配,使可匹配可不匹配的表達式,盡可能的 “不匹配” 。這種配對原則叫做 非貪婪 模式,也叫作 勉強 模式。若果少匹配就會導致整個正規表示式匹配失敗的時候,與貪婪模式類似,非貪婪模式會最小限度的再匹配一些,以使整個正則表達式匹配成功。舉例如下,針對文字「dxxxdxxxd」 舉例:
#更多的情況,舉例如下:
舉例1:表達式
aa
bb
</td>結果是:成功;配對的內容是:aa
bb
舉例2:相較之下,表達式
aa
bb
3.2 反向引用\1,\2…
#表達式在符合時,表達式引擎會將小括號 () 包含的表達式所匹配到的字串記錄下來。在取得符合結果的識貨,小括號包含的表達式所符合的字串可以單獨火球。這一點,在前面的舉例中,已經多次展示了。在實際應用場合中,當用某種邊界來查找,而索取的內容又不包含邊界時,必須使用小括號來指定所要的範圍。例如前面的
其實,」小括號包含的表達式所符合的字串」 不只是在符合結束之後才可以使用,在符合過程中也可以使用。表達式後邊的部分,可以引用前面 “括號內的子符合已經符合的字串” 。引用方法是 \ 加上一個數字。 \1引用第1對括號內符合的字串,\2 引用第2對括號內符合的字串…以此類推,如果一對括號內包含另一對括號,則外層的括號先排序號。換句話說,哪一對的左括號 ( 在前,那這一對就先排序號。
舉例1:表達式 ('|")(.*?)(/1) 在匹配'Hello',"World" 時,配對的結果是:成功;配對到的內容是:'Hello' 。 (\w)\1{4,} 在符合 aa bbbb abcdefg ccccc 111121111 999999999 時,配對結果為:成功;符合的內容為:cccccc 。範圍的字元至少重複5次,注意與 \w{5,} 之間的差異。 ).*?\4)?\s*)*>.*?/1> 在匹配
前邊的章節中,我講到了幾個代表抽象意義的特殊符號:^ ,$ ,\b 。有一個共同點,那就是:它們本身不匹配任何字符,只是對“字符串的兩頭” 或者“字符之間的縫隙” 附加了一個條件。對「兩頭」 或「縫隙」 附加條件的,更靈活的方法。
格式:(?=xxxxx) ,在符合的字串中,它對所處的「縫隙」 或「兩頭」 附加條件是:所在縫隙的右側,必須能夠匹配上 xxxxx 這部分的表達式。因為它只是在此作為這個縫隙上附加的條件,所以它並不影響後面表達式去真正匹配這個縫隙之後的字元。這就類似 \b ,本身不符合任何字元。 \b 只是將所在縫隙之前、之後的字元取來進行了一下判斷,不會影響後邊的表達式來真正的匹配。
範例1:表達式 Windows(?=NT|XP) 在符合 Windows 98 ,Windows NT ,Windows 2000 時,只會符合Windows NT 中的 Windows ,而其他的 Windows 則則不會被符合。
範例2:表達式 (\w)((?=\1\1\1)(\1))+ 在符合字串 aaa ffffff 9999999999 時,將可與6個 f 的前4個,可以配對9個 9 前7個。這個表達式可以解讀成:重複4次以上的字母 數字,則符合剩下最後2位元之前的部分。當然,這個表達式可以不這樣寫,在此的目的是作為演示之用。
格式:(?!xxxxx) ,所在縫隙的右側,必須無法符合 xxxxx 這部分錶達式。
範例3:表達式 ((?!\bstop\b).)+ 在符合 fdjka ljfdl stop fjdsla fdj 時,將從頭一直配對到 stop 之前的位置,如果字串中沒有 stop ,則將從頭開始配對到 stop 之前的位置,如果字串中沒有 stop ,則將匹配整個字串。
範例4:表達式 do(?!\w) 在符合字串 done,do,dog 時,只能符合 do 。在本條舉例中,do 後邊使用(?!\w) 和使用 \b 效果是一樣的。
反向預搜尋: (?
這兩種格式的概念和正向預搜尋是類似的,反向預搜尋要求的條件是:所在縫隙的「左側」 ,兩種格式分別要求必須能夠匹配和必須不能夠匹配指定的表達式,而不是去判斷右側。與 「正向預搜尋」 一樣的是它們都是對所在縫隙的一種附加太偶見,本身都不符合任何字元。
4.其他通用規則
4.1 規則一
表達式中,可以使用\xXX 和\uXXXX 表示一個字元(X 表示一個十六進位數)
4.2 規則二
在表達式\s ,\d ,\w ,\b 表示特殊意義的同時,對應的大寫字母表示相反的意義
4.3 規則三
在表達式中有特殊意義,需要新增\ 才能符合該字元本身的字元總表
#4.4 規則四
括號()內的子表達式,若果希望匹配結果不進行記錄供以後使用,可以使用(?:xxxxx) 格式。
舉例1:表達式 (?:(\w)\1)+ 符合 “a bbccdd efg” 時,結果是 “bbccdd” 。括號 (?:) 範圍的符合結果不進行記錄,因此 (\w) 使用 \1 來引用。
4.5 規則五
常用的表達式屬性設定簡介:Ignorecase ,Singleline ,Multiline ,Global
相關文章: