正規表示式入門教程 三

2021-07-26 16:13:32 字數 4151 閱讀 3770

這篇是正規表示式的第三篇,我們接著第二篇的知識點開始講:

有時需要查詢不屬於某個能簡單定義的字元類的字元。比如想查詢除了數字以外,其它任意字元都行的情況,這時需要用到反義:

表中上面四個字母都是大寫:\w , \s , \d , \b

例子:\s+

匹配不包含空白符的字串。

]+>

匹配用尖括號括起來的以a開頭且結尾的字串,a中間不能有》。

解析: 表示以和a開頭,結尾 ;[^>]+

表示a 中間不可以,且至少有乙個或更多的字元

強化理解: ^

的用法:

(1)^

表示表示式驗證的開始,要驗證的字串完整的匹配^後面的內容。比如: ^567     匹配「567」+str;

$ 表示表示式驗證的結束,要驗證的字串完整的匹配$前面的內容。 比如 567$       匹配str+"567";

^$結合起來   比如 ^567$              匹配 567;

(2)

^的另一種語意識非

比如 ^[^567]*$        匹配的字串不包含5、6、7任意字元

解釋:^

開始了乙個字串的匹配,表示定義需要匹配內容的乙個小節點的自定義,可以是很簡單的[5],或者複雜點的[a-z]的小寫字母或者[a-za-z]的字母限定。這裡的[^567]

就表示你定義的這個節點的內容不能是5、6、7中的任意乙個。最後$表示字串的匹配結束,你的字串不能包括多餘以^開頭以$結尾的內容。

使用小括號指定乙個子表示式後,匹配這個子表示式的文字(也就是此分組捕獲的內容)可以在表示式或其它程式中作進一步的處理。預設情況下,每個分組會自動擁有乙個組號,規則是:從左向右,以分組的左括號為標誌,第乙個出現的分組的組號為1,第二個為2,以此類推。

呃……其實,組號分配還不像我剛說得那麼簡單:

後向引用用於重複搜尋前面某個分組匹配的文字。例如,\1代表分組1匹配的文字。難以理解?請看示例:

\b(\w+)\b\s+\1\b

可以用來匹配重複的單詞,像go go

, 或者kitty kitty

。這個表示式首先是乙個單詞,也就是單詞開始處和結束處之間的多於乙個的字母或數字

(\b(\w+)\b

),這個單詞會**獲到編號為1的分組中,然後是1個或幾個空白符

(\s+

),最後是分組1中捕獲的內容(也就是前面匹配的那個單詞)

(\1)。

你也可以自己指定子表示式的組名。要指定乙個子表示式的組名,請使用這樣的語法:(?\w+)(或者把尖括號換成'也行:(?'word'\w+)),這樣就把\w+的組名指定為word了。要反向引用這個分組捕獲的內容,你可以使用\k,所以上乙個例子也可以寫成這樣:\b(?\w+)\b\s+\k\b。

使用小括號的時候,還有很多特定用途的語法。下面列出了最常用的一些:

我們已經討論了前兩種語法。第三個(?:exp)不會改變正規表示式的處理方式,只是這樣的組匹配的內容不會像前兩種那樣**獲到某個組裡面,也不會擁有組號。

反向引用這部分有點難,後面慢慢理解吧

表4中,接下來的四個用於查詢在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們像\b

,^,$

那樣用於指定乙個位置,這個位置應該滿足一定的條件(即斷言),因此它們也被稱為零寬斷言

。最好還是拿例子來說明吧:

斷言用來宣告乙個應該為真的事實。正規表示式中只有當斷言為真時才會繼續進行匹配。

(?=exp)

也叫零寬度正**先行斷言

,它斷言自身出現的位置的後面能匹配表示式exp

。比如\b\w+(?=ing\b)

,匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查詢i'm singing while you're dancing.時,它會匹配sing和danc。

(?<=exp)

也叫零寬度正回顧後發斷言

,它斷言自身出現的位置的前面能匹配表示式exp

。比如(?<=\bre)\w+\b

會匹配以re開頭的單詞的後半部分(除了re以外的部分),例如在查詢reading a book時,它匹配ading。

假如你想要給乙個很長的數字中每三位間加乙個逗號(當然是從右邊加起了),你可以這樣查詢需要在前面和裡面新增逗號的部分:((?<=\d)\d)+\b

,用它對1234567890進行查詢時結果是234567890

。下面這個例子同時使用了這兩種斷言:(?<=\s)\d+(?=\s)

匹配以空白符間隔的數字(再次強調,不包括這些空白符)

。前面我們提到過怎麼查詢不是某個字元或不在某個字元類裡的字元的方法(反義)。但是如果我們只是想要確保某個字元沒有出現,但並不想去匹配它時怎麼辦?例如,如果我們想查詢這樣的單詞--它裡面出現了字母q,但是q後面跟的不是字母u,我們可以嘗試這樣:

\b\w*q[^u]\w*\b

匹配包含後面不是字母u的字母q的單詞。

但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發現,如果q出現在單詞的結尾的話,像iraq,benq,這個表示式就會出錯。

這是因為[^u]總要匹配乙個字元,所以如果q是單詞的最後乙個字元的話,後面的[^u]

將會匹配q後面的單詞分隔符(可能是空格,或者是句號或其它的什麼),後面的\w*\b將會匹配下乙個單詞,於是\b\w*q[^u]\w*\b

就能匹配整個iraq fighting。

負向零寬斷言能解決這樣的問題,因為它只匹配乙個位置,並不消費任何字元。現在,我們可以這樣來解決這個問題:\b\w*q(?!u)\w*\b。

零寬度負**先行斷言

(?!exp)

,斷言此位置的後面不能匹配表示式exp

。例如:\d(?!\d)

匹配三位數字,而且這三位數字的後面不能是數字

;\b((?!abc)\w)+\b

匹配不包含連續字串abc的單詞。

同理,我們可以用(?

,零寬度負回顧後發斷言

來斷言此位置的前面不能匹配表示式exp

:(?匹配前面不是小寫字母的七位數字。

乙個更複雜的例子:(?<=).*(?=)

匹配不包含屬性的簡單html標籤內裡的內容。(?<=)

指定了這樣的字首:被尖括號括起來的單詞(比如可能是),然後是.*(任意的字串),最後是乙個字尾

(?=)

。注意字尾裡的\/,它用到了前面提過的字元轉義;\1則是乙個反向引用,引用的正是捕獲的第一組,前面的(\w+)匹配的內容,這樣如果字首實際上是的話,字尾就是了。整個表示式匹配的是之間的內容(再次提醒,不包括字首和字尾本身)。

請詳細分析表示式(?<=).*(?=),這個表示式最能表現零寬斷言的真正用途。

小括號的另一種用途是通過語法(?#comment)來包含注釋。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。

要包含注釋的話,最好是啟用「忽略模式裡的空白符」選項,這樣在編寫表示式時能任意的新增空格,tab,換行,而實際使用時這些都將被忽略。啟用這個選項後,在#後面到這一行結束的所有文字都將被當成注釋忽略掉。例如,我們可以前面的乙個表示式寫成這樣:

(?<=    # 斷言要匹配的文字的字首

# 查詢尖括號括起來的字母或數字(即html/xml標籤)

) # 字首結束

.* # 匹配任意文字

(?= # 斷言要匹配的文字的字尾

# 查詢尖括號括起來的內容:前面是乙個"/",後面是先前捕獲的標籤

) # 字尾結束

參考部落格:

正規表示式入門教程

元字元原義字元 非列印字元 字元類預定義類 邊界量詞 貪婪與懶惰 非貪婪 3.練習一下 先來看看幾個常用的案例。手機號碼正規表示式 1 345789 0 9 解釋 最外的 是正則的表示式的標誌,表示以什麼開頭,表示哪些可選項,表示出現幾次,以什麼結尾。手機號案例 以1開頭,第2位為 3,4,5,7,...

正規表示式入門教程

正規表示式,又稱正規表示法 常規表示法 英語 regular expression,在 中常簡寫為regex regexp或re 電腦科學的乙個概念。正規表示式使用單個字串來描述 匹配一系列符合某個句法規則的字串。在很多文字編輯器裡,正規表示式通常被用來檢索 替換那些符合某個模式的文字。在編寫處理字...

正規表示式入門教程

表1.常用的元字元 匹配除換行符以外的任意字元 w匹配字母或數字或下劃線或漢字 s匹配任意的空白符 d匹配數字 b匹配單詞的開始或結束 匹配字串的開始 匹配字串的結束 表2.常用的限定符 語法說明 重複零次或更多次 重複一次或更多次 重複零次或一次 重複n次 重複n次或更多次 重複n到m次 3 正規...