|
<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>[tt][/tt] <BR> <BR><BR>[em][/em] <BR>[strong][/strong] <BR><BR><BR><BR>[samp][/samp] <BR>[kbd][/kbd] <BR>[var][/var] <BR>[dfn][/dfn] <BR>[cite][/cite] <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); //查找[xx] <BR>if(!$eregi_ret){ <BR>$ret .= $parse; <BR>break; //如果没有,返回 <BR>} <BR>$pos = @strpos($parse,$eregi_arr[0]); <BR>$tag_len=strlen($eregi_arr[0])-2;//标记长度 <BR>$tag_start=substr($eregi_arr[0],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[0]); <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 = '[a-z]'; <BR>$this->hialpha = '[A-Z]'; <BR>$this->alpha = '('.$this->lowalpha.'|'.$this->hialpha.')'; <BR>$this->digit = '[0-9]'; <BR>$this->safe = '[$.+_-]'; <BR>$this->extra = '[*()\'!,]'; <BR>$this->national = '([{}|\^~`]|\\[|\\])'; <BR>$this->punctuation = '[<>#%"]'; <BR>$this->reserved = '[?;/ &=]'; <BR>$this->hex = '('.$this->digit.'|[a-fA-F])'; <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 = '[aidAID]'; <BR>$this->fsegment = '(('.$this->uchar.'|[? &=])*)'; <BR>$this->fpath = '('.$this->fsegment.'(/'.$this->fsegment.')*)'; <BR>$this->ftpurl = '([fF][tT][pP]://'.$this->login.'(/'.$this->fpath.'(;[tT][yY][pP][eE]='.$this->ftptype.')?)?)'; <BR><BR>$this->fileurl = '([fF][iI][lL][eE]://('.$this->host.'|[lL][oO][cC][aA][lL][hH][oO][sS][tT])?/'.$this->fpath.')'; <BR><BR>$this->search = '(('.$this->uchar.'|[; &=])*)'; <BR>$this->hsegment = '(('.$this->uchar.'|[; &=])*)'; <BR>$this->hpath = '('.$this->hsegment.'(/'.$this->hsegment.')*)'; <BR>$this->httpurl = '([hH][tT][tT][pP][sS]?://'.$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 = '([gG][oO][pP][hH][eE][rR]://'.$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 = '([nN][eE][wW][sS]:'.$this->grouppart.')'; <BR><BR>$this->nntpurl = '([nN][nN][tT][pP]://'.$this->hostport.'/'.$this->group.'(/'.$this->digits.')?)'; <BR><BR>$this->telneturl = '([tT][eE][lL][nN][eE][tT]://'.$this->login.'/?)'; <BR><BR>$this->wpath = '('.$this->uchar.'*)'; <BR>$this->wtype = '('.$this->uchar.'*)'; <BR>$this->database = '('.$this->uchar.'*)'; <BR>$this->waisdoc = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.'/'.$this->wtype.'/'.$this->wpath.')'; <BR>$this->waisindex = '([wW][aA][iI][sS]://'.$this->hostport.'/'.$this->database.'[?]'.$this->search.')'; <BR>$this->waisdatabase = '([wW][aA][iI][sS]://'.$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]+([\\._a-z0-9-]+)*)@([a-z0-9]{2,}(\\.[a-z0-9-]{2,})*\\.[a-z]{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> |
|