正規表示式

2021-05-27 15:54:11 字數 4126 閱讀 4509

正規表示式由一些普通字元和一些元字元(metacharacters)組成

正規表示式引擎的內部工作機制

知道正規表示式引擎是如何工作的有助於你很快理解為何某個正規表示式不像你期望的那樣工作。

有兩種型別的引擎:文字導向(text-directed)的引擎和正則導向(regex-directed)的引擎。jeffrey friedl把他們稱作dfa和nfa引擎。本文談到的是正則導向的引擎。這是因為一些非常有用的特性,如「惰性」量詞(lazy quantifiers)和反向引用(backreferences),只能在正則導向的引擎中實現。所以毫不意外這種引擎是目前最流行的引擎。

你可以輕易分辨出所使用的引擎是文字導向還是正則導向。如果反向引用或「惰性」量詞被實現,則可以肯定你使用的引擎是正則導向的。你可以作如下測試:將正規表示式<>應用到字串「regex not」。如果匹配的結果是regex,則引擎是正則導向的。如果結果是regex not,則是文字導向的。因為正則導向的引擎是「猴急」的,它會很急切的進行表功,報告它找到的第乙個匹配 。

·        正則導向的引擎總是返回最左邊的匹配

這是需要你理解的很重要的一點:即使以後有可能發現乙個「更好」的匹配,正則導向的引擎也總是返回最左邊的匹配。

當把<>應用到「he captured a catfish for his cat」,引擎先比較<>和「h」,結果失敗了。於是引擎再比較<>和「e」,也失敗了。直到第四個字元,<>匹配了「c」。<>匹配了第五個字元。到第六個字元<>沒能匹配「p」,也失敗了。引擎再繼續從第五個字元重新檢查匹配性。直到第十五個字元開始,<>匹配上了「catfish」中的「cat」,正規表示式引擎急切的返回第乙個匹配的結果,而不會再繼續查詢是否有其他更好的匹配。

字符集

字符集是由一對方括號「」括起來的字元集合。使用字符集,你可以告訴正規表示式引擎僅僅匹配多個字元中的乙個。如果你想匹配乙個「a」或乙個「e」,使用<<[ae]>>。你可以使用<>匹配gray或grey。這在你不確定你要搜尋的字元是採用美國英語還是英國英語時特別有用。相反,<>將不會匹配graay或graey。字符集中的字元順序並沒有什麼關係,結果都是相同的。

你可以使用連字元「-」定義乙個字元範圍作為字符集。<<[0-9]>>匹配0到9之間的單個數字。你可以使用不止乙個範圍。<<[0-9a-fa-f] >>匹配單個的十六進製制數字,並且大小寫不敏感。你也可以結合範圍定義與單個字元定義。<<[0-9a-fxa-fx]>>匹配乙個十六進製制數字或字母x。再次強調一下,字元和範圍定義的先後順序對結果沒有影響。

·        字符集的一些應用

查詢乙個可能有拼寫錯誤的單詞,比如<> 或 <>。

查詢程式語言的識別符號,<>。(*表示重複0或多次)

查詢c風格的十六進製制數<<0[xx][a-fa-f0-9]+>>。(+表示重複一次或多次)

·        取反字符集

在左方括號「[」後面緊跟乙個尖括號「^」,將會對字符集取反。結果是字符集將匹配任何不在方括號中的字元。不像「.」,取反字符集是可以匹配回車換行符的。

需要記住的很重要的一點是,取反字符集必須要匹配乙個字元。<>並不意味著:匹配乙個q,後面沒有u跟著。它意味著:匹配乙個q,後面跟著乙個不是u的字元。所以它不會匹配「iraq」中的q,而會匹配「iraq is a country」中的q和乙個空格符。事實上,空格符是匹配中的一部分,因為它是乙個「不是u的字元」。

如果你只想匹配乙個q,條件是q後面有乙個不是u的字元,我們可以用後面將講到的向前檢視來解決。

·        字符集中的元字元

需要注意的是,在字符集中只有4個 字元具有特殊含義。它們是:「] \ ^ -」。「]」代表字符集定義的結束;「\」代表轉義;「^」代表取反;「-」代表範圍定義。其他常見的元字元在字符集定義內部都是正常字元,不需要轉義。例如,要搜尋星號*或加號+,你可以用<<[+*]>>。當然,如果你對那些通常的元字元進行轉義,你的正規表示式一樣會工作得很好,但是這會降低可讀性。

在字符集定義中為了將反斜槓「\」作為乙個文字字元而非特殊含義的字元,你需要用另乙個反斜槓對它進行轉義。<<[\\x]>>將會匹配乙個反斜槓和乙個x。「]^-」都可以用反斜槓進行轉義,或者將他們放在乙個不可能使用到他們特殊含義的位置。我們推薦後者,因為這樣可以增加可讀性。比如對於字元「^」,將它放在除了左括號「[」後面的位置,使用的都是文字字元含義而非取反含義。如<<[x^]>>會匹配乙個x或^。<>會匹配乙個「]」或「x」。<<[-x]>>或<<[x-]>>都會匹配乙個「-」或「x」。

·        字符集的簡寫

因為一些字符集非常常用,所以有一些簡寫方式。

<<\d>>代表<<[0-9]>>;

<<\w>>代表單詞字元。這個是隨正規表示式實現的不同而有些差異。絕大多數的正規表示式實現的單詞字符集都包含了<>。

<<\s>>代表「白字元」。這個也是和不同的實現有關的。在絕大多數的實現中,都包含了空格符和tab符,以及回車換行符<<\r\n>>。

字符集的縮寫形式可以用在方括號之內或之外。<<\s\d>>匹配乙個白字元後面緊跟乙個數字。<<[\s\d]>>匹配單個白字元或數字。<<[\da-fa-f]>>將匹配乙個十六進製制數字。

取反字符集的簡寫

<<[\s]>> = <<[^\s]>>

<<[\w]>> = <<[^\w]>>

<<[\d]>> = <<[^\d]>>

·        字符集的重複

如果你用「?*+」操作符來重複乙個字符集,你將會重複整個字符集。而不僅是它匹配的那個字元。正規表示式<<[0-9]+>>會匹配837以及222。

如果你僅僅想重複被匹配的那個字元,可以用向後引用達到目的。我們以後將講到向後引用。

元字元

描述.點

匹配任何單個字元。例如正規表示式r.t匹配這些字串:rat、rut、r t,但是不匹配root。

$匹配行結束符。例如正規表示式weasel$ 能夠匹配字串"he's a weasel"的末尾

但是不能匹配字串"they are a bunch of weasels."

^匹配一行的開始。例如正規表示式^when in能夠匹配字串"when in the course of human events"的開始,但是不能匹配"what and when in the"

*匹配0或多個正好在它之前的那個字元。例如正規表示式。*意味著能夠匹配任意數量的任何字元。

\這是引用符,用來將這裡列出的這些元字元當作普通的字元來進行匹配。例如正規表示式\$被用來匹配美元符號,而不是行尾,類似的,正規表示式\.用來匹配點字元,而不是任何字元的萬用字元。

[ ]

[c1-c2]

[^c1-c2]

匹配括號中的任何乙個字元。例如正規表示式r[aou]t匹配rat、rot和rut,但是不匹配ret。可以在括號中使用連字元-來指定字元的區間,例如正規表示式[0-9]可以匹配任何數字字元;還可以制定多個區間,例如正規表示式[a-za-z]可以匹配任何大小寫字母。另乙個重要的用法是「排除」,要想匹配除了指定區間之外的字元——也就是所謂的補集——在左邊的括號和第乙個字元之間使用^字元,例如正規表示式[^269a-z] 將匹配除了2、6、9和所有大寫字母之外的任何字元。

\< \>

匹配詞(word)的開始(\<)和結束(\>)。例如正規表示式\能夠匹配字串"for the wise"中的"the",但是不能匹配字串"otherwise"中的"the"。注意:這個元字元不是所有的軟體都支援的。

\( \)

將 \( 和 \) 之間的表示式定義為「組」(group),並且將匹配這個表示式的字元儲存到乙個臨時區域(乙個正規表示式中最多可以儲存9個),它們可以用 \1 到\9 的符號來引用。

|將兩個匹配條件進行邏輯「或」(or)運算。例如正規表示式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:這個元字元不是所有的軟體都支援的。

+匹配1或多個正好在它之前的那個字元。例如正規表示式9+匹配9、99、999等。注意:這個元字元不是所有的軟體都支援的。

?匹配0或1個正好在它之前的那個字元。注意:這個元字元不是所有的軟體都支援的。

匹配指定數目的字元,這些字元是在它之前的表示式定義的。例如正規表示式a[0-9] 能夠匹配字元"a"後面跟著正好3個數字字元的串,例如a123、a348等,但是不匹配a1234。而正規表示式[0-9] 匹配連續的任意4個、5個或者6個數字字元。注意:這個元字元不是所有的軟體都支援的。

正規表示式 正規表示式 總結

非負整數 d 正整數 0 9 1 9 0 9 非正整數 d 0 負整數 0 9 1 9 0 9 整數 d 非負浮點數 d d 正浮點數 0 9 0 9 1 9 0 9 0 9 1 9 0 9 0 9 0 9 1 9 0 9 非正浮點數 d d 0 0 負浮點數 正浮點數正則式 英文本串 a za z...

正規表示式 表示式

網域名稱 a za z0 9 a za z0 9 a za z0 9 a za z0 9 interneturl a za z s 或 http w w w 手機號碼 13 0 9 14 5 7 15 0 1 2 3 5 6 7 8 9 18 0 1 2 3 5 6 7 8 9 d 號碼 x x x...

Linux正規表示式 編寫正規表示式

為了所有實用化的用途,你可以通過使用程式產生正確的結果。然而,並不意味著程式總是如你所願的那樣正確地工作。多數情況下,如果程式不能產生想要的輸出,可以斷定真正的問題 排除輸入或語法錯誤 在於如何描述想要的東西。換句話說,應該考慮糾正問題的地方是描述想要的結果的表示式。表示式不完整或者公式表示得不正確...