目前做的应用里有这个需求:根据学生信息取得照片存放路径。。。 这个路径是根据学生信息按照一定形式组合后确定的。
由于组合方式需要运行时配置,所以写了一个类解决替换问题。类似于 模板系统中的替换,不过没有整那么复杂。只是解决了,用信息字段替换,并进行了转换。
贴在这里,免得掉了。另外就是 ,由于时间关系,没有考虑优化。。
<?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