PHP(以及其他)将首先执行最深层的功能,然后解决问题。例如,
$text = strtoupper(str_replace('_', ' ', file_get_contents('file.txt')));
我正在为模板解析器执行与上述示例非常相似的操作。它会查找标签
{@tag_name}
并将其替换为名称 $ tag_name 的变量。还有一个例子:
$a = 'hello';
$b = ' world';
INPUT = 'This is my test {@a{@b}} string.';
OUTPUT (step 1) = 'This is my test {@a} world string.';
OUTPUT output = 'This is my test hello world string.';
我该怎么做呢?这有意义吗?如果没有,我可以尝试更好地解释。
答案 0 :(得分:4)
我不确定我是否理解了您的示例中的嵌套,因为该示例未展示嵌套背后的目的。您的示例输入可以很容易
'This is my test {@a} {@b} string.'
在str_replace中使用数组可以非常简单快速地处理这个问题。
$aVars = array('{@a}' => 'hello', '{@b}' => 'world');
$sString = 'This is my test {@a} {@b} string.';
echo str_replace(array_keys($aVars), array_values($aVars), $sString);
这给了我们
这是我的测试问候世界字符串。
现在,这个递归函数并不太难,但我不确定我是否理解它会有多大用处。这是一个有效的例子:
function template($sText, $aVars) {
if (preg_match_all('/({@([^{}]+)})/',
$sText, $aMatches, PREG_SET_ORDER)) {
foreach($aMatches as $aMatch) {
echo '<pre>' . print_r($aMatches, 1) . '</pre>';
if (array_key_exists($aMatch[2], $aVars)) {
// replace the guy inside
$sText = str_replace($aMatch[1], $aVars[$aMatch[2]], $sText);
// now run through the text again since we have new variables
$sText = template($sText, $aVars);
}
}
}
return $sText;
}
print_r会显示匹配的内容,因此您可以按照其步调跟踪功能。现在让我们尝试一下......
$aVars = array('a' => 'hello', 'b' => 'world');
$sStringOne = 'This is my test {@a} {@b} string.';
$sStringTwo = 'This is my test {@a{@b}} string.';
echo template($sStringOne, $aVars) . '<br />';
第一个结果:
这是我的测试问候世界字符串。
现在让我们尝试String Two
echo template($sStringTwo, $aVars) . '<br />';
第二个结果:
这是我的测试{@aworld}字符串。
这可能就是您正在寻找的东西。显然你需要一个aworld
变量才能以递归方式工作......
$aVars = array('a' => '', 'b' => '2', 'a2' => 'hello world');
echo template($sStringTwo, $aVars) . '<br />';
我们的结果。
这是我的测试问候世界字符串。
只是为了一些有关递归的乐趣......
$aVars = array('a3' => 'hello world', 'b2' => '3', 'c1' => '2', 'd' => '1');
$sStringTre = 'This is my test {@a{@b{@c{@d}}}} string.';
echo template($sStringTre, $aVars) . '<br />';
这是我的测试问候世界字符串。
不确定这是否是您要求的......
答案 1 :(得分:1)
这不是一项微不足道的任务。您需要手动解析字符串并执行自己的逻辑替换。没有神奇的功能或功能可以为你做到这一点。
我自己的模板引擎就此做了(以及更多),只有核心(没有模板宏)的重量为600+ LOC
答案 2 :(得分:1)
使用堆栈 - 将每个已打开元素放在最顶层array_push
上,并在第一个结束标记处评估最顶层array_pop
。
答案 3 :(得分:0)
至少在给定的例子中,我不明白为什么@b令牌会嵌套在@a令牌中。这两个人似乎没有任何需要。您是否尝试在Perl中执行此类操作?
$a = "b";
$b = "Hello World!";
print $$a;
输出将是“Hello World”