《正則表達式經典實例(第2版)》——第 2 章 正則表達式的基本技能 2.1匹配字麵文本
本節書摘來自異步社區《正則表達式經典實例(第2版)》一書中的第2章,第2.1節,作者: 【美】Jan Goyvaerts , Steven Levithan著,更多章節內容可以訪問雲棲社區“異步社區”公眾號查看
第 2 章 正則表達式的基本技能
本章要講解的問題並不是老板或客戶會要求你解決的那一類現實世界中的問題。相反,它們是在你創建和編輯正則表達式來解決現實世界問題的過程中會遇到的技術性問題。例如,第一個實例會解釋如何使用一個正則表達式來匹配字麵文本(literal text),以及如何處理正則表達式中有特殊含義的字符。這個問題本身並不是很重要,因為如果你隻是要查找字麵文本,並不需要使用正則表達式。但是,當創建正則表達式的時候,你可能會需要按照字麵來匹配某些文本,那麼你就需要知道哪些字符需要轉義。實例2.1會告訴你該如何實現。
本章前一部分的實例會講解一些非常基本的正則表達式技術。如果以前使用過正則表達式,那麼你大概可以略讀或者甚至是跳過它們。除非你已經從頭到尾認真讀過Jeffrey E. F. Friedl所著的《精通正則表達式》(Mastering Regular Expression)一書,否則在本章後一部分所給出的實例一定會教給你些新的東西。
本章實例的安排方式是每個實例會講解正則表達式語法的一個方麵。所有這些實例加在一起就形成了一份關於正則表達式的全麵指南。讀者可以先從頭到尾讀完本章以做到深入領會正則表達式。或者讀者也可以直接跳到第4~第8章中講解的現實世界中的正則表達式,而當在那些章節中遇到你不是很熟悉的語法時,再按照給出的引用跳回來閱讀本章中的相應內容。
2.1 匹配字麵文本
問題描述
創建一個正則表達式來嚴格匹配下麵這個複雜的句子:
The punctuation characters in the ASCII table are: !"#$%&'()*+,-./:;<=>?@[\] ^_`{|}~.
此實例用於演示哪些字符在正則表達式中有特殊含義,而哪些字符永遠按字麵匹配它們自身。
解決方案
The●punctuation●characters●in●the●ASCII●table●are:●↵
!"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\]\^_`\{\|}~
正則選項:無
正則流派:.NET、Java、JavaScript、PCRE、Perl、Python、Ruby
討論
任何不包含如下這些字符的正則表達式都可以簡單地匹配其自身:$()*+.?[^{|。如果要在正在編輯的文檔中查找是否包含Mary had a little lamb,那麼你隻需要簡單地查找‹Mary●had●a●little●lamb›即可。與你是否選中了文本編輯器中的“正則表達式”複選框並沒有關係。
正則表達式之所以擁有巨大的魔力,就是因為有了這12個標點字符,它們被稱作是元字符(metacharacter)。如果想要在正則表達式中照字麵匹配它們,就需要在它們前麵用一個反斜杠來進行轉義。因此,正則表達式
\$\(\)\*\+\.\?\[\\\^\{\|
會匹配文本
$()*+.?[\^{|
特別應該注意的是在這個列表中並不包含右方括號]、連字號-和右花括號}。前兩個符號隻有在它們位於一個沒有轉義的[之後才成為元字符,而}隻有在一個沒有轉義的{之後才是元字符。在任何時候都沒有必要對}進行轉義。在[和]之間出現的元字符的轉義規則會在實例2.3中加以解釋。
對任意其他非字母數字的字符進行轉義不會改變你的正則表達式的匹配結果—至少在本書中講到的所有流派中都不會改變。而對一個字母數字字符進行轉義則會給它一個特殊含義,或者出現一個語法錯誤。
新接觸正則表達式的人通常會對看到的每個標點字符進行轉義。不要讓任何人看出來你是個新手!要明智地選擇需要轉義的場合(時機)。一大堆不需要的反斜杠會使正則表達式變得難以閱讀,特別是當在源代碼中把正則表達式作為字符串來引用以至於所有這些反斜杠必須加倍出現的時候。
變體
塊轉義
當使用的正則流派支持塊轉義時,我們的解答可以更容易閱讀:
The●punctuation●characters●in●the●ASCII●table●are:●↵
\Q!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~\E
正則選項:無
正則流派:Java 6、PCRE、Perl
Perl、PCRE和Java支持使用正則表達式記號‹\Q›和‹\E›。‹\Q›可以消除包括反斜杠在內的所有元字符的特殊含義,直到出現‹\E›為止。如果漏掉了‹\E›,那麼在‹\Q›之後直到正則表達式結束之前的所有字符都會被當作字麵文本來對待。
使用‹\Q...\E›的唯一好處是它讀起來會比‹...›更容易一些。雖然Java 4和Java 5都支持這個特性,但是我們卻不推薦讀者使用它。實現中的bug導致含有‹\Q...\E›的正則表達式匹配到的內容與你的期望不同,並且與Java 6、PCRE或Perl所匹配的內容不一樣。這些bug在Java 6中得到了修正,使之與PCRE和Perl中的結果保持一致。
不區分大小寫的匹配
默認情況下,正則表達式是區分大小寫的。‹regex›會匹配regex,但是不能匹配Regex、REGEX或者ReGeX。要匹配所有這些形式,就需要打開不區分大小寫選項。
在大多數應用程序中,隻需要簡單地選中或取消一個複選框。在下一章中要講解的所有編程語言中都提供一個標誌或屬性,可以用它來標明你的正則表達式不區分大小寫。下一章中的實例3.4會講解如何在源代碼中應用本書每個正則表達式解答下列出的正則選項。
ascii
正則選項:不區分大小寫
正則流派:.NET、Java、JavaScript、PCRE、Perl、Python、Ruby
如果無法在正則表達式之外打開不區分大小寫選項的話,那麼你還可以在正則表達式之內通過使用‹(?i)›模式修飾符(mode modifier)來設置,如‹(?i) regex›。這個選項可以在.NET、Java、PCRE、Perl、Python和Ruby流派中使用。也可以在JavaScript XRegExp庫中使用。
(?i)ascii
正則選項:無
正則流派:.NET、Java、XRegExp、PCRE、Perl、Python、Ruby
.NET、Java、PCRE、Perl和Ruby支持局部模式修飾符,這樣它隻會影響到正則表達式的一部分。例如,‹sensitive(?i)caseless(?-i)sensitive›會匹配sensitiveCASELESS sensitive,但是不能匹配SENSITIVEcaselessSENSITIVE。在正則表達式中‹(?i)›後麵的字符不區分大小寫,而‹(?-i)›後麵的字符重新區分大小寫。它們結合在一起就可以像開關一樣來使用。
最後更新:2017-06-06 07:35:15