快速回憶正規表示式

2021-07-01 18:12:17 字數 4284 閱讀 3325

這不是入門級文章,但如果你對正規表示式有了解,或使用過,則能幫助你快速回憶。閱讀此文需要你之前使用過正規表示式或者有些了解,因為我沒有寫很多的例子。總結正規表示式,只是因為個人在幾年的積累之後,想通俗簡單的概述正規表示式中各種符號和用法。網上有很多關於正規表示式,但總感覺專業術語太多,讀起來拗口或繞彎子。最後兩小節來自正規表示式30分鐘入門教程(如果你完全不了解正規表示式,還是先去這看看,因為他的例子較多,兩相比較有助深入理解),有部分修繕。

正規表示式字串由兩種基本字元組成:原義文字字元和元字元。所謂元字元就是正規表示式中具有特殊意義的專用字元,元字元可能是乙個字元,也可能是多個字元組成的乙個基本單元。

乙個元字元可能代表的是乙個數字、字母、位置或數量。

**

說明

.匹配除換行符以外的任意字元

\w匹配字母或數字或下劃線或漢字

\s匹配任意的空白符

\d匹配數字

\s與\s相反

\d與\d相反

\w與\w相反

**

說明

*重複零次或更多次

+重複一次或更多次

?重複零次或一次

重複n次

重複n次或更多次

重複n到m次

**

說明

\b匹配單詞的開始或結束

\b不是單詞開頭或結束的開始

^匹配字串的開始

$匹配字串的結束

既然元字元在正規表示式中有特殊意義,如果現在要把它們當成一般原義文字字元,怎麼辦?在元字元前新增反斜槓\,表示當前元字元已經失去了正規表示式中的特殊意義,變成了乙個原義文字字元。

元字元匹配範圍太廣,如果只是想匹配某小範圍內的字元,該怎麼辦?

很簡單,使用方括號列出來即可。如[aeiou]或[.?!],表示只能匹配方括號中出現的字元。

需要注意的是:在這個方括號中,代斜槓的元字元依然是元字元,但那些沒有斜槓字首的則都不再是元字元,但多了乙個元字元,就是連字元-。

在預定義字符集中,可以使用轉義字元

有時只需要查詢不屬於某個簡單定義的字符集的字元,這就是反義

**

說明

\w匹配任意不是字母,數字,下劃線,漢字的字元

\s匹配任意不是空白符的字元

\d匹配任意非數字的字元

\b匹配不是單詞開頭或結束的位置

[^x]

匹配除了x以外的任意字元

[^aeiou]

匹配除了aeiou這幾個字母以外的任意字元

這相當於或語句,具體方法是用垂直線|把不同的規則分隔開。如0\d-\d|0\d-\d這個表示式能匹配兩種以連字型大小分隔的**號碼:一種是三位區號,8位本地號(如010-12345678),一種是4位區號,7位本地號(0376-2233445)。

所謂分組,其實就是把小括號()中正規表示式作為乙個小的匹配單元。

分組的作用有兩個:

小組後跟代表數量的元字元有乙個問題需要注意:感覺應該是生成了若干個小組,但其實就是乙個分組,因為組號是解析器解析的時候給的,代表小組的字串在整個正規表示式字串中只出現了一次,所以只分配了乙個唯一的組號。因此,正規表示式執行完後,這個組匹配的內容是最後一次匹配的內容。

比如:/(\d\.)\d/g.exec("201.202.203.204");

結果:["201.202.203.204", "203."]

後面的正規表示式通過組號引用前面分組匹配的內容,這個就叫後向引用。組號的規則是:從左向右,以分組的左括號為標誌,第乙個出現的分組的組號為1,第二個為2,依此類推。引用的時候記得在組號前加上斜槓。

比如:/\b(\w+)\b\s+\1\b/.test("hellohello");  // true

/\b(\w+)\b\s+\1\b/.test("hellohell");  // false

分組的語法:

**/語法

說明

(exp)

匹配exp,並捕獲文字到自動命名的組裡

(?exp)

匹配exp,並捕獲文字到名稱為name的組裡,也可以寫成(?'name'exp)

(?:exp)

匹配exp,不捕獲匹配的文字,也不給此分組分配組號

零寬斷言像\b、^、$一樣用於指定乙個位置,但這個位置應該滿足一定的條件,這個條件就被稱之為斷言。因為這個斷言不像分組一樣有組號,不消耗匹配的字串,所以稱之為零寬斷言。

**/語法

說明

(?=exp)

斷言這個位置的後面,一定有匹配exp的內容;

(?<=exp)

斷言這個位置的前面,一定有匹配exp的內容;

(?!exp)

斷言這個位置的後面,一定沒有匹配exp的內容

(?斷言這個位置的前面,一定沒有匹配exp的內容

注釋用(?#comment)表示。

一段固定的正規表示式,它所能匹配的可能是整個字串,也可能只是整個字串的一部分。假如出現一段正規表示式既能匹配整個字串,也能只匹配部分該如何處理?

/h.*o/.exec("hello ho");  // ["hello ho"]

/h.*?o/.exec("helloho");  // ["hello"]

以上這個例子中,匹配hello使用的是懶惰匹配,而沒有問號限定的則是使用的貪婪匹配。

所謂貪婪匹配就是盡可能多的重複,以匹配盡可能多的字元。反之,懶惰匹配就是匹配盡可能少的字元。預設是貪婪演算法,只有在表示數量的元字元後使用了懶惰限定符(也就是問號)才表示這個地方使用懶惰演算法。

懶惰限定符

語法

說明

*?重複任意次,但盡可能少重複

+?重複1次或更多次,但盡可能少重複

??重複0次或1次,但盡可能少重複

?重複n到m次,但盡可能少重複

?重複n次以上,但盡可能少重複

前面講的所有匹配都是線性的,對於匹配像( 100 * ( 50 + 15 ) )這樣的可巢狀的層次性結構,則上面的一切方法都沒用。因為你不可能知道括號什麼時候出現,而且如果左括號和右括號出現的次數不相等怎麼辦?如何匹配到最長的,配對的括號之間的內容?

這裡需要用到以下的語法構造:

為了避免(和\(把你的大腦徹底搞糊塗,我們還是用尖括號代替圓括號吧。現在我們的問題變成了如何把xx aa> yy這樣的字串裡,最長的配對的尖括號內的內容捕獲出來?

<                         #最外層的左括號

[^<>]*                #最外層的左括號後面的不是括號的內容

(?'open'<)    #碰到了左括號,在黑板上寫乙個"open"

[^<>]*       #匹配左括號後面的不是括號的內容

(?'-open'>)   #碰到了右括號,擦掉乙個"open"

[^<>]*        #匹配右括號後面不是括號的內容

(?(open)(?!))         #在遇到最外層的右括號前面,判斷黑板上還有沒有沒擦掉的"open";如果還有,則匹配失敗

>                        #最外層的右括號

常用轉義字元及其他部分元字元

**/語法

說明

\a報警字元(列印它的效果是電腦嘀一聲)

\b通常是單詞分界位置,但如果在字元類裡使用代表退格

\t製表符,tab

\r回車

\v豎向製表符

\f換頁符

\n換行符

\eescape

\0nn

ascii**中八進位制**為nn的字元

\xnn

ascii**中十六進製制**為nn的字元

\unnnn

unicode**中十六進製制**為nnnn的字元

\cnascii控制字元。比如\cc代表ctrl+c

\a字串開頭(類似^,但不受處理多行選項的影響)

\z字串結尾或行尾(不受處理多行選項的影響)

\z字串結尾(類似$,但不受處理多行選項的影響)

\g當前搜尋的開頭

\punicode中命名為name的字元類,例如\p

正規表示式快速入門

你是不是經常忘記正規表示式中的語法規則 優先順序順序 界定符 定位符等等,每次看了忘忘了看,怎麼辦的,多練習或者小抄本記起來!1 常用元字元 匹配處換行符以外的任意字元 w匹配字母或數字或下劃線或漢字 s匹配任意的空白符 d匹配數字 b匹配單詞的開始或結束 匹配字串的開始 匹配字串的結束 2 常用限...

正規表示式快速入門

一 元字元 w,s,b,d 1.後面四個有相應的大寫,表反義。匹配行開頭,只有當其在 中表示 非 2.b 匹配單詞的開始或結束,而 匹配除換行符外的任意字元。eg 匹配乙個非空行 bstr 匹配 str開頭的字串 二 重複 請叫上面四位為 四大金剛 0個或多個 個或多個 個或 個 有三種寫法,和 不...

正規表示式快速入門

匹配除了換行符以外的任何字元 w 匹配字母或數字或下劃線或漢字 s 匹配任意的空白符 d 匹配數字 b 匹配單詞的開始或結束 匹配字串的開始 匹配字串的結束 匹配除了換行符以外的任何字元,算是 w 的加強版了 w 不能匹配 空格 如果把字串加上空格用 w 就受限了,看下用 如何匹配字元 b hj 4...