一个用PHP实现的UBB类
<br> <?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( //小写的标签 => 对应的处理函数<BR>'url' => '$this->url',<BR>'email' => '$this->email',<BR>'img' => '$this->img',<BR>'b' => '$this->simple',<BR>'i' => '$this->simple',<BR>'u' => '$this->simple',<BR>'tt' => '$this->simple',<BR>'s' => '$this->simple',<BR>'strike' => '$this->simple',<BR>'h1' => '$this->simple',<BR>'h2' => '$this->simple',<BR>'h3' => '$this->simple',<BR>'h4' => '$this->simple',<BR>'h5' => '$this->simple',<BR>'h6' => '$this->simple',<BR>'sup' => '$this->simple',<BR>'sub' => '$this->simple',<BR>'em' => '$this->simple',<BR>'strong' => '$this->simple',<BR>'code' => '$this->simple',<BR>'samp' => '$this->simple',<BR>'kbd' => '$this->simple',<BR>'var' => '$this->simple',<BR>'dfn' => '$this->simple',<BR>'cite' => '$this->simple',<BR>'small' => '$this->simple',<BR>'big' => '$this->simple',<BR>'blink' => '$this->simple'<BR>);<BR>//url裢接属性<BR>var $attr_url;<BR>//url合法性检查对象<BR>var $urlcheck;<BR><BR>function ubbcode($attr_url){<BR>$this->attr_url = ''.$attr_url;<BR>$this->urlcheck = new urlcheck();<BR>}<BR><BR>//对$str进行UBB编码解析<BR>function parse($str){<BR>$this->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->call_time>1)){<BR>echo $this->call_time."<br>";<BR>return $parse;//如果不能是不能嵌套的标记,直接返回<BR>}<BR><BR>$parse2 = substr($parse,0,$pos);//标记之前<BR>$parse = substr($parse,$pos+$tag_len+2);//标记之后<BR>if(!isset($this->tags[$tag])){<BR>echo "$tag_start<br>";<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->parse($value);<BR>}<BR><BR>$ret .= $parse2;<BR>eval('$ret .= '.$this->tags[$tag].'("'.$tag_start.'","'.$tag_end.'","'.$value.'");');<BR>}<BR>$this->call_time--;<BR>return $ret;<BR>}<BR><BR>function simple($start,$end,$value){<BR>return '<'.$start.'>'.$value.'</'.$end.'>';<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->urlcheck->check($trim_value)) return '<a href="'.$trim_value.'" '.$this->attr_url.'>'.$value.'</a>';<BR>else return '['.$start.']'.$value.'[/'.$end.']';<BR>}<BR><BR>function email($start,$end,$value){<BR>if(emailcheck($value)) return '<a href="mailto:'.$value.'">'.$value.'</a>';<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->urlcheck->check($trim_value)))<BR>return '<img src="'.$trim_value.'"></img>';<BR>else return '['.$start.']'.$value.'[/'.$end.']';<BR>}<BR>}<BR><BR>//测试<BR>echo '<html>';<BR>echo '<head><title>测试</title></head>';<BR>echo '<body>';<BR>echo '<form action="'.str2url($PATH_INFO).'" method="post">';<BR>echo '<textarea cols="100" rows="10" name="ubb">'.htmlencode4textarea($ubb).'</textarea><br>';<BR>echo '<input type="submit" value="转换">';<BR>echo '</form>';<BR><BR>if(isset($ubb)){<BR>$ubbcode = new ubbcode('target="_blank"');<BR>echo '<hr>'.$ubbcode->parse($ubb);<BR>}<BR><BR>echo '</body>';<BR>echo '</html>';<BR><BR>?><BR><BR>文件urlcheck.php的内容<BR><?php<BR>//urlcheck.php<BR>class urlcheck{<BR>var $regex = array(//协议名(注意在这里必须写成小写) => 对应的正则表达式<BR>'ftp' => '$this->ftpurl',<BR>'file' => '$this->fileurl',<BR>'http' => '$this->httpurl',<BR>'https' => '$this->httpurl',<BR>'gopher' => '$this->gopherurl',<BR>'news' => '$this->newsurl',<BR>'nntp' => '$this->nntpurl',<BR>'telnet' => '$this->telneturl',<BR>'wais' => '$this->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<1) return false;<BR>$prot = substr($url,0,$pos);<BR>if(!isset($this->regex[$prot])) return false;<BR>eval('$regex = '.$this->regex[$prot].';');<BR>return ereg('^'.$regex.'$',$url);<BR>}<BR><BR>function urlcheck(){<BR>$this->lowalpha = '';<BR>$this->hialpha = '';<BR>$this->alpha = '('.$this->lowalpha.'|'.$this->hialpha.')';<BR>$this->digit = '';<BR>$this->safe = '[$.+_-]';<BR>$this->extra = '[*()\'!,]';<BR>$this->national = '([{}|\^~`]|\\[|\\])';<BR>$this->punctuation = '[<>#%"]';<BR>$this->reserved = '[?;/:@&=]';<BR>$this->hex = '('.$this->digit.'|)';<BR>$this->escape = '(%'.$this->hex.'{2})';<BR>$this->unreserved = '('.$this->alpha.'|'.$this->digit.'|'.$this->safe.'|'.$this->extra.')';<BR>$this->uchar = '('.$this->unreserved.'|'.$this->escape.')';<BR>$this->xchar = '('.$this->unreserved.'|'.$this->reserved.'|'.$this->escape.')';<BR>$this->digits = '('.$this->digit.'+)';<BR><BR>$this->urlpath = '('.$this->xchar.'*)';<BR>$this->password = '(('.$this->uchar.'|[?;&=]'.')*)';<BR>$this->user = '(('.$this->uchar.'|[?;&=]'.')*)';<BR>$this->port = $this->digits;<BR>$this->hostnumber = '('.$this->digits.'.'.$this->digits.'.'.$this->digits.'.'.$this->digits.')';<BR>$this->alphadigit = '('.$this->alpha.'|'.$this->digit.')';<BR>$this->toplabel = '('.$this->alpha.'|('.$this->alpha.'('.$this->alphadigit.'|-)*'.$this->alphadigit.'))';<BR>$this->domainlabel = '('.$this->alphadigit.'|('.$this->alphadigit.'('.$this->alphadigit.'|-)*'.$this->alphadigit.'))';<BR>$this->hostname = '(('.$this->domainlabel.'\\.)*'.$this->toplabel.')';<BR>$this->host = '('.$this->hostname.'|'.$this->hostnumber.')';<BR>$this->hostport = '('.$this->host.'(:'.$this->port.')?)';<BR>$this->login = '(('.$this->user.'(:'.$this->password.')?@)?'.$this->hostport.')';<BR><BR>$this->ftptype = '';<BR>$this->fsegment = '(('.$this->uchar.'|[?:@&=])*)';<BR>$this->fpath = '('.$this->fsegment.'(/'.$this->fsegment.')*)';<BR>$this->ftpurl = '(://'.$this->login.'(/'.$this->fpath.'(;='.$this->ftptype.')?)?)';<BR><BR>$this->fileurl = '(://('.$this->host.'|)?/'.$this->fpath.')';<BR><BR>$this->search = '(('.$this->uchar.'|[;:@&=])*)';<BR>$this->hsegment = '(('.$this->uchar.'|[;:@&=])*)';<BR>$this->hpath = '('.$this->hsegment.'(/'.$this->hsegment.')*)';<BR>$this->httpurl = '(?://'.$this->hostport.'(/'.$this->hpath.'([?]'.$this->search.')?)?)';<BR><BR>$this->gopher_string = '('.$this->xchar.'*)';<BR>$this->selector = '('.$this->xchar.'*)';<BR>$this->gtype = $this->xchar;<BR>$this->gopherurl = '(://'.$this->hostport.'(/('.$this->gtype.'('.$this->selector.'(%09'.$this->search.'(%09'.$this->gopher_string.')?)?)?)?)?)';<BR><BR>$this->article = '(('.$this->uchar.'|[;/?:&=])+@'.$this->host.')';<BR>$this->group = '('.$this->alpha.'('.$this->alpha.'|'.$this->digit.'|[-.+_])*)';<BR>$this->grouppart = '([*]|'.$this->group.'|'.$this->article.')';<BR>$this->newsurl = '(:'.$this->grouppart.')';<BR><BR>$this->nntpurl = '(://'.$this->hostport.'/'.$this->group.'(/'.$this->digits.')?)';<BR><BR>$this->telneturl = '(://'.$this->login.'/?)';<BR><BR>$this->wpath = '('.$this->uchar.'*)';<BR>$this->wtype = '('.$this->uchar.'*)';<BR>$this->database = '('.$this->uchar.'*)';<BR>$this->waisdoc = '(://'.$this->hostport.'/'.$this->database.'/'.$this->wtype.'/'.$this->wpath.')';<BR>$this->waisindex = '(://'.$this->hostport.'/'.$this->database.'[?]'.$this->search.')';<BR>$this->waisdatabase = '(://'.$this->hostport.'/'.$this->database.')';<BR>$this->waisurl = '('.$this->waisdatabase.'|'.$this->waisindex.'|'.$this->waisdoc.')';<BR>}<BR>}<BR><BR>?><BR><BR><BR>文件otherfunc.php的内容<BR><?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<$len;$i++){<BR>$chr = $str[$i];<BR>switch($chr){<BR>case '<':<BR>$ret .= '<';<BR>$nl = false;<BR>break;<BR>case '>':<BR>$ret .= '>';<BR>$nl = false;<BR>break;<BR>case '"':<BR>$ret .= '"';<BR>$nl = false;<BR>break;<BR>case '&':<BR>$ret .= '&';<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 .= '<br>';<BR>$nl = true;<BR>}<BR>break;<BR>case chr_(13):<BR>if($nl) $nl = false;<BR>else{<BR>$ret .= '<br>';<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<$len;$i++){<BR>$chr = $str[$i];<BR>switch($chr){<BR>case '<':<BR>$ret .= '<';<BR>break;<BR>case '>':<BR>$ret .= '>';<BR>break;<BR>case '"':<BR>$ret .= '"';<BR>break;<BR>case '&':<BR>$ret .= '&';<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, '@') && 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>?> <br><br>
页:
[1]