轉載文章:http://www.jb51.net/tools/zhengze.html提取精華部分
1、 常用的元字元
. |
匹配除分行符號以外的任一字元 |
\w |
匹配字母或數字或底線,[a-zA-Z0-9] |
\s |
匹配任意的空白符,[\t\n\r\f] |
\d |
匹配數字,[0-9] |
\b |
匹配單詞的開始或結束 |
^ |
匹配字串的開始 |
$ |
匹配字串的結束 |
2、 常用的反義代碼
\W |
與\w相反,[^a-zA-Z0-9] |
\S |
與\s相反,[^\t\n\r\f] |
\D |
與\d相反,[^0-9] |
\B |
匹配不是單詞開頭或結束的位置 |
[^aeiou] |
匹配除了aeiou這幾個字母以外的任一字元 |
3、 常用的限定符
* |
重複零次或更多次 |
+ |
重複一次或更多次 |
? |
重複零次或一次 |
{n} |
重複n次 |
{n,} |
重複n次或更多次 |
{n,m} |
重複n到m次 |
4、 後向引用
使用小括弧指定一個子運算式後,匹配這個子運算式的文本(也就是此分組捕獲的內容)可以在運算式或其它程式中作進一步的處理。預設情況下,每個分組會自動擁有一個組號,規則如下:
l 分組0對應整個Regex;
l 從左向右掃描兩遍,第一遍只給未命名組分配,第二遍只給命名組分配;
l 可以使用(?:exp)這樣的文法來剝奪一個分組對組號分配的參與權。
後向引用用於重複搜尋前面某個分組匹配的文本,例如,\1代表分組1匹配的文本。\b(\w+)\b\s+\1\b可以用來匹配重複的單詞,像go go, 或者kitty kitty。這個運算式首先是一個單詞,也就是單詞開始處和結束處之間的多於一個的字母或數字(\b(\w+)\b),這個單詞會被捕獲到編號為1的分組中,然後是1個或幾個空白符(\s+),最後是分組1中捕獲的內容(也就是前面匹配的那個單詞)(\1)。
也可以自己指定子運算式的組名(?'Word'\w+),這樣就把\w+的組名指定為Word了,要反向引用這個分組捕獲的內容,你可以使用\k'Word',所以上一個例子也可以寫成這樣:\b(?'Word'\w+)\b\s+\k'Word'\b。
5、 常用分組文法
捕獲 |
(exp) |
匹配exp,並捕獲文本到自動命名的組裡 |
(?<name>exp) |
匹配exp,並捕獲文本到名稱為name的組裡,也可以寫成(?'name'exp) |
(?:exp) |
匹配exp,不捕獲匹配的文本,也不給此分組分配組號 |
零寬斷言 |
(?=exp) |
匹配exp前面的位置 |
(?<=exp) |
匹配exp後面的位置 |
(?!exp) |
匹配後面跟的不是exp的位置 |
(?<!exp) |
匹配前面不是exp的位置 |
注釋 |
(?#comment) |
不對Regex的處理產生任何影響,用於提供注釋讓人閱讀 |
6、 零寬斷言
零寬斷言用於尋找在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們像\b,^,$那樣用於指定一個位置,這個位置應該滿足一定的條件(即斷言)。Regex中只有當斷言為真時才會繼續進行匹配。
(?=exp)也叫零寬度正預測先行斷言,它斷言自身出現的位置的後面能匹配運算式exp。比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如尋找I'm singing while you're dancing時,它會匹配sing和danc。
(?<=exp)也叫零寬度正回顧後發斷言,它斷言自身出現的位置的前面能匹配運算式exp。比如(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re以外的部分),例如在尋找reading a book時,它匹配ading。
一個複雜的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單HTML標籤內裡的內容。
要包含注釋的話,最好是啟用“忽略模式裡的空白符”選項,這樣在編寫運算式時能任意的添加空格,Tab,換行,而實際使用時這些都將被忽略。啟用這個選項後,在#後面到這一行結束的所有文本都將被當成注釋忽略掉。例如,可以前面的一個運算式寫成這樣:
(?<= # 斷言要匹配的文本的首碼
<(\w+)> # 尋找角括弧括起來的字母或數字(即HTML/XML標籤)
) # 首碼結束
.* # 匹配任意文本
(?= # 斷言要匹配的文本的尾碼
<\/\1> # 尋找角括弧括起來的內容:前面是一個"/",後面是先前捕獲的標籤
) # 尾碼結束
7、 貪婪與懶惰
當Regex中包含能接受重複的限定符時,通常的行為是在使整個運算式能得到匹配的前提下匹配儘可能多的字元。以這個運算式為例:a.*b,它將會匹配最長的以a開始,以b結束的字串。如果用它來搜尋aabab的話,它會匹配整個字串aabab。這被稱為貪婪匹配。有時,我們更需要懶惰匹配,也就是匹配儘可能少的字元。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它後面加上一個問號?。這樣.*?就意味著匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。
a.*?b匹配最短的,以a開始、以b結束的字串。如果把它應用於aabab的話,它會匹配aab(第一到第三個字元)和ab(第四到第五個字元)。Regex有另一條規則,比懶惰/貪婪規則的優先順序更高: The match that begins earliest wins。
*? |
重複任意次,但儘可能少重複 |
+? |
重複1次或更多次,但儘可能少重複 |
?? |
重複0次或1次,但儘可能少重複 |
{n,m}? |
重複n到m次,但儘可能少重複 |
{n,}? |
重複n次以上,但儘可能少重複 |
8、 平衡組遞迴匹配
有時需要匹配像<100*<50+15>>這樣的可嵌套的層次性結構,這時簡單地使用<.+>則只會匹配到最左邊的左括弧和最右邊的右括弧之間的內容(這裡我們討論的是貪婪模式,懶惰模式也有下面的問題)。假如原來的字串裡的左括弧和右括弧出現的次數不相等,比如<5/<3+2>>>,那我們的匹配結果裡兩者的個數也不會相等。能不能把最長的配對的角括弧內的內容捕獲出來?
(?'group') |
把捕獲的內容命名為group,並壓入堆棧(Stack) |
(?'-group') |
從堆棧上彈出最後壓入堆棧的名為group的捕獲內容,如果堆棧本來為空白,則本分組的匹配失敗 |
(?(group)yes|no) |
如果堆棧上存在以名為group的捕獲內容的話,繼續匹配yes部分的運算式,否則繼續匹配no部分 |
(?!) |
零寬負向先行斷言,由於沒有尾碼運算式,試圖匹配總是失敗 |
我們需要做的是每碰到了左括弧,就在壓入一個"Open",每碰到一個右括弧,就彈出一個,到了最後就看看堆棧是否為空白,如果不為空白那就證明左括弧比右括弧多,那匹配就應該失敗。Regex引擎會進行回溯(放棄最前面或最後面的一些字元),盡量使整個運算式得到匹配。
< #最外層的左括弧
[^<>]* #最外層的左括弧後面的不是括弧的內容
(
(
(?'Open'<) #碰到了左括弧,入堆棧"Open"
[^<>]* #匹配左括弧後面的不是括弧的內容
)+
(
(?'-Open'>) #碰到了右括弧,出堆棧"Open"
[^<>]* #匹配右括弧後面不是括弧的內容
)+
)*
(?(Open)(?!)) #在遇到最外層的右括弧前面,判斷堆棧中是否有Open,如果還有,則匹配失敗
> #最外層的右括弧
平衡組的一個最常見的應用就是匹配HTML,下面這個例子可以匹配嵌套的<div>標籤:<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>。
9、 常用Regex
網址(URL) |
[a-zA-z]+://[^\s]* |
IP地址 |
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) |
電子郵件 |
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* |
QQ號碼 |
[1-9]\d{4,} |
HTML標記(包含內容或自閉合) |
<(.*)(.*)>.*<\/\1>|<(.*) \/> |
密碼(由數字/大寫字母/小寫字母/標點符號組成,四種都必有,8位以上) |
(?=^.{8,}$)(?=.*\d)(?=.*\W+)(?=.*[A-Z])(?=.*[a-z])(?!.*\n).*$ |
日期(年-月-日) |
(\d{4}|\d{2})-((0?([1-9]))|(1[1|2]))-((0?[1-9])|([12]([1-9]))|(3[0|1])) |
日期(月/日/年) |
((0?[1-9]{1})|(1[1|2]))/(0?[1-9]|([12][1-9])|(3[0|1]))/(\d{4}|\d{2}) |
時間(小時:分鐘,24小時制) |
((1|0?)[0-9]|2[0-3]):([0-5][0-9]) |
漢字(字元) |
[\u4e00-\u9fa5] |
中文及全形標點符號(字元) |
[\u3000-\u301e\ufe10-\ufe19\ufe30-\ufe44\ufe50-\ufe6b\uff01-\uffee] |
中國大陸固定電話號碼 |
(\d{4}-|\d{3}-)?(\d{8}|\d{7}) |
中國大陸手機號碼 |
1\d{10} |
中國大陸郵遞區號 |
[1-9]\d{5} |
中國大陸社會安全號碼(15位或18位) |
\d{15}(\d\d[0-9xX])? |
非負整數(正整數或零) |
\d+ |
正整數 |
[0-9]*[1-9][0-9]* |
負整數 |
-[0-9]*[1-9][0-9]* |
整數 |
-?\d+ |
小數 |
(-?\d+)(\.\d+)? |