利用正则表达式的一些技巧完成UBB代码的转换

利用正则表达式的一些技巧完成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]
UBB是什么啊.
UBB是什么啊
UBB 标签.
UBB 标签
Very Good 的模块。--我.
Very Good 的模块。
我原来的模块只有两个部分 mini_ubb() 和 ubb()。不够灵活:)
还有一些东西没写完,其实.
还有一些东西没写完,其实真的拿到实际应用过程中来用的话还需要增加两个设置%inner,%config的函数,但暂时还用不到所以没写。

另外%config当中的变量现在还只是用到了0/1实际上你还可以增加一些值来设置一些复杂的转换模式,比如图片可以采用正常显示,缩小显示,甚至只是显示一个连接等方式。
恩,明白:)
你帮我搞清楚了一个思路方向:)
受到 LB 的 code.cgi 思路严重影响,我的UBB.pm虽然模块化,但是没有想到可以这么灵活:)

PS:战鹰老兄啊。。。N久前你开发的那个 web服务器怎么样了啊?
个人的水平和时间有限,遇.
个人的水平和时间有限,遇到很多问题,没有继续搞下去了,一个人要完成这么大且不是很熟悉的东西还是比较困难的。

Perl最大的特点就是他的灵活性,即便是在别人认为非常死板的领域里面也可以很好的发挥他自身的灵活性。通过正则表达式一个一个标签的替换是比较简单且比较常用的方式,但这样的话每个标签程序都要从头到尾的进行替换,效率很低,而且实际上能用到的标签还只是很少的,多数的替换都是在浪费时间。

最近在研究PDK,这个模块我用pdk进行了几种方式的编译发现与解释运行方式并没有太大的差别,同样是对一段文字是进行1百万次转换,编译后的还要慢1s!

不过pdk可以将pm库直接编译成.net能够调用的库文件就简直太方便了,以后写.net的时候就不用再受C#罗罗嗦嗦的语句头痛了。
哦。时间啊。。同感。。。.
哦。时间啊。。同感。。。 现在都缺少这个:) 项目不错。。但是就是没时间和精力坚持:)
不错好
这真是好代码,可不知道怎么实用...
size标签的建议
size是否要有个max和min值比较合理些