[前言:]在我(wǒ)(wǒ)們編寫WEB程序時,經常會判斷一(yī)個字符串的有效性,如;一(yī)個串是否是數字、是否是有效的Email地址等等。如果不使用正則表達式,那麽判斷的程序會很長,并且容易出錯,如果使用正則表達式,這些判斷就是一(yī)件很輕松的工(gōng)作了。本文全面介紹正則表達式的慨念、格式。并以在PHP、ASP中(zhōng)的應用實例增加讀者的感性認識。正則表達式的應用很廣,需要大(dà)家在學習和實踐中(zhōng)不斷的總結。
正則表達式簡介
簡單的說,正則表達式是一(yī)種可以用于模式匹配和替換的強有力的工(gōng)具。在網絡編程中(zhōng)應用廣泛,如PHP腳本語言或是javascript、VBScript這樣的客戶端腳本語言都提供了對正則表達式的支持。由此可見,正則表達式已經超出了某種語言或某個系統的局限,成爲人們廣爲接受的概念和功能。
正則表達式可以讓用戶通過使用一(yī)系列的特殊字符構建匹配模式,然後把匹配模式與數據文件、程序輸入以及WEB頁面的表單輸入等目标對象進行比較,根據比較對象中(zhōng)是否包含匹配模式,執行相應的程序。
舉例來說,正則表達式的一(yī)個最爲普遍的應用就是用于驗證用戶在線輸入的郵件地址的格式是否正确,如果通過正則表達式驗證用戶郵件地址的格式正确,用戶所填寫的表單信息将會被正常處理;反之,如果用戶輸入的郵件地址與正則表達的模式不匹配,将會彈出提示信息,要求用戶重新輸入正确的郵件地址。由此可見正則表達式在WEB應用的邏輯判斷中(zhōng)具有舉足輕重的作用。在後面我(wǒ)(wǒ)們會舉例詳細介紹。
正則表達式形式一(yī)般如:/love/,其中(zhōng)位于"/"定界符之間的部分(fēn)就是将要在目标對象中(zhōng)進行匹配的模式。用戶隻要把希望查找匹配對象的模式内容放(fàng)入"/"定界符之間即可。爲了能夠使用戶更加靈活的定制模式内容,正則表達式提供了專門的"元字符"。所謂元字符就是指那些在正則表達式中(zhōng)具有特殊意義的專用字符,可以用來規定其前導字符(即位于元字符前面的字符)在目标對象中(zhōng)的出現模式。較爲常用的元字符包括: "+,"*,?以及{}",或者"\s,\S,\d,\w和\W"等等。爲了能夠方便用戶更加靈活的設定匹配模式,正則表達式允許使用者在匹配模式中(zhōng)利用[]界定匹配于某一(yī)個範圍的字符而不局限于具體(tǐ)的字符。
除了我(wǒ)(wǒ)們以上的元字符之外(wài),正則表達式中(zhōng)還具有另外(wài)一(yī)種較爲獨特的專用字符,即定位符。定位符用于規定匹配模式在目标對象中(zhōng)的出現位置。較爲常用的定位符包括: "^", "$", "\b" 以及 "\B"。
如果我(wǒ)(wǒ)們希望在正則表達式中(zhōng)實現類似編程邏輯中(zhōng)的"或"運算,在多個不同的模式中(zhōng)任選一(yī)個進行匹配的話(huà),可以使用管道符 "|"。例如:
正則表達式中(zhōng)還有一(yī)個較爲常用的運算符,即否定符 "[^]"。與我(wǒ)(wǒ)們前文所提到的定位符 "^" 不同,否定符 "[^]"規定目标對象中(zhōng)不能存在模式中(zhōng)所規定的字符串。一(yī)般來說,當"^"出現在 "[]"内時就被視做否定運算符;而當"^"位于"[]"之外(wài),或沒有"[]"時,則應當被視做定位符。
最後,當用戶需要在正則表達式的模式中(zhōng)加入元字符,并查找其匹配對象時,可以使用轉義符"\"。例如:/Th\*/,該正則表達式将會與目标對象中(zhōng)的"Th*"而非"The"等相匹配。
正則表達式的語法規則和标記
現在我(wǒ)(wǒ)們正式進入則表達式的學習,我(wǒ)(wǒ)會根據實例結合講解正則表達式的用法,看完後你就會覺得寫UBB代碼如此簡單了,隻要你一(yī)步一(yī)步的跟着我(wǒ)(wǒ)學 看完本文章後你就成爲UBB高手了。激動人心的就是你能寫出自已的UBB标簽來了,再也不用到别人那裏去(qù)拷貝現成的代碼和模闆了。 還好VBScritp5.0給我(wǒ)(wǒ)們提供了"正則表達式"對象,隻要你的服務器安裝了IE5.x,就可以運行了.
字符描述:
^符号匹配字符串的開(kāi)頭。例如:
^abc 與"abc xyz"匹配,而不與"xyz abc"匹配
$符号匹配字符串的結尾。例如:
abc$ 與"xyz abc"匹配,而不與"abc xyz"匹配。
注意:如果同時使用^符号和$符号,将進行精确匹配。例如:
^abc$ 隻與"abc"匹配
*符号匹配0個或多個前面的字符。例如:
ab* 可以匹配"ab"、"abb"、"abbb"等
+符号匹配至少一(yī)個前面的字符。例如:
ab+ 可以匹配"abb"、"abbb"等,但不匹配"ab"。
?符号匹配0個或1個前面的字符。例如:
ab?c? 可以且隻能匹配"abc"、"abbc"、"abcc"和"abbcc"
.符号匹配除換行符以外(wài)的任何字符。例如:
(.)+ 匹配除換行符以外(wài)的所有字符串
x|y匹配"x"或"y"。例如:
abc|xyz 可匹配 "abc"或 "xyz",而"ab(c|x)yz"匹配 "abcyz"和"abxyz"
{n}匹配恰好n次(n爲非負整數)前面的字符。例如:
a{2} 可以匹配"aa",但不匹配"a"
{n,}匹配至少n次(n爲非負整數)前面的字符。例如:
a{3,} 匹配"aaa"、"aaaa"等,但不匹配"a"和"aa"。
注意:a{1,}等價于a+
a{0,}等價于a*
{m,n}匹配至少m個,至多n個前面的字符。例如:
a{1,3} 隻匹配"a"、"aa"和"aaa"。
注意:a{0,1}等價于a?
[xyz]表示一(yī)個字符集,匹配括号中(zhōng)字符的其中(zhōng)之一(yī)。例如:
[abc] 匹配"a"、"b"和"c"
[^xyz]表示一(yī)個否定的字符集。匹配不在此括号中(zhōng)的任何字符。例如:
[^abc] 可以匹配除"a"、"b"和"c"之外(wài)的任何字符
[a-z]表示某個範圍内的字符,匹配指定區間内的任何字符。例如:
[a-z] 匹配從"a"到"z"之間的任何一(yī)個小(xiǎo)寫字母字符
[^m-n]表示某個範圍之外(wài)的字符,匹配不在指定範圍内的字符。例如:
[m-n] 匹配除從"m"到"n"之間的任何字符
\符号是轉義操作符。例如:
\n 換行符
\f 分(fēn)頁符
\r 回車(chē)
\t 制表符
\v 垂直制表符
\\ 匹配"\"
\/ 匹配"/"
\s 任何白(bái)字符,包括空格、制表符、分(fēn)頁符等。等價于"[ \f\n\r\t\v]"
\S 任何非空白(bái)的字符。等價于"^\f\n\r\t\v]"
\w 任何單詞字符,包括字母和下(xià)劃線。等價于"[A-Za-z0-9_]"
\W 任何非單詞字符。等價于"[^A-Za-z0-9_]"
\b匹配單詞的結尾。例如:
ve\b 匹配單詞"love"等,但不匹配"very"、"even"等
\B匹配單詞的開(kāi)頭。例如:
ve\B 匹配單詞"very"等,但不匹配"love"等
\d匹配一(yī)個數字字符,等價于[0-9]。例如:
abc\dxyz 匹配"abc2xyz"、"abc4xyz"等,
但不匹配"abcaxyz"、"abc-xyz"等
\D匹配一(yī)個非數字字符,等價于[^0-9]。例如:
abc\Dxyz 匹配"abcaxyz"、"abc-xyz"等,
但不匹配"abc2xyz"、"abc4xyz"等
\NUM匹配NUM個(其中(zhōng)NUM爲一(yī)個正整數),引用回到記住的匹配。例如:
(.)\1 匹配兩個連續相同的字符。
\oNUM匹配n(其中(zhōng)n爲一(yī)個小(xiǎo)于256的八進制換碼值)。例如:
\o011 匹配制表符
\xNUM匹配NUM(其中(zhōng)NUM爲一(yī)個小(xiǎo)于256的十六進制換碼值)。例如:
\x41 匹配字符"A"
應用實例
在對正則表達式有了較爲全面的了解之後,就可以在Perl,PHP,以及ASP等程式中(zhōng)使用正則表達式了。
下(xià)面以PHP語言爲例,使用驗證用戶在線輸入的郵件地址以及網址的格式是否正确。PHP 提供了eregi()或ereg()資(zī)料處理函數實現字串比對剖析的模式匹配操作ereg()函數的使用格式如下(xià):
ereg (pattern, string)
其中(zhōng),pattern代表正則表達式的模式;而string則是執行查找替換操作的目标對象,如Email地址值。本函式以 pattern 的規則來剖析比對字串 string,找到則傳回值爲 true。函式ereg()與eregi()的區别就是前者區分(fēn)大(dà)小(xiǎo)寫,後者與大(dà)小(xiǎo)寫無關。使用PHP編寫的程序代碼如下(xià):
<?php
if (ereg("^([a-z0-9_-])+@([a-zZ0-9_-])+(\.[a-z0-9_-])+[a-z]{2,3}$",$email))
{ echo "您的 E-Mail 通過初步檢查!";}
else
{ echo "不是合法的E-Mail 地址,請重新輸入!";}
?>
這個例子是可對使用者輸入的 E-Mail 作簡單的檢查,檢查使用者的 E-Mail 字串是否有 @ 字元,在 @ 字元前有小(xiǎo)寫英文字母、數字或下(xià)"_",在 @ 之後有數節字串,最後的小(xiǎo)數點後隻能有二個或三個小(xiǎo)寫英文字母。如webmaster@mail.sever.net, hello_2001@88new.cn就可以通過檢查,而New99@253.com(出現大(dà)寫字母)和new99@253.comn(最後的小(xiǎo)數點後隻能超過3個英文字母)就不能通過檢查。
我(wǒ)(wǒ)們通過調用自定義正規則判别函式也可以進行檢查操作,如下(xià)面的網址檢驗函式:
function VerifyWebSiteAddr ($strWebSiteAddr){
return (eregi ("^([_0-9a-z-]+.)+([0-9a-z-]+.)+[a-z]{2,3}$", $strWebSiteAddr));
}
我(wǒ)(wǒ)們知(zhī)道,PHP程式的運行必須有服務器支持,如果您在自己的主頁上想實現以上功能, 嵌入式腳本語言javascript或許是好的選擇。javascript中(zhōng)帶有一(yī)個功能強大(dà)的RegExp()對象,可以用來進行正則表達式的匹配操作。其中(zhōng)的test()方法可以檢驗目标對象中(zhōng)是否包含匹配模式,并相應的返回true或false。隻須在HTML文檔的<head>區域添加一(yī)段javascript代碼。
< language="javascript1.2">
function verifyAddress(obj){
var email = obj.email.value;
var pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
flag = pattern.test(email);
if(flag){
alert("您的 E-Mail 通過初步檢查!");
return true;}
else{
alert("不是合法的E-Mail 地址,請重新輸入!");
return false;}
}
</script>
然後在網頁中(zhōng)輸入信息的表單域<form>标簽區域内中(zhōng)加入一(yī)行如下(xià)代碼:
<onSubmit="return verifyAddress(this);">
當按下(xià)提交按鈕後,首先運行verifyAddress()函式,進行匹配識别,如果滿足條件則發送表單信息到目标頁面,否則返回錯誤信息。
事實上,正則表達式的功能遠非本文提到的這一(yī)點,下(xià)次,給大(dà)家介紹一(yī)種使用正則表達式從任意指定網頁中(zhōng)析取任意種類文本信息(如網頁中(zhōng)所有的圖片文件名)的技巧。
Html源文件中(zhōng)image标簽的析取
上篇,我(wǒ)(wǒ)們介紹了正則表達式的概念及其在網絡編程中(zhōng)使用正則表達式驗證用戶在線輸入的郵件地址以及網址的格式是否正确的應用實例,今天介紹一(yī)種從指定網頁源文件中(zhōng)析取image标簽的的編程技巧,即從網頁源文件中(zhōng),解析出所有的插圖文件名(包括圖片路徑),也就是标簽<img src=".../.../abc.jpg"> 中(zhōng)的文件名".../.../abc.jpg"(有的可能是gif格式)。編程環境:PHP+Apache for Win98。
首先, 用文本編輯器新建一(yī)個PHP類型的文件:abstractSRCfrompage.php3。爲了方便講解,我(wǒ)(wǒ)們打算是在浏覽器表單域中(zhōng)輸入需要析取image标簽的網頁的URL(或本機文檔),提交後執行析取操作,所以在該文件中(zhōng),我(wǒ)(wǒ)們要建立一(yī)個用于輸入網址的表單,舉例如下(xià):
<form action=" abstractSRCfrompage.php3" method="post">
輸入網址<input type=text name=filename><br>
<input type=submit name=submit value="提交">
</form>
輸入正确的網址,提交後表單信息被送到abstractSRCfrompage.php3頁面,由于表單本身就在該頁面,所以相當于被送到自身頁面,下(xià)面我(wǒ)(wǒ)們需要編寫析取處理的PHP代碼,緊接着表單代碼段後寫入如下(xià)代碼:
<?php
if ($filename!=""){
$fp = fopen($filename, "r"); file&://若輸入不爲空,開(kāi)啓本地或者遠程檔案;
while ($buffer = fgets($fp, 1024)) {
$source .=$buffer; }
fclose($fp);
file&://查找$source中(zhōng)是否有<img ...src=".../...gif | jpg"> 這樣的标記
if(eregi("(<img)+[^<>]+(src=\")+[^\*\"<>|]+(\.)+((gif)|(jpg))+(\")",$source)) {
echo "找到圖片标簽:)<br>";}
else{
echo "未發現圖片标簽:(<br>";}
file&://拆分(fēn),第一(yī)次用标簽,<img ...src=拆分(fēn),得到了以圖形文件名開(kāi)頭的數組,
$splitres=split("((\">)|())+(<img)+[^<>]+(src=\")",$source);
echo "找到: $imagenums-1個圖片<br>分(fēn)别爲:<br>";
for($i=1;$i<sizeof($splitres);$i++){
file&://二次拆分(fēn),用"拆分(fēn)。因爲文件名能含有",得到的拆分(fēn)數組的第一(yī)個元素就是路徑+文件名了;
unset($imgname); // 再次使用前删除imgname變量;
$imgname=spliti("\"",$splitres[$i]);//将析取的圖片信息依次賦給imgname變量
echo "$i=>".$imgname[0]."<br>"; file&://輸出析取的圖片信息
}
}
?>
該段程序的設計思路是:PHP程式判斷是否輸入了檔案名稱(網址URL或本機檔案名),若不爲空則以隻讀方式打開(kāi)該檔案;接着使用函式fgets(fp,length)取得檔案指标fp所指的行并傳回該行内長度爲length-1 的字串,上例中(zhōng)就是1024-1=1023;然後利用字串比對剖析函式ereg()查找$source中(zhōng)是否含有<img ...src=".../...gif | jpg"> 這樣的标記(關于該函式在上篇中(zhōng)有詳細的介紹);假如找到的話(huà),則利用split()函式按一(yī)定的規則執行兩次拆分(fēn),去(qù)掉标記中(zhōng)的<img…src=字符和"字符,結果得到數組splitres,其中(zhōng)的每一(yī)個元素都是以圖形路徑+文件名開(kāi)頭的數組;用for循環在屏幕上輸出每個數組的第一(yī)個元素值,即我(wǒ)(wǒ)們所需要的所有圖形路徑+文件名。
其中(zhōng)函式sizeof($splitres)返回個數;在for循環中(zhōng),依次将數組splitres的每個元素(也是數組)賦給數組變量imgname,并輸出imgname的第一(yī)個元素值(爲找到的一(yī)個圖形路徑+文件名),當執行下(xià)次循環時,删除變量imgname,達到重複使用的目的。大(dà)家可以仔細研究其中(zhōng)的奧妙。
好了,寫好後,将abstractSRCfrompage.php3存到你的服務器指定目錄下(xià),啓動Apache服務器,在浏覽器中(zhōng)打開(kāi)它,随便輸入一(yī)個存在的網頁名稱或是遠程URL,看看效果如何。
如果有興趣,你可以嘗試析取HTML文檔中(zhōng)的任意感興趣的信息,如果稍加改裝,做一(yī)個網站文本搜索引擎豈不更妙?
正則表達式在UBB論壇中(zhōng)的應用
一(yī)、UBB代碼的概念
什麽是UBB代碼?
UBB代碼是HTML的一(yī)個變種。一(yī)般情況下(xià),UBB論壇不允許你使用HTML代碼,而隻能用UBB代碼替代HTML代碼。
UBB代碼是一(yī)套由流行的UBB标簽組成了固定代碼,代碼有統一(yī)的格式。用戶隻要遵循代碼規則就可以實現用戶想要的功能。如:
想要顯示粗體(tǐ)的how are you 字樣,就應該輸入 how are you而不是輸入<b>how are you</b>
你也許會問:ASP是怎樣把 how are you轉換爲<b>how are you</b>的呢?
回答這個問題就是:用正則表達式。
二、實例分(fēn)析
1)在字符串中(zhōng)精确查找鏈接地址
((http|https|ftp):(\/\/|\\\\)((\w)+[.]){1,}(net|com|cn|org|cc|tv|[0-9]{1,3})(((\/[\~]*|\\[\~]*)
(\w)+)|[.](\w)+)*(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)
我(wǒ)(wǒ)們知(zhī)道,鏈接地址一(yī)般以http或者https或者ftp等形式出現。初步總結一(yī)下(xià)就是,鏈接地址必須符合如下(xià)條件:
條件1
以http://或者https://或者ftp://等開(kāi)頭(當然還有其它形式,這裏隻列出主要的)
條件2
http://後面必須跟一(yī)個單詞字符,緊接着單詞字符後面的是"."(這樣的組合必須出現一(yī)次或多次)。緊跟着"."後面的是域名後綴(如net或者com或者cn等,如果是以IP地址的形式出現就可以是數字)
條件3
出現完整的鏈接地址後,還可以出現下(xià)一(yī)級或者更多級的目錄(還要注意個人主頁的地址有可能出現"~"符号)
條件4
鏈接地址末尾可以帶參數。如典型的頁數?PageNo=2&action=display等
現在我(wǒ)(wǒ)們用下(xià)面的代碼來逐個匹配上面的條件--
1、((http|https|ftp):(\/\/|\\\\) 滿足條件1
表示http:// http:\\ https:// https:\\ ftp:// ftp:\\都匹配(在這裏考慮了某些用戶可能把"//"輸成"\\"的易發性錯誤)
注意:"|"表示"或者","\"是轉義字符。"\/\/"表示"//","\\\\"表示"\\"
2、((\w)+[.]){1,}(net|com|cn|org|cc|tv|[0-9]{1,3}) 滿足條件2
"((\w)+[.]){1,}"表示一(yī)個單詞字符加一(yī)個點号可以出現1次或者多次(這裏考慮了某些用戶喜歡省略www而将http://www.w3c.com寫成http://w3c.com)
"(net|com|cn|org|cc|tv|[0-9]{1,3})"表示必須要以net或者com或者cn或者org或者cc或者tv或者三位以下(xià)的數字結束
[0-9]{1,3}表示三位以下(xià)的數字,因爲ip地址的任何段不能超過255
3、(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)* 滿足條件3
"(\/[\~]*|\\[\~]*)"表示可以出現"/~"或者是"\~",(其中(zhōng)"[\~]*"表示 ~ 可以出現也可以不出現),因爲不是每個鏈接地址都有下(xià)一(yī)級目錄
"(\w)+)|[.](\w)+)"表示必須出現一(yī)個單詞字符(即目錄或者是一(yī)個帶有擴展名的文件)
注意:最後還有一(yī)個"*"表示上面括号内的可以出現也可以不出現,否則就隻能匹配有下(xià)一(yī)級目錄的鏈接地址了。
4、(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)滿足條件4
"((([?](\w)+){1}[=]*))*((\w)+){1}"表示形如"?PageNo=2"的字符串可以出現也可以不出現,如果出現則隻能出現一(yī)次(因爲不可能有兩個"?"号出現)。
"([\&](\w)+[\=](\w)+)*)"表示形如"&action=display"的字符串可以出現也可以不出現(因爲并不是每個網頁都帶有兩個以上的參數。
整個"((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*"表示形如"?PageNo=2&action=display"的字符串可以出現也可以不出現(即鏈接地址可以有參數也可以沒有參數)
把上面的組合起來,我(wǒ)(wǒ)們就可以匹配一(yī)個比較全面的鏈接地址了。比用簡單的"(http:\/\/\S+)"來匹配一(yī)個鏈接地址要好,讀者可以自行行測試比較。當然,這段代碼還有很多不足之處,希望大(dà)家能夠繼續改進。
2)替代典型的UBB标簽:[b][/b]
我(wǒ)(wǒ)們的目的就是要把[b][/b]成對的替換成<b></b>下(xià)面來看我(wǒ)(wǒ)們實現它的模闆
(\[b\])(.+)(\[\/b\])
這裏用了"(.+)"來配匹到之間的整個字符串,在替代的時候我(wǒ)(wǒ)們要寫成這樣
str=checkexp(re,str,"<b>$2</b>")
(注意:checkexp是我(wǒ)(wǒ)自定義的函數,将在後面給出。這個函數将把[b][/b]按照我(wǒ)(wǒ)們提供的模闆進行替代。)
也許你會問這裏出現一(yī)個"$2"是什麽東東,呵注意了這個$2可是很重要的,它代表了"(.+)"所配匹的整個字符串。
爲什麽是$2而不是$1、$3呢?因爲$1代表(\[b\])所匹配的"[b]"字符串,$3代表(\[\/b\])所匹配的"[/b]"字符串,顯然這裏我(wǒ)(wǒ)們需要的是$2而不是$1$3。
三、UBB正則表達模闆實例
下(xià)面是我(wǒ)(wǒ)寫的一(yī)個UBB函數,這個函數基本上能使你的論壇成爲一(yī)個優秀的UBB代碼論壇了。當然,通過改進後,你可以得到一(yī)個更強大(dà)的UBB論壇。
Function ReThestr(face,str)
dim re,str
re="\>"
str=checkexp(re,str,">")
re="\<"
str=checkexp(re,str,"<")
re="\n\r\n/"
str=checkexp(re,str,"<P>")
re=chr(32)
str=checkexp(re,str," ")
re="\r"
str=checkexp(re,str," ")
re="\[img\]((http:(\/\/|\\\\)){1}((\w)+[.]){1,3}_
(net|com|cn|org|cc|tv)(((\/[\~]*|\\[\~]*)
(\w)+)|[.](\w)+)*(\w)+[.]{1}(gif|jpg|png))\[\/img\]" '查找圖片地址
str=checkexp(re,str," <img src='$1'> ")
re="\[w\](http:(\/\/|\\\\)((\w)+[.]){1,}_
(net|com|cn|org|cc|tv)(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)*
(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)\[\/w\]" '查找幀地址
str=checkexp(re,str,"<iframe width='300' height='300' src='$1'></iframe>")
re="([^('>)])(<br>)*((http|https|ftp):_
(\/\/|\\\\)((\w)+[.]){1,}(net|com|cn|org|cc|tv|_
([0-9]{1,3}))(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)*_
(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)" '查找鏈接地址
str=checkexp(re,str,"$1$2 <a href='$3' target=_blank>$3</a> ")
re="([^(http://|http:\\)])((www|cn)[.](\w)+[.]{1,}_
(net|com|cn|org|cc)(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)*
(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)
" '查找不以http://開(kāi)頭的地址
str=checkexp(re,str,"$1 <a href='http://$2' target=_blank>$2</a> ")
re="([^(=)])((\w)+[@]{1}((\w)+[.]){1,3}(\w)+)" '查找郵件地址
str=checkexp(re,str," <a href='mailto:$2'>$2</a> ")
re="\[color=(((\w)+)|[#][0-F]{6})\]((.)+)\[\/color\]" '替換字體(tǐ)色彩
str=checkexp(re,str,"<font color='$1'>$4</font>")
re="\[size=([0-9]{1})\]((.)+)\[\/size\]" '替換字體(tǐ)大(dà)小(xiǎo)
str=checkexp(re,str,"<font size='$1'>$2</font>")
re="\[font=((.)+){1,3}\]((.)+)\[\/font\]" '替換字體(tǐ)
str=checkexp(re,str,"<font face='$1'>$3</font>")
re="(\[b\])(.+)(\[\/b\])" '加粗字體(tǐ)
str=checkexp(re,str,"<b>$2</b>")
re="(\[u\])(.+)(\[\/u\])" '下(xià)畫線
str=checkexp(re,str,"<u>$2</u>")
re="(\[li\])(.+)(\[\/li\])" '列表
str=checkexp(re,str,"<li>$2</li>")
re="(\[QUOTE\])(.+)(\[\/QUOTE\])" '引用
str=checkexp(re,str,"_
<BLOCKQUOTE>引用:<HR SIZE=1>$2<HR SIZE=1></BLOCKQUOTE>")
re="\[email=((\w)+[@]{1}((\w)+[.]){1,3}(\w)+)\](.+)(\[\/email\])" '郵件
str=checkexp(re,str,"<a href=mailto:$1>$6</a>")
re="(\[center\])(.+)(\[\/center\])" '居中(zhōng)
str=checkexp(re,str,"<center>$2</center>")
re="fuck"
str=checkexp(re,str,"***")
re="操"
str=checkexp(re,str,"***")
re="sex"
str=checkexp(re,str,"***")
re="TMD"
str=checkexp(re,str,"***")
re="shit"
str=checkexp(re,str,"***")
ReThestr=str
end function
UBB代碼如下(xià):
[email=] [/email] 690 ){ this.width=690;}" />
[li] [/li] [font=impact] [/font]
測試代碼如下(xià):
690 ){ this.width=690;}" />http://cn.yahoo.com
http://aol.com http://192.168.0.1
www.yahoo.com how are you[/b]
http://page2000.xiloo.com/~page2000?PageNo=2&action=del
lucaihui@cmmail.com 大(dà)家好http:\\page2000.shit
<font color=red>http://test.com</font>http://test
全部符合預想結果
ASP正則表達式對像函數如下(xià):
Function CheckExp(patrn,strng,tagstr)
Dim regEx,Matches
Set regEx=New RegExp'建立一(yī)個新對像
regEx.Pattern=patrn'設置模闆
regEx.IgnoreCase=true'搜索是否區分(fēn)大(dà)小(xiǎo)寫的 true表是不區分(fēn) flase表示區分(fēn)
regEx.Global=True'搜索是否應用于整個字符串
Matches=regEx.replace(strng,tagstr)'匹配并替代字符串
CheckExp=Matches'返回函數結果
end function
把上面的兩個函數存爲一(yī)個頁面(如ubbcode.asp),這樣就組成一(yī)個完整的UBB函數了。
在你的論壇上加上這個函數,就成了支持UBB代碼的論壇了。隻要在用時調用這個函數就行了。調用形式如
text=ReThestr(text)
如果你要進一(yī)步測試,可以到http://www.4u2v.com/bbs去(qù)測試,因爲該論壇就采用了此模闆。
正則表達式簡介
簡單的說,正則表達式是一(yī)種可以用于模式匹配和替換的強有力的工(gōng)具。在網絡編程中(zhōng)應用廣泛,如PHP腳本語言或是javascript、VBScript這樣的客戶端腳本語言都提供了對正則表達式的支持。由此可見,正則表達式已經超出了某種語言或某個系統的局限,成爲人們廣爲接受的概念和功能。
正則表達式可以讓用戶通過使用一(yī)系列的特殊字符構建匹配模式,然後把匹配模式與數據文件、程序輸入以及WEB頁面的表單輸入等目标對象進行比較,根據比較對象中(zhōng)是否包含匹配模式,執行相應的程序。
舉例來說,正則表達式的一(yī)個最爲普遍的應用就是用于驗證用戶在線輸入的郵件地址的格式是否正确,如果通過正則表達式驗證用戶郵件地址的格式正确,用戶所填寫的表單信息将會被正常處理;反之,如果用戶輸入的郵件地址與正則表達的模式不匹配,将會彈出提示信息,要求用戶重新輸入正确的郵件地址。由此可見正則表達式在WEB應用的邏輯判斷中(zhōng)具有舉足輕重的作用。在後面我(wǒ)(wǒ)們會舉例詳細介紹。
正則表達式形式一(yī)般如:/love/,其中(zhōng)位于"/"定界符之間的部分(fēn)就是将要在目标對象中(zhōng)進行匹配的模式。用戶隻要把希望查找匹配對象的模式内容放(fàng)入"/"定界符之間即可。爲了能夠使用戶更加靈活的定制模式内容,正則表達式提供了專門的"元字符"。所謂元字符就是指那些在正則表達式中(zhōng)具有特殊意義的專用字符,可以用來規定其前導字符(即位于元字符前面的字符)在目标對象中(zhōng)的出現模式。較爲常用的元字符包括: "+,"*,?以及{}",或者"\s,\S,\d,\w和\W"等等。爲了能夠方便用戶更加靈活的設定匹配模式,正則表達式允許使用者在匹配模式中(zhōng)利用[]界定匹配于某一(yī)個範圍的字符而不局限于具體(tǐ)的字符。
除了我(wǒ)(wǒ)們以上的元字符之外(wài),正則表達式中(zhōng)還具有另外(wài)一(yī)種較爲獨特的專用字符,即定位符。定位符用于規定匹配模式在目标對象中(zhōng)的出現位置。較爲常用的定位符包括: "^", "$", "\b" 以及 "\B"。
如果我(wǒ)(wǒ)們希望在正則表達式中(zhōng)實現類似編程邏輯中(zhōng)的"或"運算,在多個不同的模式中(zhōng)任選一(yī)個進行匹配的話(huà),可以使用管道符 "|"。例如:
正則表達式中(zhōng)還有一(yī)個較爲常用的運算符,即否定符 "[^]"。與我(wǒ)(wǒ)們前文所提到的定位符 "^" 不同,否定符 "[^]"規定目标對象中(zhōng)不能存在模式中(zhōng)所規定的字符串。一(yī)般來說,當"^"出現在 "[]"内時就被視做否定運算符;而當"^"位于"[]"之外(wài),或沒有"[]"時,則應當被視做定位符。
最後,當用戶需要在正則表達式的模式中(zhōng)加入元字符,并查找其匹配對象時,可以使用轉義符"\"。例如:/Th\*/,該正則表達式将會與目标對象中(zhōng)的"Th*"而非"The"等相匹配。
正則表達式的語法規則和标記
現在我(wǒ)(wǒ)們正式進入則表達式的學習,我(wǒ)(wǒ)會根據實例結合講解正則表達式的用法,看完後你就會覺得寫UBB代碼如此簡單了,隻要你一(yī)步一(yī)步的跟着我(wǒ)(wǒ)學 看完本文章後你就成爲UBB高手了。激動人心的就是你能寫出自已的UBB标簽來了,再也不用到别人那裏去(qù)拷貝現成的代碼和模闆了。 還好VBScritp5.0給我(wǒ)(wǒ)們提供了"正則表達式"對象,隻要你的服務器安裝了IE5.x,就可以運行了.
字符描述:
^符号匹配字符串的開(kāi)頭。例如:
^abc 與"abc xyz"匹配,而不與"xyz abc"匹配
$符号匹配字符串的結尾。例如:
abc$ 與"xyz abc"匹配,而不與"abc xyz"匹配。
注意:如果同時使用^符号和$符号,将進行精确匹配。例如:
^abc$ 隻與"abc"匹配
*符号匹配0個或多個前面的字符。例如:
ab* 可以匹配"ab"、"abb"、"abbb"等
+符号匹配至少一(yī)個前面的字符。例如:
ab+ 可以匹配"abb"、"abbb"等,但不匹配"ab"。
?符号匹配0個或1個前面的字符。例如:
ab?c? 可以且隻能匹配"abc"、"abbc"、"abcc"和"abbcc"
.符号匹配除換行符以外(wài)的任何字符。例如:
(.)+ 匹配除換行符以外(wài)的所有字符串
x|y匹配"x"或"y"。例如:
abc|xyz 可匹配 "abc"或 "xyz",而"ab(c|x)yz"匹配 "abcyz"和"abxyz"
{n}匹配恰好n次(n爲非負整數)前面的字符。例如:
a{2} 可以匹配"aa",但不匹配"a"
{n,}匹配至少n次(n爲非負整數)前面的字符。例如:
a{3,} 匹配"aaa"、"aaaa"等,但不匹配"a"和"aa"。
注意:a{1,}等價于a+
a{0,}等價于a*
{m,n}匹配至少m個,至多n個前面的字符。例如:
a{1,3} 隻匹配"a"、"aa"和"aaa"。
注意:a{0,1}等價于a?
[xyz]表示一(yī)個字符集,匹配括号中(zhōng)字符的其中(zhōng)之一(yī)。例如:
[abc] 匹配"a"、"b"和"c"
[^xyz]表示一(yī)個否定的字符集。匹配不在此括号中(zhōng)的任何字符。例如:
[^abc] 可以匹配除"a"、"b"和"c"之外(wài)的任何字符
[a-z]表示某個範圍内的字符,匹配指定區間内的任何字符。例如:
[a-z] 匹配從"a"到"z"之間的任何一(yī)個小(xiǎo)寫字母字符
[^m-n]表示某個範圍之外(wài)的字符,匹配不在指定範圍内的字符。例如:
[m-n] 匹配除從"m"到"n"之間的任何字符
\符号是轉義操作符。例如:
\n 換行符
\f 分(fēn)頁符
\r 回車(chē)
\t 制表符
\v 垂直制表符
\\ 匹配"\"
\/ 匹配"/"
\s 任何白(bái)字符,包括空格、制表符、分(fēn)頁符等。等價于"[ \f\n\r\t\v]"
\S 任何非空白(bái)的字符。等價于"^\f\n\r\t\v]"
\w 任何單詞字符,包括字母和下(xià)劃線。等價于"[A-Za-z0-9_]"
\W 任何非單詞字符。等價于"[^A-Za-z0-9_]"
\b匹配單詞的結尾。例如:
ve\b 匹配單詞"love"等,但不匹配"very"、"even"等
\B匹配單詞的開(kāi)頭。例如:
ve\B 匹配單詞"very"等,但不匹配"love"等
\d匹配一(yī)個數字字符,等價于[0-9]。例如:
abc\dxyz 匹配"abc2xyz"、"abc4xyz"等,
但不匹配"abcaxyz"、"abc-xyz"等
\D匹配一(yī)個非數字字符,等價于[^0-9]。例如:
abc\Dxyz 匹配"abcaxyz"、"abc-xyz"等,
但不匹配"abc2xyz"、"abc4xyz"等
\NUM匹配NUM個(其中(zhōng)NUM爲一(yī)個正整數),引用回到記住的匹配。例如:
(.)\1 匹配兩個連續相同的字符。
\oNUM匹配n(其中(zhōng)n爲一(yī)個小(xiǎo)于256的八進制換碼值)。例如:
\o011 匹配制表符
\xNUM匹配NUM(其中(zhōng)NUM爲一(yī)個小(xiǎo)于256的十六進制換碼值)。例如:
\x41 匹配字符"A"
應用實例
在對正則表達式有了較爲全面的了解之後,就可以在Perl,PHP,以及ASP等程式中(zhōng)使用正則表達式了。
下(xià)面以PHP語言爲例,使用驗證用戶在線輸入的郵件地址以及網址的格式是否正确。PHP 提供了eregi()或ereg()資(zī)料處理函數實現字串比對剖析的模式匹配操作ereg()函數的使用格式如下(xià):
ereg (pattern, string)
其中(zhōng),pattern代表正則表達式的模式;而string則是執行查找替換操作的目标對象,如Email地址值。本函式以 pattern 的規則來剖析比對字串 string,找到則傳回值爲 true。函式ereg()與eregi()的區别就是前者區分(fēn)大(dà)小(xiǎo)寫,後者與大(dà)小(xiǎo)寫無關。使用PHP編寫的程序代碼如下(xià):
<?php
if (ereg("^([a-z0-9_-])+@([a-zZ0-9_-])+(\.[a-z0-9_-])+[a-z]{2,3}$",$email))
{ echo "您的 E-Mail 通過初步檢查!";}
else
{ echo "不是合法的E-Mail 地址,請重新輸入!";}
?>
這個例子是可對使用者輸入的 E-Mail 作簡單的檢查,檢查使用者的 E-Mail 字串是否有 @ 字元,在 @ 字元前有小(xiǎo)寫英文字母、數字或下(xià)"_",在 @ 之後有數節字串,最後的小(xiǎo)數點後隻能有二個或三個小(xiǎo)寫英文字母。如webmaster@mail.sever.net, hello_2001@88new.cn就可以通過檢查,而New99@253.com(出現大(dà)寫字母)和new99@253.comn(最後的小(xiǎo)數點後隻能超過3個英文字母)就不能通過檢查。
我(wǒ)(wǒ)們通過調用自定義正規則判别函式也可以進行檢查操作,如下(xià)面的網址檢驗函式:
function VerifyWebSiteAddr ($strWebSiteAddr){
return (eregi ("^([_0-9a-z-]+.)+([0-9a-z-]+.)+[a-z]{2,3}$", $strWebSiteAddr));
}
我(wǒ)(wǒ)們知(zhī)道,PHP程式的運行必須有服務器支持,如果您在自己的主頁上想實現以上功能, 嵌入式腳本語言javascript或許是好的選擇。javascript中(zhōng)帶有一(yī)個功能強大(dà)的RegExp()對象,可以用來進行正則表達式的匹配操作。其中(zhōng)的test()方法可以檢驗目标對象中(zhōng)是否包含匹配模式,并相應的返回true或false。隻須在HTML文檔的<head>區域添加一(yī)段javascript代碼。
< language="javascript1.2">
function verifyAddress(obj){
var email = obj.email.value;
var pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
flag = pattern.test(email);
if(flag){
alert("您的 E-Mail 通過初步檢查!");
return true;}
else{
alert("不是合法的E-Mail 地址,請重新輸入!");
return false;}
}
</script>
然後在網頁中(zhōng)輸入信息的表單域<form>标簽區域内中(zhōng)加入一(yī)行如下(xià)代碼:
<onSubmit="return verifyAddress(this);">
當按下(xià)提交按鈕後,首先運行verifyAddress()函式,進行匹配識别,如果滿足條件則發送表單信息到目标頁面,否則返回錯誤信息。
事實上,正則表達式的功能遠非本文提到的這一(yī)點,下(xià)次,給大(dà)家介紹一(yī)種使用正則表達式從任意指定網頁中(zhōng)析取任意種類文本信息(如網頁中(zhōng)所有的圖片文件名)的技巧。
Html源文件中(zhōng)image标簽的析取
上篇,我(wǒ)(wǒ)們介紹了正則表達式的概念及其在網絡編程中(zhōng)使用正則表達式驗證用戶在線輸入的郵件地址以及網址的格式是否正确的應用實例,今天介紹一(yī)種從指定網頁源文件中(zhōng)析取image标簽的的編程技巧,即從網頁源文件中(zhōng),解析出所有的插圖文件名(包括圖片路徑),也就是标簽<img src=".../.../abc.jpg"> 中(zhōng)的文件名".../.../abc.jpg"(有的可能是gif格式)。編程環境:PHP+Apache for Win98。
首先, 用文本編輯器新建一(yī)個PHP類型的文件:abstractSRCfrompage.php3。爲了方便講解,我(wǒ)(wǒ)們打算是在浏覽器表單域中(zhōng)輸入需要析取image标簽的網頁的URL(或本機文檔),提交後執行析取操作,所以在該文件中(zhōng),我(wǒ)(wǒ)們要建立一(yī)個用于輸入網址的表單,舉例如下(xià):
<form action=" abstractSRCfrompage.php3" method="post">
輸入網址<input type=text name=filename><br>
<input type=submit name=submit value="提交">
</form>
輸入正确的網址,提交後表單信息被送到abstractSRCfrompage.php3頁面,由于表單本身就在該頁面,所以相當于被送到自身頁面,下(xià)面我(wǒ)(wǒ)們需要編寫析取處理的PHP代碼,緊接着表單代碼段後寫入如下(xià)代碼:
<?php
if ($filename!=""){
$fp = fopen($filename, "r"); file&://若輸入不爲空,開(kāi)啓本地或者遠程檔案;
while ($buffer = fgets($fp, 1024)) {
$source .=$buffer; }
fclose($fp);
file&://查找$source中(zhōng)是否有<img ...src=".../...gif | jpg"> 這樣的标記
if(eregi("(<img)+[^<>]+(src=\")+[^\*\"<>|]+(\.)+((gif)|(jpg))+(\")",$source)) {
echo "找到圖片标簽:)<br>";}
else{
echo "未發現圖片标簽:(<br>";}
file&://拆分(fēn),第一(yī)次用标簽,<img ...src=拆分(fēn),得到了以圖形文件名開(kāi)頭的數組,
$splitres=split("((\">)|())+(<img)+[^<>]+(src=\")",$source);
echo "找到: $imagenums-1個圖片<br>分(fēn)别爲:<br>";
for($i=1;$i<sizeof($splitres);$i++){
file&://二次拆分(fēn),用"拆分(fēn)。因爲文件名能含有",得到的拆分(fēn)數組的第一(yī)個元素就是路徑+文件名了;
unset($imgname); // 再次使用前删除imgname變量;
$imgname=spliti("\"",$splitres[$i]);//将析取的圖片信息依次賦給imgname變量
echo "$i=>".$imgname[0]."<br>"; file&://輸出析取的圖片信息
}
}
?>
該段程序的設計思路是:PHP程式判斷是否輸入了檔案名稱(網址URL或本機檔案名),若不爲空則以隻讀方式打開(kāi)該檔案;接着使用函式fgets(fp,length)取得檔案指标fp所指的行并傳回該行内長度爲length-1 的字串,上例中(zhōng)就是1024-1=1023;然後利用字串比對剖析函式ereg()查找$source中(zhōng)是否含有<img ...src=".../...gif | jpg"> 這樣的标記(關于該函式在上篇中(zhōng)有詳細的介紹);假如找到的話(huà),則利用split()函式按一(yī)定的規則執行兩次拆分(fēn),去(qù)掉标記中(zhōng)的<img…src=字符和"字符,結果得到數組splitres,其中(zhōng)的每一(yī)個元素都是以圖形路徑+文件名開(kāi)頭的數組;用for循環在屏幕上輸出每個數組的第一(yī)個元素值,即我(wǒ)(wǒ)們所需要的所有圖形路徑+文件名。
其中(zhōng)函式sizeof($splitres)返回個數;在for循環中(zhōng),依次将數組splitres的每個元素(也是數組)賦給數組變量imgname,并輸出imgname的第一(yī)個元素值(爲找到的一(yī)個圖形路徑+文件名),當執行下(xià)次循環時,删除變量imgname,達到重複使用的目的。大(dà)家可以仔細研究其中(zhōng)的奧妙。
好了,寫好後,将abstractSRCfrompage.php3存到你的服務器指定目錄下(xià),啓動Apache服務器,在浏覽器中(zhōng)打開(kāi)它,随便輸入一(yī)個存在的網頁名稱或是遠程URL,看看效果如何。
如果有興趣,你可以嘗試析取HTML文檔中(zhōng)的任意感興趣的信息,如果稍加改裝,做一(yī)個網站文本搜索引擎豈不更妙?
正則表達式在UBB論壇中(zhōng)的應用
一(yī)、UBB代碼的概念
什麽是UBB代碼?
UBB代碼是HTML的一(yī)個變種。一(yī)般情況下(xià),UBB論壇不允許你使用HTML代碼,而隻能用UBB代碼替代HTML代碼。
UBB代碼是一(yī)套由流行的UBB标簽組成了固定代碼,代碼有統一(yī)的格式。用戶隻要遵循代碼規則就可以實現用戶想要的功能。如:
想要顯示粗體(tǐ)的how are you 字樣,就應該輸入 how are you而不是輸入<b>how are you</b>
你也許會問:ASP是怎樣把 how are you轉換爲<b>how are you</b>的呢?
回答這個問題就是:用正則表達式。
二、實例分(fēn)析
1)在字符串中(zhōng)精确查找鏈接地址
((http|https|ftp):(\/\/|\\\\)((\w)+[.]){1,}(net|com|cn|org|cc|tv|[0-9]{1,3})(((\/[\~]*|\\[\~]*)
(\w)+)|[.](\w)+)*(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)
我(wǒ)(wǒ)們知(zhī)道,鏈接地址一(yī)般以http或者https或者ftp等形式出現。初步總結一(yī)下(xià)就是,鏈接地址必須符合如下(xià)條件:
條件1
以http://或者https://或者ftp://等開(kāi)頭(當然還有其它形式,這裏隻列出主要的)
條件2
http://後面必須跟一(yī)個單詞字符,緊接着單詞字符後面的是"."(這樣的組合必須出現一(yī)次或多次)。緊跟着"."後面的是域名後綴(如net或者com或者cn等,如果是以IP地址的形式出現就可以是數字)
條件3
出現完整的鏈接地址後,還可以出現下(xià)一(yī)級或者更多級的目錄(還要注意個人主頁的地址有可能出現"~"符号)
條件4
鏈接地址末尾可以帶參數。如典型的頁數?PageNo=2&action=display等
現在我(wǒ)(wǒ)們用下(xià)面的代碼來逐個匹配上面的條件--
1、((http|https|ftp):(\/\/|\\\\) 滿足條件1
表示http:// http:\\ https:// https:\\ ftp:// ftp:\\都匹配(在這裏考慮了某些用戶可能把"//"輸成"\\"的易發性錯誤)
注意:"|"表示"或者","\"是轉義字符。"\/\/"表示"//","\\\\"表示"\\"
2、((\w)+[.]){1,}(net|com|cn|org|cc|tv|[0-9]{1,3}) 滿足條件2
"((\w)+[.]){1,}"表示一(yī)個單詞字符加一(yī)個點号可以出現1次或者多次(這裏考慮了某些用戶喜歡省略www而将http://www.w3c.com寫成http://w3c.com)
"(net|com|cn|org|cc|tv|[0-9]{1,3})"表示必須要以net或者com或者cn或者org或者cc或者tv或者三位以下(xià)的數字結束
[0-9]{1,3}表示三位以下(xià)的數字,因爲ip地址的任何段不能超過255
3、(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)* 滿足條件3
"(\/[\~]*|\\[\~]*)"表示可以出現"/~"或者是"\~",(其中(zhōng)"[\~]*"表示 ~ 可以出現也可以不出現),因爲不是每個鏈接地址都有下(xià)一(yī)級目錄
"(\w)+)|[.](\w)+)"表示必須出現一(yī)個單詞字符(即目錄或者是一(yī)個帶有擴展名的文件)
注意:最後還有一(yī)個"*"表示上面括号内的可以出現也可以不出現,否則就隻能匹配有下(xià)一(yī)級目錄的鏈接地址了。
4、(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)滿足條件4
"((([?](\w)+){1}[=]*))*((\w)+){1}"表示形如"?PageNo=2"的字符串可以出現也可以不出現,如果出現則隻能出現一(yī)次(因爲不可能有兩個"?"号出現)。
"([\&](\w)+[\=](\w)+)*)"表示形如"&action=display"的字符串可以出現也可以不出現(因爲并不是每個網頁都帶有兩個以上的參數。
整個"((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*"表示形如"?PageNo=2&action=display"的字符串可以出現也可以不出現(即鏈接地址可以有參數也可以沒有參數)
把上面的組合起來,我(wǒ)(wǒ)們就可以匹配一(yī)個比較全面的鏈接地址了。比用簡單的"(http:\/\/\S+)"來匹配一(yī)個鏈接地址要好,讀者可以自行行測試比較。當然,這段代碼還有很多不足之處,希望大(dà)家能夠繼續改進。
2)替代典型的UBB标簽:[b][/b]
我(wǒ)(wǒ)們的目的就是要把[b][/b]成對的替換成<b></b>下(xià)面來看我(wǒ)(wǒ)們實現它的模闆
(\[b\])(.+)(\[\/b\])
這裏用了"(.+)"來配匹到之間的整個字符串,在替代的時候我(wǒ)(wǒ)們要寫成這樣
str=checkexp(re,str,"<b>$2</b>")
(注意:checkexp是我(wǒ)(wǒ)自定義的函數,将在後面給出。這個函數将把[b][/b]按照我(wǒ)(wǒ)們提供的模闆進行替代。)
也許你會問這裏出現一(yī)個"$2"是什麽東東,呵注意了這個$2可是很重要的,它代表了"(.+)"所配匹的整個字符串。
爲什麽是$2而不是$1、$3呢?因爲$1代表(\[b\])所匹配的"[b]"字符串,$3代表(\[\/b\])所匹配的"[/b]"字符串,顯然這裏我(wǒ)(wǒ)們需要的是$2而不是$1$3。
三、UBB正則表達模闆實例
下(xià)面是我(wǒ)(wǒ)寫的一(yī)個UBB函數,這個函數基本上能使你的論壇成爲一(yī)個優秀的UBB代碼論壇了。當然,通過改進後,你可以得到一(yī)個更強大(dà)的UBB論壇。
Function ReThestr(face,str)
dim re,str
re="\>"
str=checkexp(re,str,">")
re="\<"
str=checkexp(re,str,"<")
re="\n\r\n/"
str=checkexp(re,str,"<P>")
re=chr(32)
str=checkexp(re,str," ")
re="\r"
str=checkexp(re,str," ")
re="\[img\]((http:(\/\/|\\\\)){1}((\w)+[.]){1,3}_
(net|com|cn|org|cc|tv)(((\/[\~]*|\\[\~]*)
(\w)+)|[.](\w)+)*(\w)+[.]{1}(gif|jpg|png))\[\/img\]" '查找圖片地址
str=checkexp(re,str," <img src='$1'> ")
re="\[w\](http:(\/\/|\\\\)((\w)+[.]){1,}_
(net|com|cn|org|cc|tv)(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)*
(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)\[\/w\]" '查找幀地址
str=checkexp(re,str,"<iframe width='300' height='300' src='$1'></iframe>")
re="([^('>)])(<br>)*((http|https|ftp):_
(\/\/|\\\\)((\w)+[.]){1,}(net|com|cn|org|cc|tv|_
([0-9]{1,3}))(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)*_
(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)" '查找鏈接地址
str=checkexp(re,str,"$1$2 <a href='$3' target=_blank>$3</a> ")
re="([^(http://|http:\\)])((www|cn)[.](\w)+[.]{1,}_
(net|com|cn|org|cc)(((\/[\~]*|\\[\~]*)(\w)+)|[.](\w)+)*
(((([?](\w)+){1}[=]*))*((\w)+){1}([\&](\w)+[\=](\w)+)*)*)
" '查找不以http://開(kāi)頭的地址
str=checkexp(re,str,"$1 <a href='http://$2' target=_blank>$2</a> ")
re="([^(=)])((\w)+[@]{1}((\w)+[.]){1,3}(\w)+)" '查找郵件地址
str=checkexp(re,str," <a href='mailto:$2'>$2</a> ")
re="\[color=(((\w)+)|[#][0-F]{6})\]((.)+)\[\/color\]" '替換字體(tǐ)色彩
str=checkexp(re,str,"<font color='$1'>$4</font>")
re="\[size=([0-9]{1})\]((.)+)\[\/size\]" '替換字體(tǐ)大(dà)小(xiǎo)
str=checkexp(re,str,"<font size='$1'>$2</font>")
re="\[font=((.)+){1,3}\]((.)+)\[\/font\]" '替換字體(tǐ)
str=checkexp(re,str,"<font face='$1'>$3</font>")
re="(\[b\])(.+)(\[\/b\])" '加粗字體(tǐ)
str=checkexp(re,str,"<b>$2</b>")
re="(\[u\])(.+)(\[\/u\])" '下(xià)畫線
str=checkexp(re,str,"<u>$2</u>")
re="(\[li\])(.+)(\[\/li\])" '列表
str=checkexp(re,str,"<li>$2</li>")
re="(\[QUOTE\])(.+)(\[\/QUOTE\])" '引用
str=checkexp(re,str,"_
<BLOCKQUOTE>引用:<HR SIZE=1>$2<HR SIZE=1></BLOCKQUOTE>")
re="\[email=((\w)+[@]{1}((\w)+[.]){1,3}(\w)+)\](.+)(\[\/email\])" '郵件
str=checkexp(re,str,"<a href=mailto:$1>$6</a>")
re="(\[center\])(.+)(\[\/center\])" '居中(zhōng)
str=checkexp(re,str,"<center>$2</center>")
re="fuck"
str=checkexp(re,str,"***")
re="操"
str=checkexp(re,str,"***")
re="sex"
str=checkexp(re,str,"***")
re="TMD"
str=checkexp(re,str,"***")
re="shit"
str=checkexp(re,str,"***")
ReThestr=str
end function
UBB代碼如下(xià):
[email=] [/email] 690 ){ this.width=690;}" />
[li] [/li] [font=impact] [/font]
測試代碼如下(xià):
690 ){ this.width=690;}" />http://cn.yahoo.com
http://aol.com http://192.168.0.1
www.yahoo.com how are you[/b]
http://page2000.xiloo.com/~page2000?PageNo=2&action=del
lucaihui@cmmail.com 大(dà)家好http:\\page2000.shit
<font color=red>http://test.com</font>http://test
全部符合預想結果
ASP正則表達式對像函數如下(xià):
Function CheckExp(patrn,strng,tagstr)
Dim regEx,Matches
Set regEx=New RegExp'建立一(yī)個新對像
regEx.Pattern=patrn'設置模闆
regEx.IgnoreCase=true'搜索是否區分(fēn)大(dà)小(xiǎo)寫的 true表是不區分(fēn) flase表示區分(fēn)
regEx.Global=True'搜索是否應用于整個字符串
Matches=regEx.replace(strng,tagstr)'匹配并替代字符串
CheckExp=Matches'返回函數結果
end function
把上面的兩個函數存爲一(yī)個頁面(如ubbcode.asp),這樣就組成一(yī)個完整的UBB函數了。
在你的論壇上加上這個函數,就成了支持UBB代碼的論壇了。隻要在用時調用這個函數就行了。調用形式如
text=ReThestr(text)
如果你要進一(yī)步測試,可以到http://www.4u2v.com/bbs去(qù)測試,因爲該論壇就采用了此模闆。