目前為止,許多程式設計語言和工具都包含對正規表達式的支援,C#也不例外,C#基礎類庫中包含有一個命名空間(System.Text.RegularExpressions)和一系列可以充分發揮規則表達式威力的類(Regex、Match、Group等)。那麼,什麼是正規表達式,怎麼定義正規表達式呢?
一、正規表達式基礎
在編寫字元串的處理程式時,經常會有查找符合某些複雜規則的字元串的需要。正規表達式就是用于描述這些規則的工具。換句話說,正規表達式就是記錄文本規則的代碼。
通常,我們在使用WINDOWS查找檔案時,會使用通配符(*和?)。如果你想查找某個目錄下的所有Word文檔時,你就可以使用*.doc進行查找,在這裡,*就被解釋為任意字元串。和通配符類似,正規表達式也是用來進行文本比對的工具,隻不過比起通配符,它能更精确地描述你的需求——當然,代價就是更複雜。
l
學習正規表達式的最好方法是從例子開始,下面我們從驗證電話号碼開始,一步一步的了解正規表達式。
在我們國家,電話号碼(如:0379-65624150)通常包含3到4為以0開頭的區号和一個7或8為的号碼,中間通常以連字元’-’隔開。在這個例子中,首先我們要介紹一個元字元\d,它用來比對一個0到9的數字。這個正規表達式可以寫成:^0\d{2,3}-\d{7,8}$
我們來對他進行分析,0比對數字“0”,\d比對一個數字,{2,3}表示重複2到3次,-隻比對”-”自身,接下來的\d同樣比對一個數字,而 {7,8}則表示重複7到8次。當然,電話号碼還可以寫成 (0379)65624150,這裡就交給讀者完成。
1.3 元字元
在上面的例子中,我們接觸到了一個元字元\d,正如你所想的,正規表達式還有很多像\d一樣的元字元,下表列出了一些常用的元字元:
元字元
說明
.
比對除換行符以外的任意字元
\b
比對單詞的開始或結束
\d
比對數字
\s
比對任意的空白符
\w
比對字母或數字或下劃線或漢字
^
比對字元串的開始
$
比對字元串的結束
\
對下一個字元轉義。比如$是個特殊的字元。要比對$的話就得用\$
|
分支條件,如:x|y比對 x 或 y。
表1、常用的元字元
1.4 轉義字元
如果你想查找元字元本身的話,比如你查找.,或者*,就出現了問題:你沒辦法指定它們,因為它們會被解釋成别的意思。這時你就得使用\來取消這些字元的特殊意義。是以,你應該使用\.和\*。當然,要查找\本身,你也得用\\.
例如:unibetter\.com比對unibetter.com,C:\\Windows比對C:\Windows。
1.5 限定符
限定符又叫重複描述字元,表示一個字元要出現的次數。比如我們在比對電話号碼時使用的{3,4}就表示出現3到4次。常用的限定符有:
限定符
*
重複零次或更多次
+
重複一次或更多次
?
重複零次或一次
{n}
重複n次
{n,}
重複n次或更多次
{n,m}
重複n到m
表2、常用的限定符
懶惰限定符
代碼
*?
重複任意次,但盡可能少重複。
如 "acbacb" 正則 "a.*?b" 隻會取到第一個"acb" 原本可以全部取到但加了限定符後,隻會比對盡可能少的字元 ,而"acbacb"最少字元的結果就是"acb" 。
+?
重複1次或更多次,但盡可能少重複。與上面一樣,隻是至少要重複1次。
??
重複0次或1次,但盡可能少重複。
如 "aaacb" 正則 "a.??b" 隻會取到最後的三個字元"acb"。
{n,m}?
重複n到m次,但盡可能少重複。
如 "aaaaaaaa" 正則 "a{0,m}" 因為最少是0次是以取到結果為空。
{n,}?
重複n次以上,但盡可能少重複。
如 "aaaaaaa" 正則 "a{1,}" 最少是1次是以取到結果為 "a"。
捕獲分組
(exp)
比對exp,并捕獲文本到自動命名的組裡。
(?<name>exp)
比對exp,并捕獲文本到名稱為name的組裡。
(?:exp)
比對exp,不捕獲比對的文本,也不給此分組配置設定組号以下為零寬斷言。
(?=exp)
比對exp前面的位置。
如 "How are you doing" 正則"(?<txt>.+(?=ing))" 這裡取ing前所有的字元,并定義了一個捕獲分組名字為 "txt" 而"txt"這個組裡的值為"How are you do";
(?<=exp)
比對exp後面的位置。
如 "How are you doing" 正則"(?<txt>(?<=How).+)" 這裡取"How"之後所有的字元,并定義了一個捕獲分組名字為 "txt" 而"txt"這個組裡的值為" are you doing";
(?!exp)
比對後面跟的不是exp的位置。
如 "123abc" 正則 "\d{3}(?!\d)"比對3位數字後非數字的結果
(?<!exp)
比對前面不是exp的位置。
如 "abc123 " 正則 "(?<![0-9])123" 比對"123"前面是非數字的結果也可寫成"(?!<\d)123"
System.Text.RegularExpressions 命名空間包含一些類,這些類提供對 .NET Framework 正規表達式引擎的通路。該命名空間提供正規表達式功能,可以從運作在 Microsoft .NET Framework 内的任何平台或語言中使用該功能。
在了解了C#中支援正規表達式的類後,我們一起來将上面提到的驗證電話号碼的正規表達式寫入C#代碼中,實作電話号碼的驗證。
第一步,建立一個名為SimpleCheckPhoneNumber的Windows項目。
第二步,引入System.Text.RegularExpressions命名空間。
第三步,寫出正規表達式。這裡的正規表達式就是上面的驗證号碼的字元串。由于上面的字元串隻能驗證用連字元連接配接區号和号碼的方式的電話号碼,是以我們做了一些修改:0\d{2,3}-\d{7,8}|\(0\d{2,3}\)\d{7,8}。在這個表達式中,| 号面的一部分是我們上面提到過的,後面一部分是用來驗證(0379)65624150這種電話号碼寫法的。由于 ( 和 ) 也是元字元,是以要用轉義字元。| 表示分支比對,要麼比對前面的一部分,要麼比對後面的一部分。
第四步,正規表達式構造一個Regex類。
第五步,使用Regex類的IsMatch方法驗證比對。Regex類的IsMatch()方法傳回一個bool值,如果有比對項,傳回true,否則傳回false。
三、正規表達式進階
3.1分組
在比對電話号碼的時候,我們已經用到過重複單個字元。下面我們來了解如何使用分組來比對一個IP位址。
衆所周知,IP位址是四段點分十進制的字元串表示的。是以,我們可以通過位址的分組,來進行比對。
首先,我們來比對第一段:
2[0-4]\d|25[0-5]|[01]?\d\d?
這段正規表達式可以比對IP位址的一段數字。
2[0-4]\d 比對以2開頭,十位為0到4,個位為任何數字的三位字段,25[0-5] 比對以25 開頭,個位為0到5 的三位字段,[01]?\d\d? 比對任何以1者0頭,個位和十位為任何數子的字段。? 表示出現零次或一次。是以, [01] 和 最後一個 \d 都可以不出現,如果我們再向這個字元串後面添加一個 \. 來比對 . 就可以劃分一個段了。
現在,我們把 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? 就可以了。
完整的正規表達式為: (2[0-4]\d|25[0-5]|[01]?\d\d?\.){3}2[0-4]\d|25[0-5]|[01]?\d\d?
l 3.2 後向引用
在我們了解分組以後,我們就可以使用後向引用了。所謂後向引用,就是使用前面捕獲的結果,對後面的字元進行比對。多用于比對重複字元。比如比對 go go 這樣的重複字元。我們就可以使用 (go) \1來進行比對。
預設情況下,每個分組會自動擁有一個組号,規則是:從左向右,以分組的左括号為标志,第一個出現的分組的組号為1,第二個為2,以此類推。當然,你也可以自己指定子表達式的組名。要指定一個子表達式的組名,請使用這樣的文法:
(?<Word>\w+)(或者把尖括号換成'也行:(?'Word'\w+)),這樣就把\w+的組名指定為Word了。要反向引用這個分組捕獲的内容,你可以使用\k<Word>,是以上一個例子也可以寫成這樣:\b(?<Word>\w+)\b\s+\k<Word>\b。
自定義組名還有另外一個好處,在我們的C#程式中,如果需要得到分組的值,我們就可以很明确的使用我們定義的分組的名字來得到,而不必使用下标。
當我們并不想使用後向引用時,是不需要捕獲組記憶任何東西的,這種情況下就可以利用(?:nocapture)文法來主動地告訴正規表達式引擎,不要把圓括号的内容當作捕獲組,以便提高效率。
l 3.3 零寬斷言
在前面的元字元介紹中,我們已經知道了有這樣一類字元,可以比對一句話的開始、結束(^ $)或者比對一個單詞的開始、結束(\b)。這些元字元隻比對一個位置,指定這個位置滿足一定的條件,而不是比對某些字元,是以,它們被成為 零寬斷言。所謂零寬,指的是它們不與任何字元相比對,而比對一個位置;所謂斷言,指的是一個判斷。正規表達式中隻有當斷言為真時才會繼續進行比對。
在有些時候,我們精确的比對一個位置,而不僅僅是句子或者單詞,這就需要我們自己寫出斷言來進行比對。下面是斷言的文法:
斷言文法
(?=pattern)
前向肯定斷言,比對pattern前面的位置
(?!pattern)
前向否定斷言,比對後面不是pattern的位置
(?<=pattern)
後向肯定斷言,比對pattern後面的位置
(?<!pattern)
後向否定斷言,比對前面不是pattern的位置
表3、斷言的文法及說明
很難了解嗎?我們來看一個例子。
有一個标簽:<book>,我們想要得到标簽<book>的标簽名(book),這個時候,我們就可以使用斷言來處理。看下面這個表達式:(?<=\<)(?<tag>\w*)(?=\>) ,使用這個表達式,可以比對< 和 >之間的字元,也就是這裡的book。使用斷言還還可以寫出更加複雜的表達式,這裡就不再舉例了。
還有一點非常重要,就是斷言文法所使用的圓括号并不作為捕獲組,是以不能使用編号或命名來對它進行引用。
3.4 貪婪與懶惰
當正規表達式中包含能接受重複的限定符時,通常的行為是(在使整個表達式能得到比對的前提下)比對盡可能多的字元。來看一下這個表達式:a\w*b ,用它來比對字元串 aabab 時,得到的比對結果是 aabab 。這種比對被稱為貪婪比對。
有些時候,我們希望讓它盡可能的少重複,即用上面的例子得到的比對結果是 aab,這時我們就要使用懶惰比對。懶惰比對需要在重複限定符的後面添加一個 ? 符号,上面的表達式就可以寫成:a\w*?b 我們再來比對字元串 aabab時,得到的比對結果是 aab 和 ab 。
也許這個時候你要問,ab 比aab重複次數更少,為什麼不先比對ab呢?其實在正規表達式中還有比貪婪/懶惰優先級更高的規則:最先開始的比對擁有最高的優先權——The match that begins earliest wins。
3.5 注釋
文法:(?#comment)
例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)
注意:如果使用注釋,則需要格外注意不要在注釋的小括号前面出現空格、換行符等一些字元,如果可以忽略這些字元,則最好使用“忽略模式裡的空白符”選項,即C#中RegexOptions枚舉的IgnorePatternWhitespace選項(C#中的RegexOptions枚舉下面将會提到)。
3.6 C#中的處理選項
在C#中,可以使用RegexOptions 枚舉來選擇C#對正規表達式的處理方式。
3.7 C#中Capture類、Group類、Match類
Capture類: 表示單個子表達式捕獲中的結果。Capture類表示單個成功捕獲中的一個子字元串。該類沒有公共構造函數,可以從Group類或者Match類中得到一 個Capture類的對象集合。Capture類有三個常用屬性,分别是Index、Length和Value。Index表示捕獲的子字元串的第一個字 符的位置。Length表示捕獲的子字元串的長度,Value表示捕獲的子字元串。
Group類: 表示正規表達式中分組的資訊。該類提供了對分組比對的正規表達式的支援。該類沒有公共構造函數。可以從Match類中得到一個Group類的集合。如果正 則表達式中的分組已命名,則可以使用名字對其進行通路,如果沒有命名,則可以采用下标通路。注意:每一個Match的Groups集合中的第0個元素 (Groups[0])都是這個Match捕獲的字元串,也是Capture的Value。
Match類:表示單個正規表達式比對的結果。該類同樣沒有公共構造函數,可以從Regex類的Match()方法得到該類的一個執行個體,也可以使用Regex類的Matches()方法得到給類的一個集合。
這三個類都能表示單個正規表達式比對的結果,但Match類得到的更為詳細,包含捕獲和分組資訊。是以,Match類在這個三個類中是最常用的。
在實際項目中我們常常需要對使用者輸入的資訊進行驗證。如:比對使用者輸入的内容是否為數字,是否為有效的手機号碼,郵箱是否合法....等。
結果如下:
運作結果:
從上面的例子中我們不難看出貪婪與懶惰的差別,他們的名子取的都很形象。
貪婪比對:比對盡可能多的字元。
懶惰比對:比對盡可能少的字元。
在做爬蟲時我們經常獲得A中一些有用資訊。如href,title和顯示内容等。
在正規表達式裡使用()包含的文本自動會命名為一個組。上面的表達式中共使用了4個()可以認為是分為了4組。
輸出結果共分為:4組。
0組:為我們所比對的字元串。
1組:是我們第一個括号[href=""(\S+)""]中(\S+)所比對的網址資訊。内容為:http://www.taobao.com。
2組:是第二個括号[title=""([\s\S]+?)""]中所比對的内容資訊。内容為:淘寶網 - 淘!我喜歡。
這裡我們會看到+?懶惰限定符。title=""([\s\S]+?)"" 這裡+?的下一個字元為"雙引号,"雙引号在比對字元串後面還有三個。+?懶惰限定符會盡可能少重複,所他會比對最前面那個"雙引号。如果我們不使用+? 懶惰限定符他會比對到:淘寶網 - 淘!我喜歡" target= 會盡可能多重複比對。
3組:是第三個括号[(\S+)]所比對的内容資訊。内容為:淘寶。
說明:反義元字元所對應的元字元都能組合比對任意字元。如:[\w\W],[\s\S],[\d\D]..
(?<name>exp) 分組取名
當我們比對分組資訊過多後,在某種場合隻需取當中某幾組資訊。這時我們可以對分組取名。通過分組名稱來快速提取對應資訊。
通過(?<name>exp)可以很輕易為分組取名。然後通過Groups["name"]取得分組值。
獲得頁面中A标簽中href值:
View Code
結果為:
使用者在輸入資訊時偶爾會包含一些敏感詞,這時我們需要替換這個敏感詞。
更改日期的格式(用 dd-mm-yy 的日期形式代替 mm/dd/yy 的日期形式)
從 URL 提取協定和端口号:
這裡的例子可能是我們在網頁開發中,通常會碰到的一些正規表達式,尤其在第一個例子中,給出了使用javascript,vbScript,C#等不同語 言的實作方式,大家不難看出,對于不同的語言來說,正規表達式沒有差別,隻是正規表達式的實作類不同而已。而如何發揮正規表達式的公用,也要看實作類的支 持。
下面我們逐個來分析這些例子:
1-2,這兩個例子很簡單,隻是簡單的驗證字元串是否符合正規表達式規定的格式,其中使用的文法,在第一篇文章中都已經介紹過了,這裡做一下簡單的描述。
第1個例子的表達式: ^\w+$
^ -- 表示限定比對開始于字元串的開始
\w – 表示比對英文字元
+ -- 表示比對字元出現1次或多次
$ -- 表示比對字元到字元串結尾處結束
驗證形如asgasdfs的字元串
第2個例子的表達式:
^\w+@\w+.\w+$
@ -- 比對普通字元@
\. – 比對普通字元.(注意.為特殊字元,是以要加上\轉譯)
驗證形如[email protected]的郵件格式
替換
字元
含義
$123
替換由組号 123(十進制)比對的最後一個子字元串。
${name}
替換由 (? ) 組比對的最後一個子字元串。
$$
替換單個“$”字元。
$&
替換完全比對本身的一個副本。
$`
替換比對前的輸入字元串的所有文本。
$'
替換比對後的輸入字元串的所有文本。
$+
替換最後捕獲的組。
$_
替換整個輸入字元串。
捕獲比對的子字元串(或非捕獲組;有關更多資訊,請參閱正規表達式選項中的 ExplicitCapture 選項。)使用 () 的捕獲根據左括号的順序從 1 開始自動編号。捕獲元素編号為零的第一個捕獲是由整個正規表達式模式比對的文本。
(?<name> )
将比對的子字元串捕獲到一個組名稱或編号名稱中。用于 name 的字元串不能包含任何标點符号,并且不能以數字開頭。可以使用單引号替代尖括号,例如 (?'name')。
(?<name1-name2> )
平衡組定義。删除先前定義的 name2 組的定義并在 name1 組中存儲先前定義的 name2 組和目前組之間的間隔。如果未定 義 name2 組,則比對将回溯。由于删除 name2 的最後一個定義會顯示 name2 的先前定義,是以該構造允許将 name2 組的捕獲堆棧 用作計數器以跟蹤嵌套構造(如括号)。在此構造中,name1 是可選的。可以使用單引号替代尖括号,例如 (?'name1-name2')。
(?: )
非捕獲組。
(?imnsx-imnsx: )
應用或禁用子表達式中指定的選項。例如,(?i-s: ) 将打開不區分大小寫并禁用單行模式。有關更多資訊,請參閱正規表達式選項。
(?= )
零寬度正預測先行斷言。僅當子表達式在此位置的右側比對時才繼續比對。例如,\w+(?=\d) 與後跟數字的單詞比對,而不與該數字比對。此構造不會回溯。
(?! )
零寬度負預測先行斷言。僅當子表達式不在此位置的右側比對時才繼續比對。例如,\b(?!un)\w+\b 與不以 un 開頭的單詞比對。
(?<= )
零寬度正回顧後發斷言。僅當子表達式在此位置的左側比對時才繼續比對。例如,(?<=19)99 與跟在 19 後面的 99 的執行個體比對。此構造不會回溯。
(?
零寬度負回顧後發斷言。僅當子表達式不在此位置的左側比對時才繼續比對。
(?> )
非回溯子表達式(也稱為貪婪子表達式)。該子表達式僅完全比對一次,然後就不會逐段參與回溯了。(也就是說,該子表達式僅與可由該子表達式單獨比對的字元串比對。)
我們還是先簡單的了解一下這兩個概念:
分組構造:
最基本的構造方式就是(),在左右括号中括起來的部分,就是一個分組;
更進一步的分組就是形如:(?<name> )的分組方式,這種方式與第一種方式的不同點,就是對分組的部分進行了命名,這樣就可以通過該組的命名來擷取資訊;
(還有形如(?= )等等的分組構造,我們這篇的例子中也沒有使用到,下次我們在來介紹)
替換:
上面提到了兩種基本的構造分組方式()以及(?<name> ),通過這兩種分組方式,我們可以得到形如$1,${name}的比對結果。
這樣說,可能概念上還是有些模糊,我們還是結合上面的例子來說:
第三個例子的正規表達式為:\\b(?\\d{1,2})/(?\\d{1,2})/(?\\d{2,4})\\b
(解釋一下,為什麼這裡都是\\一起用:這裡是C#的例子,在C#語言中\是轉譯字元,要想字元串中的\不轉譯,就需要使用\\或者在整個字元串的開始加上@标記,即上面等價與
@”\b(?\d{1,2})/(?\d{1,2})/(?\d{2,4}\b”)
\b -- 是一種特殊情況。在正規表達式中,除了在 [] 字元類中表示倒退符以外,\b 表示字邊界(在 \w 和 \W 字元之間)。在替換模式中,\b 始終表示倒退符
(?\d{1,2}) – 構造一個名為month的分組,這個分組比對一個長度為1-2的數字
/ -- 比對普通的/字元
(?\d{1,2}) --構造一個名為day的分組,這個分組比對一個長度為1-2的數字
(?\d{2,4}\b”) --構造一個名為year的分組,這個分組比對一個長度為2-4的數字
這裡還不能夠看出這些分組的作用,我們接着看這一句
${day}-${month}-${year}
${day} – 獲得上面構造的名為day的分組比對後的資訊
- -- 普通的-字元
${month} --獲得上面構造的名為month的分組比對後的資訊
${year} --獲得上面構造的名為year的分組比對後的資訊
舉例來說:
将形如04/02/2003的日期使用例3種的方法替換
(?\d{1,2}) 分組将比對到04由${month}得到這個比對值
(?\d{1,2}) 分組将比對到02由${day}得到這個比對值
(?\d{1,2}) 分組将比對到2003由${year}得到這個比對值
了解了這個例子後,我們在來看第4個例子就很簡單了。
第4個例子的正則
^(?\w+)://[^/]+?(?:\d+)?/
(?\w+) – 構造一個名為proto的分組,比對一個或多個字母
: -- 普通的:字元
// -- 比對兩個/字元
[^/] – 表示這裡不允許是/字元
+? – 表示指定盡可能少地使用重複但至少使用一次比對
(?:\d+) – 構造一個名為port的分組,比對形如:2134(冒号+一個或多個數字)
? – 表示比對字元出現0次或1次
/ -- 比對/字元
"^\d+$" //非負整數(正整數 + 0)
"^[0-9]*[1-9][0-9]*$" //正整數
"^((-\d+)|(0+))$" //非正整數(負整數 + 0)
"^-[0-9]*[1-9][0-9]*$" //負整數
"^-?\d+$" //整數
"^\d+(\.\d+)?$" //非負浮點數(正浮點數 + 0)
"^(([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+)?))$" //非正浮點數(負浮點數 + 0)
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //負浮點數
"^(-?\d+)(\.\d+)?$" //浮點數
"^[A-Za-z]+$" //由26個英文字母組成的字元串
"^[A-Z]+$" //由26個英文字母的大寫組成的字元串
"^[a-z]+$" //由26個英文字母的小寫組成的字元串
"^[A-Za-z0-9]+$" //由數字和26個英文字母組成的字元串
"^\w+$" //由數字、26個英文字母或者下劃線組成的字元串
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" //email位址
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$" //url
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/ // 年-月-日
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/ // 月/日/年
"^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$" //Emil
"(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?" //電話号碼
"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$" //IP位址
YYYY-MM-DD基本上把閏年和2月等的情況都考慮進去了
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$
圖檔 src[^>]*[^/].(?:jpg|bmp|gif)(?:\"|\')
中文 ^([\u4e00-\u9fa5]+|[a-zA-Z0-9]+)$
網址 "\<a.+?href=['""](?!http\:\/\/)(?!mailto\:)(?>foundAnchor>[^'"">]+?)[^>]*?\>"
比對中文字元的正規表達式: [\u4e00-\u9fa5]
比對雙位元組字元(包括漢字在内):[^\x00-\xff]
比對空行的正規表達式:\n[\s| ]*\r
比對HTML标記的正規表達式:/<(.*)>.*<\/\1>|<(.*) \/>/
比對首尾空格的正規表達式:(^\s*)|(\s*$)(像vbscript那樣的trim函數)
比對Email位址的正規表達式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
比對網址URL的正規表達式:http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
以下是例子:
利用正規表達式限制網頁表單裡的文本框輸入内容:
用 正規表達式限制隻能輸入中文:onkeyup="value=value.replace(/[^\u4E00-\u9FA5] /g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"
1.用正規表達式限制隻能輸入全角字元: onkeyup="value=value.replace(/[^\uFF00- \uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"
2.用正規表達式限制隻能輸入數字:onkeyup="value=value.replace(/[^\d] /g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
3.用正規表達式限制隻能輸入數字和英文:onkeyup="value=value.replace(/[\W] /g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
4.計算字元串的長度(一個雙位元組字元長度計2,ASCII字元計1)
String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}
5.javascript中沒有像vbscript那樣的trim函數,我們就可以利用這個表達式來實作,如下:
String.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, "");
}
利用正規表達式分解和轉換IP位址:
6. 下面是利用正規表達式比對IP位址,并将IP位址轉換成對應數值的Javascript程式:
不過上面的程式如果不用正規表達式,而直接用split函數來分解可能更簡單,程式如下:
參考文章:
沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。
本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/5795253.html,如需轉載請自行聯系原作者