s选项确定的
如space_doing.htm里有一个被替换成了
*/
//开始处理
//变量
$var_regexp = "((\$[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*)([[a-zA-Z0-9_-."\[]$x7f-xff]+])*)";
/*
上面用红色显示的是转义符,没用红色显示的\就还是反斜杠
但是一开始为什么要用三个,我搞不明白。试验了一下,\$匹配的就是$,而改成$却没能匹配模板文件里的变量名。这个我还没搞明白。
$var_regexp匹配变量名
[a-zA-Z_x7f-xff] 变量名以字母或下划线或汉字开头
x7f-xff这个让人非常困惑,到底是想匹配什么呢?难道是想匹配扩展ASCII码吗?0x7f-0xff确实是扩展ASCII码表的范围,但显然没人会用这些控制字符去当变量名。
我这个UCH是UTF-8版本的,从UCS-2(就是现在通用的Unicode)到UTF-8的编码方式如下:
UCS-2编码(16进制)
UTF-8 字节流(二进制)
0000 - 007F
0xxxxxxx
0080 - 07FF
110xxxxx 10xxxxxx
0800 - FFFF
1110xxxx 10xxxxxx 10xxxxxx
前面的0000-007F是兼容ASCII码的
汉字的unicode编码在0080-FFFF里,转换成UTF-8后的字节是
110xxxxx或10xxxxxx或1110xxxx,在0x01111111-0x11111111范围内,也即0x7f-0xff。
更精确地,这个匹配变量名开头的部分可以写成[a-zA-Z_xc0-xef],因为汉字的开始字节只可能是110xxxxx或1110xxxx,范围就是0xc0-0xdf和0xe0-0xef
[a-zA-Z0-9_x7f-xff]* 比变量名的开头字节的允许取值范围多了数字,和C语言是一样的,变量名不能以数字开头
更精确地,这里可以写成[a-zA-Z0-9_x80-xef]* 因为这里汉字的字节可能是110xxxxx或1110xxxx或10xxxxxx,比0xc0-0xef多了10xxxxxx,即0x80-0xbf,合起来就是0x80-0xef
([[a-zA-Z0-9_-."\[]$x7f-xff]+])*
变量可能是数组形式的,如$name1[$name2],$[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*匹配了$name1,后面的[$name2]怎么匹配呢?我一开始以为是[$[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]],因为[]里面也应该是一个变量名。
但是变量可能是嵌套数组形式的,如$name1[$name2[$name3[$name4]]],此时用$[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]来一个个匹配变量名明显不可行。所以只是用[]把可能的字符都框起来,希望程序员不要写太扯淡的变量名了。
*/
$template = preg_replace("//s", "{\1}", $template);
/*
形如的字符串被替换成{name}
前面 解析广告,时间处理等产生的等都不匹配,仍然保留
name就是(.+ ) 这里的.匹配包括换行符在内的所有字符(有/s选项) 表示懒惰匹配
*/
$template = preg_replace("/([ ]+) +/s", "\1", $template);
/*
去掉换行回车后的制表符
beyondcompare中的对比效果如下
*/
$template = preg_replace("/(\$[a-zA-Z0-9_[]\"$x7f-xff]+).([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*)/s", "\1[\2]", $template);
/*
形如$name1.name2替换成$name1[name2],不要搞成了$name1[name2],\2和"\1"都是正则表达式的后向引用。可是我在模板文件中还没找到例子
*/
$template = preg_replace("/{(\$[a-zA-Z0-9_[]\"$.x7f-xff]+)}/s", "< =\1 >", $template);
/*
形如{$name1}替换成< =$name1 >
如space_doing.htm里有{$_SN[$space[uid]]}被换成了
< =$_SN[$space[uid]] >
*/
$template = preg_replace("/$var_regexp/es", "addquote(< =\1 >)", $template);
/*
将没有被{}包裹的变量名替换成addquote(< =\1 >)
addquote的作用是将类似[name]转换成[‘name’]
如space_doing.htm里有{if $space}被替换成了{if < =$space >}
但是这样也有副作用,比如space_doing.htm里有{$_SN[$space[uid]]},在上一条语句中被替换成了< =$_SN[$space[uid]] >,在这又被替换成了< =< =$_SN[$space[uid]] > >
*/
$template = preg_replace("/< =< =$var_regexp > >/es", "addquote(< =\1 >)", $template);
/*
消除上一条语句的副作用,将< =< =$_SN[$space[uid]] > >换成< =$_SN[$space[uid]] >
*/
//逻辑
$template = preg_replace("/{elseifs+(.+ )}/ies", "stripvtags(< php } elseif(\1) { >,)", $template);
/*
{elseif expression1} 替换成stripvtags(< php } elseif(expression1) { >,)
stripvtags的作用是将类似< =$name >替换成$name
*/
$template = preg_replace("/{else}/is", "< php } else { >", $template);
/*
{else} 替换成< php } else { >
*/
//循环
for($i = 0; $i < 5; $i++) {
$template = preg_replace("/{loops+(S+)s+(S+)}(.+ ){/loop}/ies", "stripvtags(< php if(is_array(\1)) { foreach(\1 as \2) { >,\3< php } } >)", $template);
/*
解析loop
将类似{loop array1 key1} expression1 {/loop}替换成
stripvtags(
<’ php if(is_array(array1)) {foreach (array1 as key1){ >’,
‘expression1< php } } >’
)
如space_doing.htm里将
{if < =$_TPL[titles] >}{loop < =$_TPL[titles] > < =$value >}{if < =$value >}< =$value > - {/if}{/loop}{/if}{if < =$space >}< =$_SN[$space[uid]] > - {/if}< =$_SCONFIG[sitename] >
替换成了
{if < =$_TPL[titles] >}< php if(is_array($_TPL[titles])) { foreach($_TPL[titles] as $value) { >{if < =$value >}< =$value > - {/if}< php } } >{/if}{if < =$space >}< =$_SN[$space[uid]] > - {/if}< =$_SCONFIG[sitename] >
*/
$template = preg_replace("/{loops+(S+)s+(S+)s+(S+)}(.+ ){/loop}/ies", "stripvtags(< php if(is_array(\1)) { foreach(\1 as \2 => \3) { >,\4< php } } >)", $template);
/*
解析loop
将类似{loop array1 key1 value1} expression1 {/loop}替换成
stripvtags(
<’ php if(is_array(array1)) {foreach (array1 as key1=>value1){ >’,
‘expression1< php } } >’
)
如space_doing.htm里将
{loop < =$moodlist > < =$key > < =$value >}
< =$_SN[$value[uid]] >
{/loop}
替换成了
< php if(is_array($moodlist)) { foreach($moodlist as $key => $value) { >
< =$_SN[$value[uid]] >
< php } } >
*/
$template = pr