正則表達式的學習分享

一、    正則表達式

正則表達式(Regular Expression)是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱爲"元字符")。
正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。
正則表達式是煩瑣的,但它是強大的,學會之後的應用會讓你除了提高效率外,會給你帶來絕對的成就感。只要認真閱讀本教程,加上應用的時候進行一定的參考,掌握正則表達式不是問題。
許多程序設計語言都支持利用正則表達式進行字符串操作。
現在開始學習正則表達式!

實例:
以下實例從字符串 str 中找出數字:
實例:
從字符串 str 中提取數字部分的內容:
var str = "abc123def";
var patt1 = /[0-9]+/;
document.write(str.match(patt1));
以下標記的文本是獲得的匹配的表達式:
123

二、正則表達式--簡介:
例如,您很可能使用 ? 和 * 通配符來查找硬盤上的文件。? 通配符匹配文件名中的單個字符,而 * 通配符匹配零個或多個字符。像 data?.dat 這樣的模式將查找下列文件:
data1.dat
data2.dat
datax.dat
dataN.dat
使用 * 字符代替 ? 字符擴大了找到的文件的數量。data*.dat 匹配下列所有文件:
data.dat
data1.dat
data2.dat
data12.dat
datax.dat
dataXYZ.dat
儘管這種搜索方法很有用,但它還是有限的。通過理解 * 通配符的工作原理,引入了正則表達式所依賴的概念,但正則表達式功能更強大,而且更加靈活。
正則表達式的使用,可以通過簡單的辦法來實現強大的功能。下面先給出一個簡單的示例:
 
•    ^ 爲匹配輸入字符串的開始位置。
•    [0-9]+匹配多個數字, [0-9] 匹配單個數字,+ 匹配一個或者多個。
•    abc$匹配字母 abc 並以 abc 結尾,$ 爲匹配輸入字符串的結束位置。
實例
匹配以數字開頭,並以 abc 結尾的字符串。:
var str = "123abc";
var patt1 = /^[0-9]+abc$/;
document.write(str.match(patt1));
以下標記的文本是獲得的匹配的表達式:
123abc
________________________________________爲什麼使用正則表達式?
典型的搜索和替換操作要求您提供與預期的搜索結果匹配的確切文本。雖然這種技術對於對靜態文本執行簡單搜索和替換任務可能已經足夠了,但它缺乏靈活性,若採用這種方法搜索動態文本,即使不是不可能,至少也會變得很困難。
通過使用正則表達式,可以:
•    測試字符串內的模式。
例如,可以測試輸入字符串,以查看字符串內是否出現電話號碼模式或信用卡號碼模式。這稱爲數據驗證。
•    替換文本。
可以使用正則表達式來識別文檔中的特定文本,完全刪除該文本或者用其他文本替換它。
•    基於模式匹配從字符串中提取子字符串。
可以查找文檔內或輸入域內特定的文本。
例如,您可能需要搜索整個網站,刪除過時的材料,以及替換某些 HTML 格式標記。在這種情況下,可以使用正則表達式來確定在每個文件中是否出現該材料或該 HTML 格式標記。此過程將受影響的文件列表縮小到包含需要刪除或更改的材料的那些文件。然後可以使用正則表達式來刪除過時的材料。最後,可以使用正則表達式來搜索和替換標記。
________________________________________應用領域
目前,正則表達式已經在很多軟件中得到廣泛的應用,包括 *nix(Linux, Unix等)、HP 等操作系統,PHP、C#、Java 等開發環境,以及很多的應用軟件中,都可以看到正則表達式的影子。
C# 正則表達式
在我們的 C# 教程中,C# 正則表達式 這一章節專門介紹了有關 C# 正則表達式的知識。Java 正則表達式
在我們的 Java 教程中,Java 正則表達式 這一章節專門介紹了有關 Java 正則表達式的知識。
JavaScript 正則表達式
在我們的 JavaScript 教程中,JavaScript RegExp 對象 這一章節專門介紹了有關 JavaScript 正則表達式的知識,同時我們還提供了完整的 JavaScript RegExp 對象參考手冊。
Python 正則表達式
在我們的 Python 基礎教程中,Python 正則表達式 這一章節專門介紹了有關 Python 正則表達式的知識。
三、    正則表達式--語法
正則表達式(regular expression)描述了一種字符串匹配的模式(pattern),可以用來檢查一個串是否含有某種子串、將匹配的子串替換或者從某個串中取出符合某個條件的子串等。
例如:
•    runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 號代表前面的字符必須至少出現一次(1次或多次)。
•    runoo*b,可以匹配 runob、runoob、runoooooob 等,* 號代表字符可以不出現,也可以出現一次或者多次(0次、或1次、或多次)。
•    colou?r 可以匹配 color 或者 colour,? 問號代表前面的字符最多隻可以出現一次(0次、或1次)。
構造正則表達式的方法和創建數學表達式的方法一樣。也就是用多種元字符與運算符可以將小的表達式結合在一起來創建更大的表達式。正則表達式的組件可以是單個的字符、字符集合、字符範圍、字符間的選擇或者所有這些組件的任意組合。
正則表達式是由普通字符(例如字符 a 到 z)以及特殊字符(稱爲"元字符")組成的文字模式。模式描述在搜索文本時要匹配的一個或多個字符串。正則表達式作爲一個模板,將某個字符模式與所搜索的字符串進行匹配。
________________________________________普通字符
普通字符包括沒有顯式指定爲元字符的所有可打印和不可打印字符。這包括所有大寫和小寫字母、所有數字、所有標點符號和一些其他符號。
非打印字符
非打印字符也可以是正則表達式的組成部分。下表列出了表示非打印字符的轉義序列:
 特殊字符
所謂特殊字符,就是一些有特殊含義的字符,如上面說的 runoo*b 中的 *,簡單的說就是表示任何字符串的意思。如果要查找字符串中的 * 符號,則需要對 * 進行轉義,即在其前加一個 \: runo\*ob 匹配 runo*ob。
許多元字符要求在試圖匹配它們時特別對待。若要匹配這些特殊字符,必須首先使字符"轉義",即,將反斜槓字符\ 放在它們前面。下表列出了正則表達式中的特殊字符:
 限定符
限定符用來指定正則表達式的一個給定組件必須要出現多少次才能滿足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6種。
正則表達式的限定符有:
 
由於章節編號在大的輸入文檔中會很可能超過九,所以您需要一種方式來處理兩位或三位章節編號。限定符給您這種能力。下面的正則表達式匹配編號爲任何位數的章節標題:
/Chapter [1-9][0-9]*/
請注意,限定符出現在範圍表達式之後。因此,它應用於整個範圍表達式,在本例中,只指定從 0 到 9 的數字(包括 0 和 9)。
這裏不使用 + 限定符,因爲在第二個位置或後面的位置不一定需要有一個數字。也不使用?字符,因爲它將章節編號限制到只有兩位數。您需要至少匹配 Chapter 和空格字符後面的一個數字。
如果您知道章節編號被限制爲只有 99 章,可以使用下面的表達式來至少指定一位但至多兩位數字。
/Chapter [0-9]{1,2}/
上面的表達式的缺點是,大於 99 的章節編號仍只匹配開頭兩位數字。另一個缺點是 Chapter 0 也將匹配。只匹配兩位數字的更好的表達式如下:
/Chapter [1-9][0-9]?/

/Chapter [1-9][0-9]{0,1}/
*、+和?限定符都是貪婪的,因爲它們會盡可能多的匹配文字,只有在它們的後面加上一個?就可以實現非貪婪或最小匹配。
例如,您可能搜索 HTML 文檔,以查找括在 H1 標記內的章節標題。該文本在您的文檔中如下:
<H1>Chapter 1 - 介紹正則表達式</H1>
貪婪:下面的表達式匹配從開始小於符號 (<) 到關閉 H1 標記的大於符號 (>) 之間的所有內容。
/<.*>/
非貪婪:如果您只需要匹配開始和介紹 H1 標記,下面的非貪婪表達式只匹配 <H1>。
/<.*?>/
如果只想匹配開始的 H1 標籤,表達式則是:
/<\w+?>/
通過在 *、+ 或 ? 限定符之後放置 ?,該表達式從"貪心"表達式轉換爲"非貪心"表達式或者最小匹配。
/Chapter [1-9][0-9]?/

/Chapter [1-9][0-9]{0,1}/
*、+和?限定符都是貪婪的,因爲它們會盡可能多的匹配文字,只有在它們的後面加上一個?就可以實現非貪婪或最小匹配。
例如,您可能搜索 HTML 文檔,以查找括在 H1 標記內的章節標題。該文本在您的文檔中如下:
<H1>Chapter 1 - 介紹正則表達式</H1>
貪婪:下面的表達式匹配從開始小於符號 (<) 到關閉 H1 標記的大於符號 (>) 之間的所有內容。
/<.*>/
非貪婪:如果您只需要匹配開始和介紹 H1 標記,下面的非貪婪表達式只匹配 <H1>。
/<.*?>/
如果只想匹配開始的 H1 標籤,表達式則是:
/<\w+?>/
通過在 *、+ 或 ? 限定符之後放置 ?,該表達式從"貪心"表達式轉換爲"非貪心"表達式或者最小匹配。
 
注意:不能將限定符與定位點一起使用。由於在緊靠換行或者字邊界的前面或後面不能有一個以上位置,因此不允許諸如 ^* 之類的表達式。
若要匹配一行文本開始處的文本,請在正則表達式的開始使用 ^ 字符。不要將 ^ 的這種用法與中括號表達式內的用法混淆。
若要匹配一行文本的結束處的文本,請在正則表達式的結束處使用 $ 字符。
若要在搜索章節標題時使用定位點,下面的正則表達式匹配一個章節標題,該標題只包含兩個尾隨數字,並且出現在行首:
/^Chapter [1-9][0-9]{0,1}/
真正的章節標題不僅出現行的開始處,而且它還是該行中僅有的文本。它即出現在行首又出現在同一行的結尾。下面的表達式能確保指定的匹配只匹配章節而不匹配交叉引用。通過創建只匹配一行文本的開始和結尾的正則表達式,就可做到這一點。
/^Chapter [1-9][0-9]{0,1}$/
匹配字邊界稍有不同,但向正則表達式添加了很重要的能力。字邊界是單詞和空格之間的位置。非字邊界是任何其他位置。下面的表達式匹配單詞 Chapter 的開頭三個字符,因爲這三個字符出現字邊界後面:
/\bCha/
\b 字符的位置是非常重要的。如果它位於要匹配的字符串的開始,它在單詞的開始處查找匹配項。如果它位於字符串的結尾,它在單詞的結尾處查找匹配項。例如,下面的表達式匹配單詞 Chapter 中的字符串 ter,因爲它出現在字邊界的前面:
/ter\b/
下面的表達式匹配 Chapter 中的字符串 apt,但不匹配 aptitude 中的字符串 apt:
/\Bapt/
字符串 apt 出現在單詞 Chapter 中的非字邊界處,但出現在單詞 aptitude 中的字邊界處。對於 \B 非字邊界運算符,位置並不重要,因爲匹配不關心究竟是單詞的開頭還是結尾。
選擇
用圓括號將所有選擇項括起來,相鄰的選擇項之間用|分隔。但用圓括號會有一個副作用,是相關的匹配會被緩存,此時可用?:放在第一個選項前來消除這種副作用。
其中 ?: 是非捕獲元之一,還有兩個非捕獲元是 ?= 和 ?!,這兩個還有更多的含義,前者爲正向預查,在任何開始匹配圓括號內的正則表達式模式的位置來匹配搜索字符串,後者爲負向預查,在任何開始不匹配該正則表達式模式的位置來匹配搜索字符串。
________________________________________反向引用
對一個正則表達式模式或部分模式兩邊添加圓括號將導致相關匹配存儲到一個臨時緩衝區中,所捕獲的每個子匹配都按照在正則表達式模式中從左到右出現的順序存儲。緩衝區編號從 1 開始,最多可存儲 99 個捕獲的子表達式。每個緩衝區都可以使用 \n訪問,其中 n 爲一個標識特定緩衝區的一位或兩位十進制數。
可以使用非捕獲元字符 ?:、?= 或 ?! 來重寫捕獲,忽略對相關匹配的保存。
反向引用的最簡單的、最有用的應用之一,是提供查找文本中兩個相同的相鄰單詞的匹配項的能力。以下面的句子爲例:
Is is the cost of of gasoline going up up?
上面的句子很顯然有多個重複的單詞。如果能設計一種方法定位該句子,而不必查找每個單詞的重複出現,那該有多好。下面的正則表達式使用單個子表達式來實現這一點:
實例
查找重複的單詞:
var str = "Is is the cost of of gasoline going up up";
var patt1 = /\b([a-z]+) \1\b/;
document.write(str.match(patt1));
 運行結果
Is is,of of,up up
捕獲的表達式,正如 [a-z]+ 指定的,包括一個或多個字母。正則表達式的第二部分是對以前捕獲的子匹配項的引用,即,單詞的第二個匹配項正好由括號表達式匹配。\1 指定第一個子匹配項。
字邊界元字符確保只檢測整個單詞。否則,諸如 "is issued" 或 "this is" 之類的詞組將不能正確地被此表達式識別。
正則表達式後面的全局標記 g 指定將該表達式應用到輸入字符串中能夠查找到的儘可能多的匹配。
表達式的結尾處的不區分大小寫 i 標記指定不區分大小寫。
多行標記指定換行符的兩邊可能出現潛在的匹配。
反向引用還可以將通用資源指示符 (URI) 分解爲其組件。假定您想將下面的 URI 分解爲協議(ftp、http 等等)、域地址和頁/路徑:
http://www.openketang.com:80/html/html-tutorial.html
下面的正則表達式提供該功能:
實例
輸出所有匹配的數據:
var str = "https://www.openketang.com:80/html/html-tutorial.html";
var patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/;
arr = str.match(patt1);
for (var i = 0; i < arr.length ; i++) {
    document.write(arr[i]);
    document.write("<br>");
}
 運行結果
http://www.openketang.com:80/html/html-tutorial.html
http
openketang
:80
/html/html-tutorial.html
第一個括號子表達式捕獲 Web 地址的協議部分。該子表達式匹配在冒號和兩個正斜槓前面的任何單詞。
第二個括號子表達式捕獲地址的域地址部分。子表達式匹配 / 和 : 之外的一個或多個字符。
第三個括號子表達式捕獲端口號(如果指定了的話)。該子表達式匹配冒號後面的零個或多個數字。只能重複一次該子表達式。
最後,第四個括號子表達式捕獲 Web 地址指定的路徑和 / 或頁信息。該子表達式能匹配不包括 # 或空格字符的任何字符序列。
將正則表達式應用到上面的 URI,各子匹配項包含下面的內容:
•    第一個括號子表達式包含"http"
•    第二個括號子表達式包含"www.openketang.com"
•    第三個括號子表達式包含":80"
•    第四個括號子表達式包含"/html/html-tutorial.html"
四、    正則表達式元字符
下表包含了元字符的完整列表以及它們在正則表達式上下文中的行爲:
 
 
   
 
 
五、    正則表達式運算符優先級
正則表達式從左到右進行計算,並遵循優先級順序,這與算術表達式非常類似。
相同優先級的從左到右進行運算,不同優先級的運算先高後低。下表從最高到最低說明了各種正則表達式運算符的優先級順序:
 
六、    正則表達式匹配規則
基本模式匹配
一切從最基本的開始。模式,是正規表達式最基本的元素,它們是一組描述字符串特徵的字符。模式可以很簡單,由普通的字符串組成,也可以非常複雜,往往用特殊的字符表示一個範圍內的字符、重複出現,或表示上下文。例如:
^once
這個模式包含一個特殊的字符^,表示該模式只匹配那些以once開頭的字符串。例如該模式與字符串"once upon a time"匹配,與"There once was a man from NewYork"不匹配。正如如^符號表示開頭一樣,$符號用來匹配那些以給定模式結尾的字符串。
bucket$
這個模式與"Who kept all of this cash in a bucket"匹配,與"buckets"不匹配。字符^和$同時使用時,表示精確匹配(字符串與模式一樣)。例如:
^bucket$
只匹配字符串"bucket"。如果一個模式不包括^和$,那麼它與任何包含該模式的字符串匹配。例如:模式
once
與字符串
There once was a man from NewYorkWho kept all of his cash in a bucket.
是匹配的。
在該模式中的字母(o-n-c-e)是字面的字符,也就是說,他們表示該字母本身,數字也是一樣的。其他一些稍微複雜的字符,如標點符號和白字符(空格、製表符等),要用到轉義序列。所有的轉義序列都用反斜槓(\)打頭。製表符的轉義序列是:\t。所以如果我們要檢測一個字符串是否以製表符開頭,可以用這個模式:
^\t
類似的,用\n表示"新行",\r表示回車。其他的特殊符號,可以用在前面加上反斜槓,如反斜槓本身用\\表示,句號.用\.表示,以此類推。
字符簇
在INTERNET的程序中,正規表達式通常用來驗證用戶的輸入。當用戶提交一個FORM以後,要判斷輸入的電話號碼、地址、EMAIL地址、信用卡號碼等是否有效,用普通的基於字面的字符是不夠的。
所以要用一種更自由的描述我們要的模式的辦法,它就是字符簇。要建立一個表示所有元音字符的字符簇,就把所有的元音字符放在一個方括號裏:
[AaEeIiOoUu]
這個模式與任何元音字符匹配,但只能表示一個字符。用連字號可以表示一個字符的範圍,如:
[a-z] //匹配所有的小寫字母 [A-Z] //匹配所有的大寫字母 [a-zA-Z] //匹配所有的字母 [0-9] //匹配所有的數字 [0-9\.\-] //匹配所有的數字,句號和減號 [ \f\r\t\n] //匹配所有的白字符
同樣的,這些也只表示一個字符,這是一個非常重要的。如果要匹配一個由一個小寫字母和一位數字組成的字符串,比如"z2"、"t6"或"g7",但不是"ab2"、"r2d3" 或"b52"的話,用這個模式:
^[a-z][0-9]$
儘管[a-z]代表26個字母的範圍,但在這裏它只能與第一個字符是小寫字母的字符串匹配。
前面曾經提到^表示字符串的開頭,但它還有另外一個含義。當在一組方括號裏使用^是,它表示"非"或"排除"的意思,常常用來剔除某個字符。還用前面的例子,我們要求第一個字符不能是數字:
^[^0-9][0-9]$
這個模式與"&5"、"g7"及"-2"是匹配的,但與"12"、"66"是不匹配的。下面是幾個排除特定字符的例子:
[^a-z] //除了小寫字母以外的所有字符 [^\\\/\^] //除了(\)(/)(^)之外的所有字符 [^\"\'] //除了雙引號(")和單引號(')之外的所有字符
特殊字符"." (點,句號)在正則表達式中用來表示除了"新行"之外的所有字符。所以模式"^.5$"與任何兩個字符的、以數字5結尾和以其他非"新行"字符開頭的字符串匹配。模式"."可以匹配任何字符串,除了空串和只包括一個"新行"的字符串。
PHP的正規表達式有一些內置的通用字符簇,列表如下:
字符簇    描述
[[:alpha:]]    任何字母
[[:digit:]]    任何數字
[[:alnum:]]    任何字母和數字
[[:space:]]    任何空白字符
[[:upper:]]    任何大寫字母
[[:lower:]]    任何小寫字母
[[:punct:]]    任何標點符號
[[:xdigit:]]    任何16進制的數字,相當於[0-9a-fA-F]
    
確定重複出現
到現在爲止,你已經知道如何去匹配一個字母或數字,但更多的情況下,可能要匹配一個單詞或一組數字。一個單詞有若干個字母組成,一組數字有若干個單數組成。跟在字符或字符簇後面的花括號({})用來確定前面的內容的重複出現的次數。
字符簇    描述
^[a-zA-Z_]$    所有的字母和下劃線
^[[:alpha:]]{3}$    所有的3個字母的單詞
^a$    字母a
^a{4}$    aaaa
^a{2,4}$    aa,aaa或aaaa
^a{1,3}$    a,aa或aaa
^a{2,}$    包含多於兩個a的字符串
^a{2,}    如:aardvark和aaab,但apple不行
a{2,}    如:baad和aaa,但Nantucket不行
\t{2}    兩個製表符
.{2}    所有的兩個字符
這些例子描述了花括號的三種不同的用法。一個數字 {x} 的意思是前面的字符或字符簇只出現x次 ;一個數字加逗號 {x,} 的意思是前面的內容出現x或更多的次數 ;兩個數字用逗號分隔的數字 {x,y} 表示 前面的內容至少出現x次,但不超過y次。我們可以把模式擴展到更多的單詞或數字:
^[a-zA-Z0-9_]{1,}$      // 所有包含一個以上的字母、數字或下劃線的字符串 ^[1-9][0-9]{0,}$        // 所有的正整數 ^\-{0,1}[0-9]{1,}$      // 所有的整數 ^[-]?[0-9]+\.?[0-9]+$   // 所有的浮點數
最後一個例子不太好理解,是嗎?這麼看吧:以一個可選的負號 ([-]?) 開頭 (^)、跟着1個或更多的數字([0-9]+)、和一個小數點(\.)再跟上1個或多個數字([0-9]+),並且後面沒有其他任何東西($)。下面你將知道能夠使用的更爲簡單的方法。
特殊字符 ? 與 {0,1} 是相等的,它們都代表着: 0個或1個前面的內容 或 前面的內容是可選的 。所以剛纔的例子可以簡化爲:
^\-?[0-9]{1,}\.?[0-9]{1,}$
特殊字符 * 與 {0,} 是相等的,它們都代表着 0 個或多個前面的內容 。最後,字符 + 與 {1,} 是相等的,表示 1 個或多個前面的內容 ,所以上面的4個例子可以寫成:
^[a-zA-Z0-9_]+$      // 所有包含一個以上的字母、數字或下劃線的字符串 ^[1-9][0-9]*$        // 所有的正整數 ^\-?[0-9]+$          // 所有的整數 ^\-?[0-9]+\.?[0-9]*$ // 所有的浮點數
當然這並不能從技術上降低正規表達式的複雜性,但可以使它們更容易閱讀。
七、    正則表達式示例
簡單表達式
正則表達式的最簡單形式是在搜索字符串中匹配其本身的單個普通字符。例如,單字符模式,如 A,不論出現在搜索字符串中的何處,它總是匹配字母 A。下面是一些單字符正則表達式模式的示例:
/a//7//M/
可以將許多單字符組合起來以形成大的表達式。例如,以下正則表達式組合了單字符表達式:a、7 和 M。
/a7M/
請注意,沒有串聯運算符。只須在一個字符後面鍵入另一個字符。
字符匹配
句點 (.) 匹配字符串中的各種打印或非打印字符,只有一個字符例外。這個例外就是換行符 (\n)。下面的正則表達式匹配 aac、abc、acc、adc 等等,以及 a1c、a2c、a-c 和 a#c:
/a.c/
若要匹配包含文件名的字符串,而句點 (.) 是輸入字符串的組成部分,請在正則表達式中的句點前面加反斜扛 (\) 字符。舉例來說明,下面的正則表達式匹配 filename.ext:
/filename\.ext/
這些表達式只讓您匹配"任何"單個字符。可能需要匹配列表中的特定字符組。例如,可能需要查找用數字表示的章節標題(Chapter 1、Chapter 2 等等)。
中括號表達式
若要創建匹配字符組的一個列表,請在方括號([ 和 ])內放置一個或更多單個字符。當字符括在中括號內時,該列表稱爲"中括號表達式"。與在任何別的位置一樣,普通字符在中括號內表示其本身,即,它在輸入文本中匹配一次其本身。大多數特殊字符在中括號表達式內出現時失去它們的意義。不過也有一些例外,如:
•    如果 ] 字符不是第一項,它結束一個列表。若要匹配列表中的 ] 字符,請將它放在第一位,緊跟在開始 [ 後面。
•    \ 字符繼續作爲轉義符。若要匹配 \ 字符,請使用 \\。
括在中括號表達式中的字符只匹配處於正則表達式中該位置的單個字符。以下正則表達式匹配 Chapter 1、Chapter 2、Chapter 3、Chapter 4 和 Chapter 5:
/Chapter [12345]/
請注意,單詞 Chapter 和後面的空格的位置相對於中括號內的字符是固定的。中括號表達式指定的只是匹配緊跟在單詞 Chapter 和空格後面的單個字符位置的字符集。這是第九個字符位置。
若要使用範圍代替字符本身來表示匹配字符組,請使用連字符 (-) 將範圍中的開始字符和結束字符分開。單個字符的字符值確定範圍內的相對順序。下面的正則表達式包含範圍表達式,該範圍表達式等效於上面顯示的中括號中的列表。
/Chapter [1-5]/
當以這種方式指定範圍時,開始值和結束值兩者都包括在範圍內。注意,還有一點很重要,按 Unicode 排序順序,開始值必須在結束值的前面。
若要在中括號表達式中包括連字符,請採用下列方法之一:
•    用反斜扛將它轉義:
[\-]
 
•    將連字符放在中括號列表的開始或結尾。下面的表達式匹配所有小寫字母和連字符:
[-a-z][a-z-]
 
•    創建一個範圍,在該範圍中,開始字符值小於連字符,而結束字符值等於或大於連字符。下面的兩個正則表達式都滿足這一要求:
[!--][!-~]
若要查找不在列表或範圍內的所有字符,請將插入符號 (^) 放在列表的開頭。如果插入字符出現在列表中的其他任何位置,則它匹配其本身。下面的正則表達式匹配1、2、3、4 或 5 之外的任何數字和字符:
/Chapter [^12345]/
在上面的示例中,表達式在第九個位置匹配 1、2、3、4 或 5 之外的任何數字和字符。這樣,例如,Chapter 7 就是一個匹配項,Chapter 9 也是一個匹配項。
上面的表達式可以使用連字符 (-) 來表示:
/Chapter [^1-5]/
中括號表達式的典型用途是指定任何大寫或小寫字母或任何數字的匹配。下面的表達式指定這樣的匹配:
/[A-Za-z0-9]/

替換和分組

替換使用 | 字符來允許在兩個或多個替換選項之間進行選擇。例如,可以擴展章節標題正則表達式,以返回比章標題範圍更廣的匹配項。但是,這並不象您可能認爲的那樣簡單。替換匹配 | 字符任一側最大的表達式。
您可能認爲,下面的表達式匹配出現在行首和行尾、後面跟一個或兩個數字的 Chapter 或 Section:
/^Chapter|Section [1-9][0-9]{0,1}$/
很遺憾,上面的正則表達式要麼匹配行首的單詞 Chapter,要麼匹配行尾的單詞 Section 及跟在其後的任何數字。如果輸入字符串是 Chapter 22,那麼上面的表達式只匹配單詞 Chapter。如果輸入字符串是 Section 22,那麼該表達式匹配 Section 22。
若要使正則表達式更易於控制,可以使用括號來限制替換的範圍,即,確保它只應用於兩個單詞 Chapter 和 Section。但是,括號也用於創建子表達式,並可能捕獲它們以供以後使用,這一點在有關反向引用的那一節講述。通過在上面的正則表達式的適當位置添加括號,就可以使該正則表達式匹配 Chapter 1 或 Section 3。
下面的正則表達式使用括號來組合 Chapter 和 Section,以便表達式正確地起作用:
/^(Chapter|Section) [1-9][0-9]{0,1}$/
儘管這些表達式正常工作,但 Chapter|Section 周圍的括號還將捕獲兩個匹配字中的任一個供以後使用。由於在上面的表達式中只有一組括號,因此,只有一個被捕獲的"子匹配項"。
在上面的示例中,您只需要使用括號來組合單詞 Chapter 和 Section 之間的選擇。若要防止匹配被保存以備將來使用,請在括號內正則表達式模式之前放置 ?:。下面的修改提供相同的能力而不保存子匹配項:
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/
除 ?: 元字符外,兩個其他非捕獲元字符創建被稱爲"預測先行"匹配的某些內容。正向預測先行使用 ?= 指定,它匹配處於括號中匹配正則表達式模式的起始點的搜索字符串。反向預測先行使用 ?! 指定,它匹配處於與正則表達式模式不匹配的字符串的起始點的搜索字符串。
例如,假設您有一個文檔,該文檔包含指向 Windows 3.1、Windows 95、Windows 98 和 Windows NT 的引用。再進一步假設,您需要更新該文檔,將指向 Windows 95、Windows 98 和 Windows NT 的所有引用更改爲 Windows 2000。下面的正則表達式(這是一個正向預測先行的示例)匹配 Windows 95、Windows 98 和 Windows NT:
/Windows(?=95 |98 |NT )/
找到一處匹配後,緊接着就在匹配的文本(不包括預測先行中的字符)之後搜索下一處匹配。例如,如果上面的表達式匹配 Windows 98,將在 Windows 之後而不是在 98 之後繼續搜索。
其他示例
下面列出一些正則表達式示例:
正則表達式    描述
/\b([a-z]+) \1\b/gi    一個單詞連續出現的位置。
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/    將一個URL解析爲協議、域、端口及相對路徑。
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/    定位章節的位置。
/[-a-z]/    a至z共26個字母再加一個-號。
/ter\b/    可匹配chapter,而不能匹配terminal。
/\Bapt/    可匹配chapter,而不能匹配aptitude。
/Windows(?=95 |98 |NT )/    可匹配Windows95或Windows98或WindowsNT,當找到一個匹配後,從Windows後面開始進行下一次的檢索匹配。
/^\s*$/    匹配空行。
/\d{2}-\d{5}/    驗證由兩位數字、一個連字符再加 5 位數字組成的 ID 號。
/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/    匹配 HTML 標記。
八、    正則表達式-常用表達式 
常用正則表達式
一、校驗數字的表達式
•    數字:^[0-9]*$
•    n位的數字:^\d{n}$
•    至少n位的數字:^\d{n,}$
•    m-n位的數字:^\d{m,n}$
•    零和非零開頭的數字:^(0|[1-9][0-9]*)$
•    非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
•    帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})?$
•    正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$
•    有兩位小數的正實數:^[0-9]+(\.[0-9]{2})?$
•    有1~3位小數的正實數:^[0-9]+(\.[0-9]{1,3})?$
•    非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
•    非零的負整數:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
•    非負整數:^\d+$ 或 ^[1-9]\d*|0$
•    非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
•    •  非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
•    •  非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
•    •  正浮點數:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
•    •  負浮點數:^-([1-9]\d*\.\d*|0\.\d*[1-9]\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+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
校驗字符的表達式
•    漢字:^[\u4e00-\u9fa5]{0,}$
•    英文和數字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
•    長度爲3-20的所有字符:^.{3,20}$
•    由26個英文字母組成的字符串:^[A-Za-z]+$
•    由26個大寫英文字母組成的字符串:^[A-Z]+$
•    由26個小寫英文字母組成的字符串:^[a-z]+$
•    由數字和26個英文字母組成的字符串:^[A-Za-z0-9]+$
•    由數字、26個英文字母或者下劃線組成的字符串:^\w+$ 或 ^\w{3,20}$
•    中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
•    中文、英文、數字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
•    可以輸入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
•    禁止輸入含有~的字符:[^~\x22]+
特殊需求表達式
•    Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
•    域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
•    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{8}$
•    電話號碼("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
•    國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
•    電話號碼正則表達式(支持手機號碼,3-4位區號,7-8位直播號碼,1-4位分機號): ((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
•    身份證號(15位、18位數字),最後一位是校驗位,可能爲數字或字符X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
•    帳號是否合法(字母開頭,允許5-16字節,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
•    密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):^[a-zA-Z]\w{5,17}$
•    強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間):^(?=.*\d)(?=.*[a-
•    z])(?=.*[A-Z]).{8,10}$
•    日期格式:^\d{4}-\d{1,2}-\d{1,2}
•    一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$
•    一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
•    錢的輸入格式:
•    有四種錢的表示形式我們可以接受:"10000.00" 和 "10,000.00", 和沒有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
•    這表示任意一個不以0開頭的數字,但是,這也意味着一個字符"0"不通過,所以我們採用下面的形式:^(0|[1-9][0-9]*)$
•    一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
•    這表示一個0或者一個可能爲負的開頭不爲0的數字.讓用戶以0開頭好了.把負號的也去掉,因爲錢總不能是負的吧。下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$
•    必須說明的是,小數點後面至少應該有1位數,所以"10."是不通過的,但是 "10" 和 "10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
•    這樣我們規定小數點後面必須有兩位,如果你認爲太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
•    這樣就允許用戶只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
•    1到3個數字,後面跟着任意個 逗號+3個數字,逗號成爲可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
•    備註:這就是最終結果了,別忘了"+"可以用"*"替代如果你覺得空字符串也可以接受的話(奇怪,爲什麼?)最後,別忘了在用函數時去掉去掉那個反斜槓,一般的錯誤都在這裏
•    xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
•    中文字符的正則表達式:[\u4e00-\u9fa5]
•    雙字節字符:[^\x00-\xff] (包括漢字在內,可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1))
•    空白行的正則表達式:\n\s*\r (可以用來刪除空白行)
•    HTML標記的正則表達式:<(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字符的正則表達式:^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字符(包括空格、製表符、換頁符等等),非常有用的表達式)
•    騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始)
•    中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼爲6位數字)
•    IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章