正規表示式 2018 08 07

2022-05-07 10:09:09 字數 4319 閱讀 4055

參考:正規表示式30分鐘入門教程

元字元 metacharacter

\b : 匹配單詞的開始或結尾,只匹配乙個位置

. (點) 匹配除換行符以外的任何字元

\d 匹配數字 0-9

\s 匹配任意的空白符,包括空格、製表符、換行符、中文全形空格等

\w 匹配字母、數字、下劃線

^ 匹配字串的開始

$匹配字串的結束,比如 乙個**要求你填寫的qq號必須為5-12位數字時,可以使用^\d$,單獨的表示不多不少重複2次,表示重複的次數不能少於5次,不能多餘12次。

如果選中了處理多行的選項,^和$的意義為 匹配行的開始和結束處

() 也是元字元,用來分組

如果要查詢元字元本身,比如 . 和 * ,就需要使用反斜槓 \ 來進行轉義,查詢反斜槓 \,也得用 \\

限定符 指定數量的**

**說明

*重複 0 次或者重複多次

+重複 1 次或者重複多次

?重複 0 次或者 1 次

重複了 n 次

重複了 n 次或者更多次

重複 m 到 n次

字元類使用中括號

[aeiou]匹配任何乙個母音字母

[.?!]匹配標點符號 . ? !

[0-9]匹配數字 0-9 與\d代表的意義相同

[0-9a-za-z]\w等價

\(?0\d[(-]?\d首先是乙個轉義字元\(它出現0次或1次(?), 然後是數字 0,後面跟著 2 個數字 (\d), 然後是空格或者-中的乙個,它出現1次或者不出現(?),最後是8個數字(\d) 。上式可以匹配010)88886666,或022-22334455,或02912345678等常見**號碼格式,但是也能匹配 010)12345678或(022-87654321這樣的「不正確」的格式,因此就要使用下面的 分支條件

分支條件

|號把不同的規則分隔開

e.g.\(0\d\)[- ]?\d|0\d[- ]?\d這個表示式匹配三位區號的**號碼,其中區號可以用小括號括起來,也可以不用,區號與本地號支架你可以用連字型大小或空格間隔,也可以不用。

注意: 匹配分支條件時,將會從左到右地測試每個條件,如果滿足了某個條件將不會再去管其他的條件分組

e.g. 描述乙個ip位址

((2[0-4]\d|25[0-5]|[01]?\d\d?)\.)(2[0-4]\d|25[0-5]|[01]?\d\d?)

要點:2[0-4]\d|25[0-5]|[01]?\d\d?分為三種情況:

反義採用大寫的方式,與原來的小寫方式表達相反的含義

**說明

\w

\w相對應,匹配不是字母、數字、下劃線的字元

\s

\s相對應,匹配任何不是空白符的字元

\d

\d相對應,匹配任意非數字的字元

\b

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

[^x]

匹配除x以外的字元

[^aeiou]

匹配除aeiou以外的任意字元

後向引用

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

後向引用用於重複搜尋前面某個分組匹配的文字,\1代表分組1匹配的文字

e.g.

**說明

(exp)

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

(?exp)

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

?:exp

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

零寬斷言

e.g.(?<=\s)\d+(?=\s)匹配以空白字元間隔的數字(不包括這些空白字元)

負向零寬斷言

(?!exp)斷言此位置的後面不能匹配表示式 exp

e.g.

\d(?!\d)匹配三位數字,而且這三位數字的後面不能是數字

\b((?!abc)\w)+\b匹配不包含連續字串 abc 的單詞

乙個更複雜的例子:(?<=<(\w+)>).*(?=<\/\1>)

匹配不包含屬性的簡單html標籤內的內容;(?<=<(\w+)>)指定了這樣的字首:被尖括號括起來的單詞;然後是.*,即任意字串,最後是乙個字尾?=<\/\1>,這裡\/(斜槓和反斜槓)b用到了前面的字元轉義;\1用到了反向引用,引用的正是捕獲的第一組\w+匹配的內容,這樣,如果字首是, 那字尾就是 ;整個表示式匹配的是和之間的內容(不包括字首和字尾)

注釋

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

<(\w+)> #查詢尖括號括起來的字母或數字(即html或xml標籤)

) #字首結束

.* #匹配任意文字

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

<\/\1> #查詢尖括號括起來的內容

) #字尾結束

貪婪與懶惰

**說明

*?

重複任意次,但是盡可能少的重複

+?

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

??

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

?

重複 m-n 次,但是盡可能少重複

?

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

平衡組/遞迴匹配

有時我們需要匹配像( 100 * ( 50 + 15 ) )這樣的可巢狀的層次性結構,這時簡單地使用(.+)則只會匹配到最左邊的左括號和最右邊的右括號之間的內容(這裡我們討論的是貪婪模式,懶惰模式也有下面的問題)。假如原來的字串裡的左括號和右括號出現的次數不相等,比如( 5 / ( 3 + 2 ) ) ),那我們的匹配結果裡兩者的個數也不會相等。有沒有辦法在這樣的字串裡匹配到最長的,配對的括號之間的內容呢?

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

這裡將用到一下語法:

思路:每碰到左括號,就壓入乙個 "open" ,每碰到乙個右括號,就彈出乙個,到了最後看堆疊是否為空,如果不為空則證明左括號比右括號多,那匹配就應該失敗。正規表示式會進行回溯(放棄最前面或最後面的一些字元),盡量使整個班表示式得到匹配

<				#最外層的左括號

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

( (

(?'open'<) #匹配到了左括號,往堆疊壓入乙個'open'

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

)+ #可以出現多次

( (?'-open'>) #碰到了右括號,則從堆疊彈出乙個'open'

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

)+ #可以出現多次

)* #整個上面可以出現多次

(?(open)(?!)) #在遇到最外層的右括號前面,判斷堆疊上是否還有"open",

#如果還有,則執行 (?!),由於後面沒有字尾表示式,匹配總是失敗

> #最外層的括號

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

非負整數 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正規表示式 編寫正規表示式

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