正則表達式

正則表達式

1.常用的元字符

代碼

說明

.

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

\w

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

\s

匹配任意的空白符

\d

匹配數字

\b

匹配單詞的開始或結束

^

匹配字符串的開始

$

匹配字符串的結束

+匹配重復1次或更多次

*匹配重復任意次(可能是0次)

有些正則表達式處理工具還有一個處理多行的選項。如果選中了這個選項,^和$的意義就變成了匹配行的開始處和結束處。

轉義字符:

如果要查找.或者*,必須使用轉義字符,\.和\*,這樣才能查找出.和*

例如:deerchao\.net匹配deerchao.net

C:\\Windows匹配C:\Windows

2.常用的限定符

代碼/語法

說明

*

重復零次或更多次

+

重復一次或更多次

?

重復零次或一次

{n}

重復n次

{n,}

重復n次或更多次

{n,m}

重復n到m次

例如:

Windows\d+匹配Windows后面跟1個或更多數字

^\w+匹配一行的第一個單詞(或整個字符串的第一個單詞,具體匹配哪個意思得看選項設置)

3.字符類

[aeiou]匹配任何一個英文元音字母

[.?!]匹配標點符號

[0-9]0到9任意一位數字,與\d含義一致

[a-z0-9A-Z]等同于\w

?能出現0次或1次

4.分枝條件

正則表達式里的分枝條件指的是有幾種規則,如果滿足其中任意一種規則都應該當成匹配,具體方法是用|把不同的規則分隔開。

注意:使用分枝條件時,要注意各個條件的順序。原因是匹配分枝條件時,將會從左到右的測試每個條件,如果滿足了某個分枝的話,就不會再去管其他的條件了。

5.反義

常用的反義代碼

代碼/語法

說明

\W

匹配任意不是字母,數字,下劃線,漢字的字符

\S

匹配任意不是空白符的字符

\D

匹配任意非數字的字符

\B

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

[^x]

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

[^aeiou]

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

例子:\S+匹配不包含空白符的字符串

]+>匹配用尖括號括起來的以a開頭的字符串

6.后向引用

后向應用用于重復搜索前面某個分組匹配的文本。

6.1規則:從左向右,以分組的左括號為標志,第一個出現的分組的組號為1,第二個為2,以此類推。

6.2常用分組語法

分類

代碼/語法

說明

捕獲

(exp)

匹配exp,并捕獲文本到自動命名的組里

(?exp)

匹配exp,并捕獲文本到名稱為name的組里,也可以寫成(?'name'exp)

(?:exp)

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

零寬斷言

(?=exp)

匹配exp前面的位置

(?<=exp)

匹配exp后面的位置

(?!exp)

匹配后面跟的不是exp的位置

(?

匹配前面不是exp的位置

注釋

(?#comment)

這種類型的分組不對正則表達式的處理產生任何影響,用于提供注釋讓人閱讀

第三個(?:exp)不會改變正則表達式的處理方式,只是這樣的組匹配的內容不會像前兩種那樣被捕獲到某個組里面,也不會擁有組號。

7.領寬斷言

7.1(?=exp)也叫零寬度正預測先行斷言,它斷言自身出現的位置的后面能匹配表達式exp。比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.時,它會匹配sing和danc。

7.2(?<=exp)也叫零寬度正回顧后發斷言,它斷言自身出現的位置的前面能匹配表達式exp。比如(?<=\bre)\w+\b會匹配以re開頭的單詞的后半部分(除了re以外的部分),例如在查找reading a book時,它匹配ading。

例子:下面這個例子同時使用了這兩種斷言:(?<=\s)\d+(?=\s)匹配以空白符間隔的數字(再次強調,不包括這些空白符)。

8.負向零寬斷言

8.1零寬度負預測先行斷言(?!exp),斷言此位置的后面不能匹配表達式exp。例如:\d{3}(?!\d)匹配三位數字,而且這三位數字的后面不能是數字;\b((?!abc)\w)+\b匹配不包含連續字符串abc的單詞。

8.2同理,我們可以用(?零寬度負回顧后發斷言來斷言此位置的前面不能匹配表達式exp:(?

8.3請詳細分析表達式(?<=<(\w+)>).*(?=<\/\1>),這個表達式最能表現零寬斷言的真正用途。

一個更復雜的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單HTML標簽內里的內容。(?<=<(\w+)>)指定了這樣的前綴:被尖括號括起來的單詞(比如可能是),然后是.*(任意的字符串),最后是一個后綴(?=<\/\1>)。注意后綴里的\/,它用到了前面提過的字符轉義;\1則是一個反向引用,引用的正是捕獲的第一組,前面的(\w+)匹配的內容,這樣如果前綴實際上是的話,后綴就是了。整個表達式匹配的是之間的內容(再次提醒,不包括前綴和后綴本身)。

注意:請詳細分析表達式(?<=<(\w+)>).*(?=<\/\1>),這個表達式最能表現零寬斷言的真正用途。

9.注釋

9.1小括號的另一種用途是通過語法(?#comment)來包含注釋。

9.2要包含注釋的話,最好是啟用“忽略模式里的空白符”選項,這樣在編寫表達式時能任意的添加空格,Tab,換行,而實際使用時這些都將被忽略。啟用這個選項后,在#后面到這一行結束的所有文本都將被當成注釋忽略掉。

9.3例如:

(?<=#斷言要匹配的文本的前綴

<(\w+)> #查找尖括號括起來的字母或數字(即HTML/XML標簽)

)#前綴結束

.*#匹配任意文本

(?=#斷言要匹配的文本的后綴

<\/\1>#查找尖括號括起來的內容:前面是一個"/",后面是先前捕獲的標簽

)#后綴結束

10.貪婪與懶惰

當正則表達式中包含能接受重復的限定符時,通常的行為是(在使整個表達式能得到匹配的前提下)匹配盡可能多的字符。以這個表達式為例:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱為貪婪匹配。

有時,我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它后面加上一個問號?。這樣.*?就意味著匹配任意數量的重復,但是在能使整個匹配成功的前提下使用最少的重復。現在看看懶惰版的例子吧:

a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用于aabab的話,它會匹配aab(第一到第三個字符)和ab(第四到第五個字符)。

10.1懶惰限定符

代碼/語法

說明

*?

重復任意次,但盡可能少重復

+?

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

??

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

{n,m}?

重復n到m次,但盡可能少重復

{n,}?

重復n次以上,但盡可能少重復

11.處理選項

11.1常用的處理選項

名稱

說明

IgnoreCase(忽略大小寫)

匹配時不區分大小寫。

Multiline(多行模式)

更改^和$的含義,使它們分別在任意一行的行首和行尾匹配,而不僅僅在整個字符串的開頭和結尾匹配。(在此模式下,$的精確含意是:匹配\n之前的位置以及字符串結束前的位置.)

Singleline(單行模式)

更改.的含義,使它與每一個字符匹配(包括換行符\n)。

IgnorePatternWhitespace(忽略空白)

忽略表達式中的非轉義空白并啟用由#標記的注釋。

ExplicitCapture(顯式捕獲)

僅捕獲已被顯式命名的組。

注:一個經常被問到的問題是:是不是只能同時使用多行模式和單行模式中的一種?答案是:不是。這兩個選項之間沒有任何關系,除了它們的名字比較相似(以至于讓人感到疑惑)以外。

12.平衡組/遞歸匹配

這里介紹的平衡組語法是由.Net Framework支持的;其它語言/庫不一定支持這種功能,或者支持此功能但需要使用不同的語法。

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

?(?'group')把捕獲的內容命名為group,并壓入堆棧(Stack)

?(?'-group')從堆棧上彈出最后壓入堆棧的名為group的捕獲內容,如果堆棧本來為空,則本分組的匹配失敗

?(?(group)yes|no)如果堆棧上存在以名為group的捕獲內容的話,繼續匹配yes部分的表達式,否則繼續匹配no部分

(?!)零寬負向先行斷言,由于沒有后綴表達式,試圖匹配總是失敗

我們需要做的是每碰到了左括號,就在壓入一個"Open",每碰到一個右括號,就彈出一個,到了最后就看看堆棧是否為空--如果不為空那就證明左括號比右括號多,那匹配就應該失敗。正則表達式引擎會進行回溯(放棄最前面或最后面的一些字符),盡量使整個表達式得到匹配。

<#最外層的左括號

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

(

(

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

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

)+

(

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

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

)+

)*

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

>#最外層的右括號

平衡組的一個最常見的應用就是匹配HTML,下面這個例子可以匹配嵌套的

標簽:]*>[^<>]*(((?'Open']*>)[^<>]*)+((?'-Open'

)[^<>]*)+)*(?(Open)(?!)).

13.補充

13.1尚未詳細討論的語法

代碼/語法

說明

\a

報警字符(打印它的效果是電腦嘀一聲)

\b

通常是單詞分界位置,但如果在字符類里使用代表退格

\t

制表符,Tab

\r

回車

\v

豎向制表符

\f

換頁符

\n

換行符

\e

Escape

\0nn

ASCII代碼中八進制代碼為nn的字符

\xnn

ASCII代碼中十六進制代碼為nn的字符

\unnnn

Unicode代碼中十六進制代碼為nnnn的字符

\cN

ASCII控制字符。比如\cC代表Ctrl+C

\A

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

\Z

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

\z

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

\G

當前搜索的開頭

\p{name}

Unicode中命名為name的字符類,例如\p{IsGreek}

(?>exp)

貪婪子表達式

(?-exp)

平衡組

(?im-nsx:exp)

在子表達式exp中改變處理選項

(?im-nsx)

為表達式后面的部分改變處理選項

(?(exp)yes|no)

把exp當作零寬正向先行斷言,如果在這個位置能匹配,使用yes作為此組的表達式;否則使用no

(?(exp)yes)

同上,只是使用空表達式作為no

(?(name)yes|no)

如果命名為name的組捕獲到了內容,使用yes作為表達式;否則使用no

(?(name)yes)

同上,只是使用空表達式作為no

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容