一、字面值字符
正則表達式的作用就是根據給定的字符樣式,來匹配目標字符串。而這種匹配方案中,最簡單的就是字面值字符的匹配。
那么,什么叫字面值字符匹配呢?簡單的說,就是輸入一個樣式 ABC ,就能把目標字符串“智能 ABC —輸入法,智能 ABC 輸入法,中文輸入法,打字,打字 ABC ,中文 ABC ”中所有的“ABC”給查找出來。但這個查找過程并不是一次性完成的,正則表達式引擎是先匹配第一個“ABC”,然后再從上一次成功匹配的地方進行第二次匹配。
在正則表達式中,有些字符符號被賦予了特殊的功能,它們通常被稱為元字符。如果要對這些字符進行匹配操作,我們就不能像 ABC 那樣直接使用。正則表達式為這類字符提供了一個轉義機制,就是在它們之前添加一個“/”作為轉義標識。比如我們要匹配“a+b=c”的話,正則表達式的語法就應該是 a/+b=c 。
二、字符集合
字符集合也被稱作字符類,它每次只用集合中的一個字符與目標字符串進行匹配。字符集合有兩種語法格式:第一種是采用枚舉的形式,把每個要匹配的元素放到方括號中 [你我他] ,這樣對字符串“是你嗎?不是我!是他?”的匹配的結果就是“是 你 嗎?不是 我 !是 他 ?”。
另外一種寫法就是指定字符范圍,比如我們用 [1-3] 來匹配“1982,1983”,結果就是“198 2 ,198 3 ”; [A-D] 對“BAD BOY”的匹配結果就是“ BAD B OY”
除此之外,正則表達式還提供了一種補集的形式,就是把不出現在集合內的字符作為匹配對象,它的語法格式就是在左方括號的右邊添加一個“^”,正則表達式 [^1-3] 匹配“1982,1983”的結果就是“ 198 2, 198 3”。
三、元字符
元字符是被正則表達式預先保留下來的一部分字符,并有著特殊的含義。這些元字符大致可以分為兩類,一類用于字符匹配,一類作為正則表達式語法的一部分來使用。如“/d”就代表了 0 至 9 之間的數字,“/s”表示空白符號,其中包括空格、制表符和換行符等,它們就是用于字符串匹配的;但是像字符集合中用到的“[”和“]”,就是被當作正則表達式語法的一部分來使用的。我們這里所介紹的都是一般的通用含義,對于這些元字符的精確含義,取決于我們所使用的軟件或程序語言,因為不同的工具或程序語言都對原始的正則表達式或多或少地進行了修改或補充。
常見的用于字符匹配的元字符有“/r”——回車符、“/n”——換行符、“/t”——制表符、“/s”——空白符、“/d”——數字 0 至 9、“/w”——字母數字與下劃線的組合。其中,還有一組匹配內容恰好與“/s”、“/d”、“/w”相反的 “/S”、“/D”、“/W”,如“/S”,就是與非空白字符相匹配的。
四、匹配任意字符的“.”
在正則表達式中,“.”的匹配范圍最廣泛,它幾乎能與所有的字符相匹配,但換行符除外。所以,它相當于Unix下的 [^/n] 和Windows下的 [^/r/n] 。
再次提醒一下,我們這里介紹的內容是最通用的基本含義,雖然“.”不能與換行符匹配,但在有些程序語言中,如 Java,就可以通過一種 Pattern.DOTALL 的匹配模式來讓“.”與換行符相匹配,下面一段話是JavaDoc中的一段原文:
In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators. — 在 dotall 模式下,表達式 . 與任意字符匹配,包括行終結符。該表達式在默認情況下是不與行終結符相匹配的。
五、邊界
邊界不與任何字符相匹配,但它們能夠與位置相匹配,如果不在指定位置的話,即使內容都正則表達式相符,也是不能成功匹配的。邊界分為詞邊界和行邊界兩種,符號分別是 /b 和 ^$ 。
當我們要匹配與單詞 cat 一致的字符串時,可以直接用 cat ,但是匹配的結果“Con cat the word cat and dog.”并不能令我們滿意。如果加上詞界限定,用 /bcat/b 來進行匹配,效果就很明顯—“Concat the word cat and dog.”,“/b”的作用就是要確保“cat”必須是一個獨立單詞。
行邊界分為行的起始邊界“^”和行的終止邊界“$”。要與字符串“beginning of line border”的起始字符“b”相匹配的話,就可以使用 ^b ,結果就是“ b egining of line border”。
六、重復匹配
在實際應用中,我們常常需要反復使用某個正則表達式樣式,比如說要匹配電話號碼的格式為0123-88888888,如果不使用正則表達式的重復匹配功能時,我們所編寫的正則表達式將是 /d/d/d/d-/d/d/d/d/d/d/d/d ,顯然,這樣是很繁瑣的,并且要求我們在使用中要十分小心,一不小心遺漏了一個 /d ,那將是件很麻煩的事情。
幸運的是,正則表達式中為我們提供了重復匹配的功能,重新改寫上面的正則表達式為 /d{4}-/d{8} ,一下子就簡潔了許多。
花括號只是重復匹配功能一種形式,還有諸如“?”、“*”和“+”等重復匹配形式,它們的含義分別為:匹配零次或一次、匹配零次或更多次、匹配一次或更多次。
七、貪婪式與懶惰式
與重復匹配密切相關的一個概念就是重復匹配的模式:貪婪式和懶惰式。從書面意義上看,貪婪式就是匹配盡可能多的字符,而懶惰式當然是越少越好了。我們現在用字符串“ABC123”做個例子,首先構造使用了重復匹配功能的正則表達式 ABC/d+ ,這時匹配的結果就是“ ABC123 ”;如果換成 ABC/d+? 的話,匹配的結果就是“ ABC1 23”。這下明白了吧,字符“+”使前面的“/d”不斷的重復,在貪婪模式下,只要有滿足匹配條件的,引擎就會進行下一次匹配操作,直到最后一次無法找到匹配內容時才善罷甘休;相比之下,懶惰模式下的正則表達式是很容易得到滿足的,只要有一個滿足匹配條件的內容,它就會立即終止匹配操作,返回結果。
八、選擇
有時候,我們要匹配的內容不是很固定,這就需要提供多個備選方案。在正則表達式中“|”就能幫助我們實現按這樣的效果。字符串“Superman can swim, run and fly!”用 swim|run|fly 進行匹配的結果就是“Superman can swim , run and fly !”
九、捕獲組與逆向引用
對于詞組“look down upon”和“look down on”來說,它們的含義相同,如果我們要寫一個同時匹配這兩個詞組的正則表達式該怎么做呢?難道是 look down upon|look down on ?當然不是!在正則表達式中,有一種稱為捕獲組的語法,它能讓我們把某個樣式作為一個獨立的單元來進行處理,這樣就能對它使用各種限定修飾符,如“?”、“*”、“+”和花括號等。所以, look down (up)?on 才是正確匹配詞組“look down upon”和“look down on”的正則表達式;當然,這也不是唯一一個簡潔的寫法,我們還可以用“選擇”編寫 look down (upon|on) 來進行匹配。
使用圓括號時可以創建捕獲組,捕獲組的作用是把匹配到的內容“記憶”下來,這樣我們就能利用逆向引用獲得滿足匹配條件的內容。
利用捕獲組就能讓我們使用逆向引用,更加靈活方便地進行樣式匹配操作。但是這種靈活性是我們用更多的計算機資源所換取的,如果僅僅是為了進行匹配,并沒有要使用逆向引用的需求時,完全可以取消捕獲組。改寫上面的正則表達式為 look down (?:up)?on 。
十、斷言
當我們要按照某一定條件來匹配一個目標字符串時,就可以使用斷言。斷言的作用是確保要匹配的內容的前方或后方必須是或不是我們指定的內容。
比如要找到所有那些以字符串“anti-”開頭的所有單詞,首先編寫正則表達式 anti-/b/w+/b ,這時匹配字符串“anti-imperialism, anti-consumerism, anti-aircraft, anti-semitism, anti-fertilizin”的結果就是“ anti-aircraft , anti-semitism , anti-fertilizin ”。現在我們使用后向斷言重新編寫正則表達式 (?<=anti-)/b/w+/b ,匹配的結果就是“anti- aircraft , anti- semitism , anti- fertilizin ”。
從例子可以看出,斷言部分的正則表達式雖然也參與字符串匹配,但它并不把自身作為匹配結果的一部分。
<!-- InstanceEndEditable -->
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
