1. 程式人生 > >玩轉正則表示式(Regular),這個世界正在獎勵偷偷用心的人

玩轉正則表示式(Regular),這個世界正在獎勵偷偷用心的人

宣告:以下只是本人學習正則表示式的筆記概要,主要參考:

1.必記的常用元字元:

.匹配除換行符以外的任意字元
\w 匹配字母或數字或下劃線或漢字 \W表示與之相反
\s匹配任意的空白符\S表示與之相反
\d匹配數字\D表示與之相反
\b匹配單詞的開始或結束\B表示與之相反
^匹配字串的開始 
$匹配字串的結束
[x] 匹配字元x [^x]表示出來字元x以外的任意字元
[aeiou] 匹配英語中的母音字母 [^aeiou]表示除了母音字母以外的所有字元

2.必記的常用限定符

* 重複零次或更多次
+ 重複一次或更多次
? 重複零次或一次
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次

3.必記的常用分組語法


小括號表示一個子表示式,匹配這個子表示式也就是捕獲匹配到的文字,預設情況下,每個分組會自動擁有一個組號,

規則是:從左向右,以分組的左括號為標誌,第一個出現的分組的組號為1,第二個為2,以此類推,
組號分配過程是要從左向右掃描兩遍的:第一遍只給未命名組分配,第二遍只給命名組分配--因此所有命名組的組號都大於未命名的組號

3.1捕獲
(exp) 匹配exp,並捕獲文字到自動命名的組裡 \b(\w+)\b\s+\1\b可以用來匹配重複的單詞,像go go, 或者kitty kitty
(?<name>exp)匹配exp,並捕獲文字到名稱為name的組裡,也可以寫成(?'name'exp) 

上面的正則指定組名,可以寫成\b(?<Word>\w+)\b\s+\k<Word>\b
(?:exp) 匹配exp,不捕獲匹配的文字,也不給此分組分配組號 (?:@\w*)binguo\w*匹配@開頭包含binguo的字串 
(?:exp)不會改變正則表示式的處理方式,只是這樣的組匹配的內容不會像前兩種那樣被捕獲到某個組裡面,也不會擁有組號


3.2零寬斷言
(?=exp) 匹配exp前面的位置 

 \b\w+(?=ing\b) I'm singing while you're dancing 匹配singdanc
(?<=exp)匹配exp後面的位置

(?<=\bre)\w+\b

reading a book 匹配ading

(?<=\s)\d+(?=\s)匹配以空白符間隔的數字(再次強調,不包括這些空白符)
(?!exp) 匹配後面跟的不是exp的位置  

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

\d{3}(?!\d)匹配三位數字,而且這三位數字的後面不能是數字
(?<!exp)匹配前面不是exp的位置(?<![a-z])\d{7}匹配前面不是小寫字母的七位數字 
(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單HTML標籤內裡的內容

3.3註釋
(?#comment)這種型別的分組不對正則表示式的處理產生任何影響,用於提供註釋讓人閱讀
(?<=   #斷言要匹配的文字的字首
<(\w+)> #查詢尖括號括起來的字母或數字(即HTML/XML標籤)
)       #字首結束
.*     #匹配任意文字
(?=     #斷言要匹配的文字的字尾
<\/\1>  #查詢尖括號括起來的內容:前面是一個"/",後面是先前捕獲的標籤
)       # 字尾結束

4.必記的懶惰限定符

*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

貪婪匹配:在使整個表示式能得到匹配的前提下,匹配儘可能多的字元
a.*b,它將會匹配最長的以a開始,以b結束的字串。如果用它來搜尋aabab的話,它會匹配整個字串aabab。

懶惰(非貪婪)匹配:

也就是匹配儘可能少的字元,《2.必記的常用限定符》提到的限定符都可以被轉化為懶惰匹配模式,只要在它後面加上一個問號?
a.*?b匹配最短的,以a開始,以b結束的字串

如果把它應用於aabab的話,它會匹配aab(第一到第三個字元)和ab(第四到第五個字元)
為什麼第一個匹配的是aab(第一到第三個字元)而不是ab(第二到第三個字元)?
簡單地說,因為正則表示式有另一條規則,比懶惰/貪婪規則的優先順序更高:最先開始的匹配擁有最高的優先權

5.非常用正則表示式元素

\a報警字元(列印它的效果是電腦嘀一聲)
\b通常是單詞分界位置,但如果在字元類裡使用代表退格
\t製表符,Tab
\r回車
\v豎向製表符
\f換頁符
\n換行符
\eEscape
\0nnASCII程式碼中八進位制程式碼為nn的字元
\xnnASCII程式碼中十六進位制程式碼為nn的字元
\unnnnUnicode程式碼中十六進位制程式碼為nnnn的字元
\cNASCII控制字元。比如\cC代表Ctrl+C
\A字串開頭(類似^,但不受處理多行選項的影響)
\Z字串結尾或行尾(不受處理多行選項的影響)
\z字串結尾(類似$,但不受處理多行選項的影響)
\G當前搜尋的開頭
\p{name}Unicode中命名為name的字元類,例如\p{IsGreek}
(?>exp)貪婪子表示式
(?<x>-<y>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

附錄:

正則表示式本地及線上測試工具、MSDN官方正則表示式線上文件

IP地址匹配: ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) 
  
(\d{1,3}\.){3}\d{1,3}是一個簡單的IP地址匹配表示式。表示式順序分析:   
   
\d{1,3}匹配1到3位的數字,  
  
(\d{1,3}\.){3}匹配三位數字加上一個英文句號(這個整體也就是這個分組)重複3次,
最後再加上一個一到三位的數字(\d{1,3})