haidong 发表于 2010-2-24 13:33:59

一个用PHP实现的UBB类

<br>                   &lt;?php<BR>/*<BR>如有转载,请注明作者<BR><BR>作者: 何志强<BR>文件: ubb.php<BR>备注: 说是改进,其实核心函数parse()已经完全重写了,而且思路也是不一样的。<BR>不过仍是受何志强的例子的启发,而且测试的例子还有URLCHECK等几个函数也是沿用的何志强的程序,谢谢何志强。<BR>目前还没有颜色的功能,但我会加入的。<BR>如果在程序上有什么BUG或不便的地方,请给我MAIL。<BR>谢谢!<BR>改进功能:<BR>对字符串进行UBB编码,该类目前只支持下列几个简单且实用的编码:<BR>1. URL裢接<BR>http://www.phpexe.com/<BR>http://头可以不需要<BR>如phpexe.com也是可以的。<BR>2. Email裢接<BR>demo@163.net<BR>3. 图片裢接<BR><BR>同URL链接一样,前面的http也可以不要。<BR>4. 文字方面<BR>粗体字<BR>斜体字<BR>加下划线<BR><BR>1号标题字<BR>...<BR>6号标题字<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>注意以下几点:<BR>1. url,email,img等标签是不分大小写的.<BR>2. 在标签中不允许有TAB键出现,但空格允许。<BR>3. 该类要调用htmlencode,htmlencode4textarea,emailcheck函数和urlcheck类.<BR>4. 修改后支持嵌套,但url,email,img这三个标签不是允许嵌套的。<BR>技术资料:<BR>Ultimate Bulletin Board<BR>http://www.ultimatebb.com/<BR>What is UBB Code<BR>http://www.scriptkeeper.com/ubb/ubbcode.html<BR>*/<BR><BR>include("urlcheck.php");<BR>include("otherfunc.php"); //这两个文件的内容,附在最后。<BR><BR>//ubbcode类<BR>class ubbcode{<BR>var $call_time=0;<BR>//可处理标签及处理函数对应表<BR>var $tags = array( //小写的标签 =&gt; 对应的处理函数<BR>'url' =&gt; '$this-&gt;url',<BR>'email' =&gt; '$this-&gt;email',<BR>'img' =&gt; '$this-&gt;img',<BR>'b' =&gt; '$this-&gt;simple',<BR>'i' =&gt; '$this-&gt;simple',<BR>'u' =&gt; '$this-&gt;simple',<BR>'tt' =&gt; '$this-&gt;simple',<BR>'s' =&gt; '$this-&gt;simple',<BR>'strike' =&gt; '$this-&gt;simple',<BR>'h1' =&gt; '$this-&gt;simple',<BR>'h2' =&gt; '$this-&gt;simple',<BR>'h3' =&gt; '$this-&gt;simple',<BR>'h4' =&gt; '$this-&gt;simple',<BR>'h5' =&gt; '$this-&gt;simple',<BR>'h6' =&gt; '$this-&gt;simple',<BR>'sup' =&gt; '$this-&gt;simple',<BR>'sub' =&gt; '$this-&gt;simple',<BR>'em' =&gt; '$this-&gt;simple',<BR>'strong' =&gt; '$this-&gt;simple',<BR>'code' =&gt; '$this-&gt;simple',<BR>'samp' =&gt; '$this-&gt;simple',<BR>'kbd' =&gt; '$this-&gt;simple',<BR>'var' =&gt; '$this-&gt;simple',<BR>'dfn' =&gt; '$this-&gt;simple',<BR>'cite' =&gt; '$this-&gt;simple',<BR>'small' =&gt; '$this-&gt;simple',<BR>'big' =&gt; '$this-&gt;simple',<BR>'blink' =&gt; '$this-&gt;simple'<BR>);<BR>//url裢接属性<BR>var $attr_url;<BR>//url合法性检查对象<BR>var $urlcheck;<BR><BR>function ubbcode($attr_url){<BR>$this-&gt;attr_url = ''.$attr_url;<BR>$this-&gt;urlcheck = new urlcheck();<BR>}<BR><BR>//对$str进行UBB编码解析<BR>function parse($str){<BR>$this-&gt;call_time++;<BR>$parse = ''.htmlencode($str);<BR><BR>$ret = '';<BR>while(true){<BR>$eregi_ret=eregi("\{#]{0,1}{:alnum:}{1,7}\]",$parse,$eregi_arr); //查找<BR>if(!$eregi_ret){<BR>$ret .= $parse;<BR>break; //如果没有,返回<BR>}<BR>$pos = @strpos($parse,$eregi_arr);<BR>$tag_len=strlen($eregi_arr)-2;//标记长度<BR>$tag_start=substr($eregi_arr,1,$tag_len);<BR>$tag=strtolower($tag_start);<BR><BR>if((($tag=="url") or ($tag=="email") or ($tag=="img")) and ($this-&gt;call_time&gt;1)){<BR>echo $this-&gt;call_time."&lt;br&gt;";<BR>return $parse;//如果不能是不能嵌套的标记,直接返回<BR>}<BR><BR>$parse2 = substr($parse,0,$pos);//标记之前<BR>$parse = substr($parse,$pos+$tag_len+2);//标记之后<BR>if(!isset($this-&gt;tags[$tag])){<BR>echo "$tag_start&lt;br&gt;";<BR>$ret .= $parse2.'['.$tag_start.']';<BR>continue;//如果是不支持的标记<BR>}<BR><BR>//查找对对应的结束标记<BR>$eregi_ret=eregi("\[\/".$tag."\]",$parse,$eregi_arr);<BR>if(!$eregi_ret){<BR>$ret .= $parse2.'['.$tag_start.']';<BR>continue;//如果没有对应该的结束标记<BR>}<BR>$pos=strpos($parse,$eregi_arr);<BR>$value=substr($parse,0,$pos);//这是起止标记之间的内容<BR>$tag_end=substr($parse,$pos+2,$tag_len);<BR>$parse=substr($parse,$pos+$tag_len+3);//结束标记之后的内容<BR><BR>if(($tag!="url") and ($tag!="email") and ($tag!="img")){<BR>$value=$this-&gt;parse($value);<BR>}<BR><BR>$ret .= $parse2;<BR>eval('$ret .= '.$this-&gt;tags[$tag].'("'.$tag_start.'","'.$tag_end.'","'.$value.'");');<BR>}<BR>$this-&gt;call_time--;<BR>return $ret;<BR>}<BR><BR>function simple($start,$end,$value){<BR>return '&lt;'.$start.'&gt;'.$value.'&lt;/'.$end.'&gt;';<BR>}<BR><BR>function url($start,$end,$value){<BR>$trim_value=trim($value);<BR>if (strtolower(substr($trim_value,0,7))!="http://")<BR>$trim_value="http://".$trim_value;<BR>if($this-&gt;urlcheck-&gt;check($trim_value)) return '&lt;a href="'.$trim_value.'" '.$this-&gt;attr_url.'&gt;'.$value.'&lt;/a&gt;';<BR>else return '['.$start.']'.$value.'[/'.$end.']';<BR>}<BR><BR>function email($start,$end,$value){<BR>if(emailcheck($value)) return '&lt;a href="mailto:'.$value.'"&gt;'.$value.'&lt;/a&gt;';<BR>else return '['.$start.']'.$value.'[/'.$end.']';<BR>}<BR><BR>function img($start,$end,$value){<BR>$trim_value=trim($value);<BR>if ((strtolower(substr($trim_value,0,7))!="http://") or ($this-&gt;urlcheck-&gt;check($trim_value)))<BR>return '&lt;img src="'.$trim_value.'"&gt;&lt;/img&gt;';<BR>else return '['.$start.']'.$value.'[/'.$end.']';<BR>}<BR>}<BR><BR>//测试<BR>echo '&lt;html&gt;';<BR>echo '&lt;head&gt;&lt;title&gt;测试&lt;/title&gt;&lt;/head&gt;';<BR>echo '&lt;body&gt;';<BR>echo '&lt;form action="'.str2url($PATH_INFO).'" method="post"&gt;';<BR>echo '&lt;textarea cols="100" rows="10" name="ubb"&gt;'.htmlencode4textarea($ubb).'&lt;/textarea&gt;&lt;br&gt;';<BR>echo '&lt;input type="submit" value="转换"&gt;';<BR>echo '&lt;/form&gt;';<BR><BR>if(isset($ubb)){<BR>$ubbcode = new ubbcode('target="_blank"');<BR>echo '&lt;hr&gt;'.$ubbcode-&gt;parse($ubb);<BR>}<BR><BR>echo '&lt;/body&gt;';<BR>echo '&lt;/html&gt;';<BR><BR>?&gt;<BR><BR>文件urlcheck.php的内容<BR>&lt;?php<BR>//urlcheck.php<BR>class urlcheck{<BR>var $regex = array(//协议名(注意在这里必须写成小写) =&gt; 对应的正则表达式<BR>'ftp' =&gt; '$this-&gt;ftpurl',<BR>'file' =&gt; '$this-&gt;fileurl',<BR>'http' =&gt; '$this-&gt;httpurl',<BR>'https' =&gt; '$this-&gt;httpurl',<BR>'gopher' =&gt; '$this-&gt;gopherurl',<BR>'news' =&gt; '$this-&gt;newsurl',<BR>'nntp' =&gt; '$this-&gt;nntpurl',<BR>'telnet' =&gt; '$this-&gt;telneturl',<BR>'wais' =&gt; '$this-&gt;waisurl'<BR>);<BR><BR>var $lowalpha;<BR>var $hialpha;<BR>var $alpha;<BR>var $digit;<BR>var $safe;<BR>var $extra;<BR>var $national;<BR>var $punctuation;<BR>var $reserved;<BR>var $hex;<BR>var $escape;<BR>var $unreserved;<BR>var $uchar;<BR>var $xchar;<BR>var $digits;<BR><BR>var $urlpath;<BR>var $password;<BR>var $user;<BR>var $port;<BR>var $hostnumber;<BR>var $alphadigit;<BR>var $toplabel;<BR>var $domainlabel;<BR>var $hostname;<BR>var $host;<BR>var $hostport;<BR>var $login;<BR><BR>//ftp<BR>var $ftptype;<BR>var $fsegment;<BR>var $fpath;<BR>var $ftpurl;<BR><BR>//file<BR>var $fileurl;<BR><BR>//http,https<BR>var $search;<BR>var $hsegment;<BR>var $hpath;<BR>var $httpurl;<BR><BR>//gopher<BR>var $gopher_string;<BR>var $selector;<BR>var $gtype;<BR>var $gopherurl;<BR><BR>//news<BR>var $article;<BR>var $group;<BR>var $grouppart;<BR>var $newsurl;<BR><BR>//nntp<BR>var $nntpurl;<BR><BR>//telnet<BR>var $telneturl;<BR><BR>//wais<BR>var $wpath;<BR>var $wtype;<BR>var $database;<BR>var $waisdoc;<BR>var $waisindex;<BR>var $waisdatabase;<BR>var $waisurl;<BR><BR>function check($url){<BR>$pos = @strpos($url,':',1);<BR>if($pos&lt;1) return false;<BR>$prot = substr($url,0,$pos);<BR>if(!isset($this-&gt;regex[$prot])) return false;<BR>eval('$regex = '.$this-&gt;regex[$prot].';');<BR>return ereg('^'.$regex.'$',$url);<BR>}<BR><BR>function urlcheck(){<BR>$this-&gt;lowalpha = '';<BR>$this-&gt;hialpha = '';<BR>$this-&gt;alpha = '('.$this-&gt;lowalpha.'|'.$this-&gt;hialpha.')';<BR>$this-&gt;digit = '';<BR>$this-&gt;safe = '[$.+_-]';<BR>$this-&gt;extra = '[*()\'!,]';<BR>$this-&gt;national = '([{}|\^~`]|\\[|\\])';<BR>$this-&gt;punctuation = '[&lt;&gt;#%"]';<BR>$this-&gt;reserved = '[?;/:@&amp;=]';<BR>$this-&gt;hex = '('.$this-&gt;digit.'|)';<BR>$this-&gt;escape = '(%'.$this-&gt;hex.'{2})';<BR>$this-&gt;unreserved = '('.$this-&gt;alpha.'|'.$this-&gt;digit.'|'.$this-&gt;safe.'|'.$this-&gt;extra.')';<BR>$this-&gt;uchar = '('.$this-&gt;unreserved.'|'.$this-&gt;escape.')';<BR>$this-&gt;xchar = '('.$this-&gt;unreserved.'|'.$this-&gt;reserved.'|'.$this-&gt;escape.')';<BR>$this-&gt;digits = '('.$this-&gt;digit.'+)';<BR><BR>$this-&gt;urlpath = '('.$this-&gt;xchar.'*)';<BR>$this-&gt;password = '(('.$this-&gt;uchar.'|[?;&amp;=]'.')*)';<BR>$this-&gt;user = '(('.$this-&gt;uchar.'|[?;&amp;=]'.')*)';<BR>$this-&gt;port = $this-&gt;digits;<BR>$this-&gt;hostnumber = '('.$this-&gt;digits.'.'.$this-&gt;digits.'.'.$this-&gt;digits.'.'.$this-&gt;digits.')';<BR>$this-&gt;alphadigit = '('.$this-&gt;alpha.'|'.$this-&gt;digit.')';<BR>$this-&gt;toplabel = '('.$this-&gt;alpha.'|('.$this-&gt;alpha.'('.$this-&gt;alphadigit.'|-)*'.$this-&gt;alphadigit.'))';<BR>$this-&gt;domainlabel = '('.$this-&gt;alphadigit.'|('.$this-&gt;alphadigit.'('.$this-&gt;alphadigit.'|-)*'.$this-&gt;alphadigit.'))';<BR>$this-&gt;hostname = '(('.$this-&gt;domainlabel.'\\.)*'.$this-&gt;toplabel.')';<BR>$this-&gt;host = '('.$this-&gt;hostname.'|'.$this-&gt;hostnumber.')';<BR>$this-&gt;hostport = '('.$this-&gt;host.'(:'.$this-&gt;port.')?)';<BR>$this-&gt;login = '(('.$this-&gt;user.'(:'.$this-&gt;password.')?@)?'.$this-&gt;hostport.')';<BR><BR>$this-&gt;ftptype = '';<BR>$this-&gt;fsegment = '(('.$this-&gt;uchar.'|[?:@&amp;=])*)';<BR>$this-&gt;fpath = '('.$this-&gt;fsegment.'(/'.$this-&gt;fsegment.')*)';<BR>$this-&gt;ftpurl = '(://'.$this-&gt;login.'(/'.$this-&gt;fpath.'(;='.$this-&gt;ftptype.')?)?)';<BR><BR>$this-&gt;fileurl = '(://('.$this-&gt;host.'|)?/'.$this-&gt;fpath.')';<BR><BR>$this-&gt;search = '(('.$this-&gt;uchar.'|[;:@&amp;=])*)';<BR>$this-&gt;hsegment = '(('.$this-&gt;uchar.'|[;:@&amp;=])*)';<BR>$this-&gt;hpath = '('.$this-&gt;hsegment.'(/'.$this-&gt;hsegment.')*)';<BR>$this-&gt;httpurl = '(?://'.$this-&gt;hostport.'(/'.$this-&gt;hpath.'([?]'.$this-&gt;search.')?)?)';<BR><BR>$this-&gt;gopher_string = '('.$this-&gt;xchar.'*)';<BR>$this-&gt;selector = '('.$this-&gt;xchar.'*)';<BR>$this-&gt;gtype = $this-&gt;xchar;<BR>$this-&gt;gopherurl = '(://'.$this-&gt;hostport.'(/('.$this-&gt;gtype.'('.$this-&gt;selector.'(%09'.$this-&gt;search.'(%09'.$this-&gt;gopher_string.')?)?)?)?)?)';<BR><BR>$this-&gt;article = '(('.$this-&gt;uchar.'|[;/?:&amp;=])+@'.$this-&gt;host.')';<BR>$this-&gt;group = '('.$this-&gt;alpha.'('.$this-&gt;alpha.'|'.$this-&gt;digit.'|[-.+_])*)';<BR>$this-&gt;grouppart = '([*]|'.$this-&gt;group.'|'.$this-&gt;article.')';<BR>$this-&gt;newsurl = '(:'.$this-&gt;grouppart.')';<BR><BR>$this-&gt;nntpurl = '(://'.$this-&gt;hostport.'/'.$this-&gt;group.'(/'.$this-&gt;digits.')?)';<BR><BR>$this-&gt;telneturl = '(://'.$this-&gt;login.'/?)';<BR><BR>$this-&gt;wpath = '('.$this-&gt;uchar.'*)';<BR>$this-&gt;wtype = '('.$this-&gt;uchar.'*)';<BR>$this-&gt;database = '('.$this-&gt;uchar.'*)';<BR>$this-&gt;waisdoc = '(://'.$this-&gt;hostport.'/'.$this-&gt;database.'/'.$this-&gt;wtype.'/'.$this-&gt;wpath.')';<BR>$this-&gt;waisindex = '(://'.$this-&gt;hostport.'/'.$this-&gt;database.'[?]'.$this-&gt;search.')';<BR>$this-&gt;waisdatabase = '(://'.$this-&gt;hostport.'/'.$this-&gt;database.')';<BR>$this-&gt;waisurl = '('.$this-&gt;waisdatabase.'|'.$this-&gt;waisindex.'|'.$this-&gt;waisdoc.')';<BR>}<BR>}<BR><BR>?&gt;<BR><BR><BR>文件otherfunc.php的内容<BR>&lt;?php<BR>//otherfunc.php<BR>function htmlencode($str){<BR>$str = (string)$str;<BR><BR>$ret = '';<BR>$len = strlen($str);<BR>$nl = false;<BR>for($i=0;$i&lt;$len;$i++){<BR>$chr = $str[$i];<BR>switch($chr){<BR>case '&lt;':<BR>$ret .= '&lt;';<BR>$nl = false;<BR>break;<BR>case '&gt;':<BR>$ret .= '&gt;';<BR>$nl = false;<BR>break;<BR>case '"':<BR>$ret .= '"';<BR>$nl = false;<BR>break;<BR>case '&amp;':<BR>$ret .= '&amp;';<BR>$nl = false;<BR>break;<BR>/*<BR>case ' ':<BR>$ret .= ' ';<BR>$nl = false;<BR>break;<BR>*/<BR>case chr_(9):<BR>$ret .= ' ';<BR>$nl = false;<BR>break;<BR>case chr_(10):<BR>if($nl) $nl = false;<BR>else{<BR>$ret .= '&lt;br&gt;';<BR>$nl = true;<BR>}<BR>break;<BR>case chr_(13):<BR>if($nl) $nl = false;<BR>else{<BR>$ret .= '&lt;br&gt;';<BR>$nl = true;<BR>}<BR>break;<BR>default:<BR>$ret .= $chr;<BR>$nl = false;<BR>break;<BR>}<BR>}<BR><BR>return $ret;<BR>}<BR><BR><BR>function htmlencode4textarea($str){<BR>$str = (string)$str;<BR><BR>$ret = '';<BR>$len = strlen($str);<BR>for($i=0;$i&lt;$len;$i++){<BR>$chr = $str[$i];<BR>switch($chr){<BR>case '&lt;':<BR>$ret .= '&lt;';<BR>break;<BR>case '&gt;':<BR>$ret .= '&gt;';<BR>break;<BR>case '"':<BR>$ret .= '"';<BR>break;<BR>case '&amp;':<BR>$ret .= '&amp;';<BR>break;<BR>case ' ':<BR>$ret .= ' ';<BR>break;<BR>case chr_(9):<BR>$ret .= ' ';<BR>break;<BR>default:<BR>$ret .= $chr;<BR>break;<BR>}<BR>}<BR><BR>return $ret;<BR>}<BR><BR>function emailcheck($email){<BR>$ret=false;<BR>if(strstr($email, '@') &amp;&amp; strstr($email, '.')){<BR>if(eregi("^(+([\\._a-z0-9-]+)*)@({2,}(\\.{2,})*\\.{2,3})$", $email)){<BR>$ret=true;<BR>}<BR>}<BR>return $ret;<BR>}<BR><BR>function str2url($path){<BR>return eregi_replace("%2f","/",urlencode($path));<BR>}<BR>?&gt;                   <br><br>
页: [1]
查看完整版本: 一个用PHP实现的UBB类