利用正则表达式的一些技巧完成UBB代码的转换
zhanying
|
1#
zhanying 发表于 2005-06-08 01:25
利用正则表达式的一些技巧完成UBB代码的转换
利用正则表达式的一些技巧完成UBB代码的转换
本代码使用了正则表达式当中的e修饰符,从而实现了对正则表达式的复杂替换 [quote] package ubb_code; use strict; #定义处理各种ubb格式的函数Hash结构,哈希结构索引为ubb格式的名字 #函数的格式为String=function(ubb代码包含的文本,ubb代码的参数,ubb代码转换设置) my %function=( b=>\&ubb_b, i=>\&ubb_i, u=>\&ubb_u, align=>\&ubb_align, url=>\&ubb_url, email=>\&ubb_email, img=>\&ubb_img, flash=>\&ubb_flash, quote=>\&ubb_quote, fly=>\&ubb_fly, move=>\&ubb_move, glow=>\&ubb_glow, shadow=>\&ubb_shadow, color=>\&ubb_color, size=>\&ubb_size, face=>\&ubb_face, dir=>\&ubb_dir, rm=>\&ubb_rm, mp=>\&ubb_mp, qt=>\&ubb_qt, upload=>\&ubb_upload ); #定义缺省的ubb嵌套 my %inner=( b=>1, i=>1, u=>1, align=>1, url=>0, email=>0, img=>0, flash=>0, quote=>1, fly=>1, move=>1, glow=>1, shadow=>1, color=>1, size=>1, face=>1, dir=>0, rm=>0, mp=>0, qt=>0, upload=>0 ); #定义缺省的ubb转换参数,默认情况下转换所有的ubb代码, #如果需要跳过哪个ubb代码的转换,将对应的值设置为0即可。 my %conf=( b=>1, i=>1, u=>1, align=>1, url=>1, email=>1, img=>1, flash=>1, quote=>1, fly=>1, move=>1, glow=>1, shadow=>1, color=>1, size=>1, face=>1, dir=>1, rm=>1, mp=>1, qt=>1, upload=>1 ); my $ubb_code_1=')(=[\"\']?[\d\w\_\,\:\/\.\@\-\?\&\#]+[\"\']?)?\](.+?)\[\/\1\]'; my $ubb_code_2=')(=[\"\']?[\d\w\_\,\:\/\.\@\-\?\&\#]+[\"\']?)?\](.+)\[\/\1\]'; sub new { my $class = shift; my $self = bless {}, $class; $self->{Conf}=\%conf; $self->{Inner}=\%inner; $self->{UBB}=""; $self->{HTML}=""; my @s; my @m; foreach(keys %inner){ if($inner{$_}){ push(@m,$_); }else{ push(@s,$_); } } #分别生成需要嵌套处理和不需要嵌套处理的ubb正则表达式 $self->{inner_fmt}='\[('.join('|',@m).$ubb_code_2; $self->{single_fmt}='\[('.join('|',@s).$ubb_code_1; return $self; } sub Encoding{ my $self=shift; my $str=shift; my $param=shift; my $head=shift; my $tmp=$str; if(defined $head){#如果没ubb代码开头参数,说明是第一次调用,如果有ubb代码的开头则表示是函数的递归调用 $head=lc($head);#转为小写,否则代码无法正确识别hash if($self->{Inner}{$head}){ $str=~s/$self->{inner_fmt}/Encoding($self,$3,$2,$1)/egsi; $str=~s/$self->{single_fmt}/Encoding($self,$3,$2,$1)/egi; } }else{ $str=~s/$self->{inner_fmt}/Encoding($self,$3,$2,$1)/egsi; $str=~s/$self->{single_fmt}/Encoding($self,$3,$2,$1)/egi; } if(defined $head && $function{$head} && $self->{Conf}{$head}){ #根据ubb和hash调用相关的处理函数 $str=&{$function{$head}}($str,$param,$self->{Conf}{$head}); } return $str||"\[$head$param\]$tmp\[\/$head\]"; } sub ubb_b{ return "<b>$_[0]</b>"; } sub ubb_i{ return "<i>$_[0]</i>"; } sub ubb_u{ return "<u>$_[0]</u>"; } sub ubb_align{ my $str=shift; my $param=shift; if($param=~/=([\"\']?)(center|left|right)([\"\']?)/){ return "<div align=\"$2\">$str</div>"; }else{ return "<div>$str</div>"; } } sub ubb_url{ my $str=shift; my $param=shift||''; if($param=~/=([\"\']?)(.+)([\"\']?)/){ return "<a href=\"$2\">$str</a>"; }else{ return"<a href=\"$str\">$str</a>"; } } sub ubb_email{ my $str=shift; my $param=shift||''; if($param=~/=([\"\']?)(.+)([\"\']?)/){ return "<a href=\"mailto:$2\">$str</a>"; }else{ return "<a href=\"mailto:$str\">$str</a>"; } } sub ubb_img{ my $str=shift; my $param=shift||''; if($param=~/=([\"\']?)(\d+),(\d+)([\"\']?)/){ return "<img src=\"$str\" height=\"$2\" width=\"$3\"></img>"; }else{ return "<img src=\"$str\"></img>"; } } sub ubb_flash{ my $str=shift; my $param=shift||''; if($param=~/=([\"\']?)(\d+),(\d+)([\"\']?)/){ return "<embed src=\"$str\" quality=low pluginspage=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\" type=\"application/x-shockwave-flash\" width=\"$2\" height=\"$3\"></embed>"; }else{ return "<embed src=\"$str\" quality=low pluginspage=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\" type=\"application/x-shockwave-flash\"></embed>"; } } sub ubb_quote{ return "<div class=\"sytl_quote\">$_[0]</div>"; } sub ubb_fly{ return "<marquee behavior=\"alternate\">$_[0]</marquee>" } sub ubb_move{ return "<marquee>$_[0]</marquee>" } sub ubb_glow{ my $str=shift; my $param=shift; if($param=~/=([\"\']?)(\d+),([\d\w\#]+),(\d+)([\"\']?)/){ return "<div style=\"width:$2;filter:glow(color=$3, strength=$4)\">$str</div>"; }else{ return "<div style=\"filter:glow(color=red, strength=2)\">$str</div>"; } } sub ubb_shadow{ my $str=shift; my $param=shift; if($param=~/=([\"\']?)(\d+),([\d\w\#]+),(\d+)([\"\']?)/){ return "<div style=\"width:$2;filter:shadow(color=$3, strength=$4)\">$str</div>"; }else{ return "<div style=\"filter:shadow(color=red, strength=2)\">$str</div>"; } } sub ubb_color{ my $str=shift; my $param=shift; if($param=~/=([\"\']?)([\w\d\#]+)([\"\']?)/){ return "<font color=\"$2\">$str</font>"; }else{ return "<font>$str</font>"; } } sub ubb_size{ my $str=shift; my $param=shift; if($param=~/=([\"\']?)([\d]+)([\"\']?)/){ return "<font size=\"$2\">$str</font>"; }else{ return "<font>$str</font>"; } } sub ubb_face{ my $str=shift; my $param=shift; if($param=~/=([\"\']?)([^\>\<\/\\:\n\r]+)([\"\']?)/){ return "<font face=\"$2\">$str</font>"; }else{ return "<font>$str</font>"; } } sub ubb_dir{} sub ubb_rm{} sub ubb_mp{} sub ubb_qt{} sub ubb_upload{ my $str=shift; my $param=shift; $str=~s/[\n\r]+//; if($str=/.*\/(.*\.)(jpg|gif|png|bmp|wmf)$/){ return "<a href=\"$str\"><img src=\"$str\"></img></a>"; }elsif($str=/.*\/(.*\.)(zip|rar|txt|doc|xsl|pdf)$/){ return "<a href=\"$str\">Download:$1$2</a><br>" } } [/quote] |