目前做的应用里有这个需求:根据学生信息取得照片存放路径。。。 这个路径是根据学生信息按照一定形式组合后确定的。
由于组合方式需要运行时配置,所以写了一个类解决替换问题。类似于 模板系统中的替换,不过没有整那么复杂。只是解决了,用信息字段替换,并进行了转换。
贴在这里,免得掉了。另外就是 ,由于时间关系,没有考虑优化。。
<?php
Class MyStringParser{
//var $pattern="/\{([a-zA-Z0-9]+)(:(upper|lower|left\((\d+)\)|right\((\d+)\)|sub\((\d+),(\d+)\)))*\}/";
// var $pattern="/^\{([a-zA-Z0-9]+)(:[a-zA-Z0-9_\(\) ]+)*\}$/";
//匹配模式 {Field:Fun(x,x):Fun2(x):Fun3}
var $pattern="/\{([a-zA-Z0-9]+)(:[a-zA-Z0-9\(\),]+)*\}/";
Class MyStringParser{
//var $pattern="/\{([a-zA-Z0-9]+)(:(upper|lower|left\((\d+)\)|right\((\d+)\)|sub\((\d+),(\d+)\)))*\}/";
// var $pattern="/^\{([a-zA-Z0-9]+)(:[a-zA-Z0-9_\(\) ]+)*\}$/";
//匹配模式 {Field:Fun(x,x):Fun2(x):Fun3}
var $pattern="/\{([a-zA-Z0-9]+)(:[a-zA-Z0-9\(\),]+)*\}/";
// 这里可能还需要修改
//var $pattern="/\{([a-zA-Z0-9]+)(:[a-zA-Z][a-zA-Z0-9]*\([0-9,]*\))*\}/";
var $data=array();
var $callback=array();
function MyStringParser(){
//添加内置函数,可以被替换
$this->addCallBack("left",array($this,"left"));
$this->addCallBack("right",array($this,"right"));
$this->addCallBack("sub",array($this,"sub"));
$this->addCallBack("upper",array($this,"upper"));
$this->addCallBack("lower",array($this,"lower"));
}
function addCallBack($name,$obj){
$this->callback[strtolower($name)]=& $obj;
}
function Parse($subject,$data){
$this->data=$data;
return preg_replace_callback($this->pattern,array($this,"replace"),$subject);
}
function parsetags($val,$tags){
$tags=str_replace(array(")","}"),"",$tags);
$tags=explode("(",$tags);
$method=strtolower($tags[0]);
if(array_key_exists($method,$this->callback) && is_callable($this->callback[$method])){
//print_R($method);print_R($this->callback);
return call_user_func($this->callback[$method],$val,$tags);
}
else{
return $val.":".$method."(".$tags[1].")" ;
}
}
function replace($matchs)
{
// print_R($matchs);
$key=$matchs[1];
if(array_key_exists($key,$this->data))
{
$val=$this->data[$key];
if(count($matchs)>2)
{
$mats=explode(":",$matchs[0]);
for($i=1;$i<count($mats);$i++)
{
$val=$this->parsetags($val,$mats[$i]);
}
}
return $val;
}
return $matchs[0];
}
//自定义替换函数 XXX
function upper($val,$tag){
return strtoupper($val);
}
function lower($val,$tag){
return strtolower($val);
}
function left($val,$tag){
return substr($val,0,$tag[1]);
}
function right($val,$tag){
return substr($val,0-$tag[1],$tag[1]);
}
function sub($val,$tag){
$t=explode(",",$tag[1]);
return substr($val,$t[0]-1,$t[1]);
}
}
调用方式:
include_once("MyStringParser.class.php");
//需要替换的字符串
$subject="http://url/{xh:left(2)}/{xh:right(5):upper}/{xh:sub(5,1)}/{xh:myfun(2,2)}/{xh:sub(1,2)}/{xh:sub(1,10)}/{xh:upper}/{xh:lower}//.jpg";
//数据
$data=Array("xh"=>"0123456ABCefghiG");
$parse= new MyStringParser();
//添加自定义函数
function MyCallBack($val,$tag){
return "call( $val ,".print_R($tag).");";
}
function MyCallBack($val,$tag){
return "call( $val ,".print_R($tag).");";
}
class testclass{
function testmethod($val,$tag){
return "testclass.testmethod:call( $val ,".print_R($tag).");";
}
}
//自定义函数的三种添加方式
$parse->addCallBack("myfun","MyCallBack");
$parse->addCallBack("callfun",array("testclass","testmethod"));
$aclass= new testclass();
$parse->addCallBack("callfun2",array(&$aclass,"testmethod"));
//解析
echo $subject."</br>";
echo $data['xh']."</br>";
echo $parse->Parse($subject,$data)."<br>";
//需要替换的字符串
$subject="http://url/{xh:left(2)}/{xh:right(5):upper}/{xh:sub(5,1)}/{xh:myfun(2,2)}/{xh:sub(1,2)}/{xh:sub(1,10)}/{xh:upper}/{xh:lower}//.jpg";
//数据
$data=Array("xh"=>"0123456ABCefghiG");
$parse= new MyStringParser();
//添加自定义函数
function MyCallBack($val,$tag){
return "call( $val ,".print_R($tag).");";
}
function MyCallBack($val,$tag){
return "call( $val ,".print_R($tag).");";
}
class testclass{
function testmethod($val,$tag){
return "testclass.testmethod:call( $val ,".print_R($tag).");";
}
}
//自定义函数的三种添加方式
$parse->addCallBack("myfun","MyCallBack");
$parse->addCallBack("callfun",array("testclass","testmethod"));
$aclass= new testclass();
$parse->addCallBack("callfun2",array(&$aclass,"testmethod"));
//解析
echo $subject."</br>";
echo $data['xh']."</br>";
echo $parse->Parse($subject,$data)."<br>";
输出:
http://url/{xh:left(2)}/{xh:right(5):upper}/{xh:sub(5,1)}/{xh:myfun(2,2)}/{xh:callfun(2,2)}/{xh:callfun2(2,2)/{xh:sub(1,2)}/{xh:undefinetest(1,10)}/{xh:upper()}/{xh:lower()}//.jpg
0123456ABCefghiG
http://url/01/FGHIG/4/MyCallBack:call( 0123456ABCefghiG ,myfun-2,2);/testclass.testmethod:call( 0123456ABCefghiG ,callfun-2,2);/{xh:callfun2(2,2)/01/0123456ABCefghiG:undefinetest(1,10)/0123456ABCEFGHIG/0123456abcefghig//.jpg
0123456ABCefghiG
http://url/01/FGHIG/4/MyCallBack:call( 0123456ABCefghiG ,myfun-2,2);/testclass.testmethod:call( 0123456ABCefghiG ,callfun-2,2);/{xh:callfun2(2,2)/01/0123456ABCefghiG:undefinetest(1,10)/0123456ABCEFGHIG/0123456abcefghig//.jpg