我正在制作一个模板系统,我可以在其中输入:
<t:category:item:parameter1:parameter2...>
并将其替换为文件中的文本。可选参数被放置在替换字符串中,如%1
, %2
...
到目前为止,我有这个:
$data = preg_replace_callback("/<t:([^:]+):([^>]+)>/",function($m) use (&$userdata) {
static $fcache = Array();
$parse = function($file) use (&$fcache,&$lang) {
// parse the file if it's a new one. False indicates success, otherwise error message is returned
if( !isset($fcache[$file])) {
if( !file_exists("text/".$lang."/".$file.".html")) $lang = "en";
if( !file_exists("text/".$lang."/".$file.".html")) return "<div class=\"alert\">ERROR: File ".$file." not found.</div>";
$k = "";
foreach(file("text/".$lang."/".$file.".html") as $l) {
if( substr($l,0,1) == "|") $k = rtrim(substr($l,1));
else $fcache[$file][$k] .= $l;
}
}
return false;
};
$lang = $userdata && $userdata['language'] ? $userdata['language'] : "uk";
list(,$file,$d) = $m;
$params = explode(":",$d);
$section = array_shift($params);
if( $e = $parse($file)) return $e;
if( !$fcache[$file][$section]) {
$lang = "uk";
if( $e = $parse($file)) return $e;
}
return preg_replace_callback("/%(\d+)/",function($i) use ($params) {
return htmlspecialchars_decode($params[$i[1]-1]);
},trim($fcache[$file][$section]));
},$data);
文本文件的格式为:
|key
replacement text
|otherkey
more text %1
无论如何,切入正题:如果其中一个参数本身就是替换字符串怎么办?例如,如果我想要一个像“快来拜访他!”这样的字符串怎么办?- 我希望它是这样的:
<t:person:visit:<t:grammar:pronoun_object_m>>
该文件将具有:
|visit
Come and visit %1 soon!
|pronoun_object_m
him
但是,当前函数会将参数作为文字,并且在短语末尾<t:grammar:pronoun_object_m
会显示一个额外的内容:>
快来参观<t:grammar:pronoun_object_m!>
实际上会显示为:
前来参观
由于未解析的替换看起来像一个 HTML 标记......
我相当确定我需要一个递归正则表达式,但是我对它们的工作方式感到非常困惑。谁能解释我如何“递归”我的正则表达式以允许这样的嵌入参数?