2008-10-30 91 views
1

PHP(除其他外)将首先执行最深的功能,解决问题。例如,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.'; 

我该如何去做这件事?这有意义吗?如果不是,我可以尝试更好地解释。

+1

为什么不一步1的输出是:“这是我的测试{@a世界}字符串”; – Kip 2008-10-30 20:25:48

回答

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 />'; 

第一个结果:

这是我的测试世界您好字符串。

现在让我们试着线二

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

这不是一项简单的任务。您需要手动解析字符串并执行您自己的逻辑替换。没有任何魔术功能可以为你做到这一点。

我自己的模板引擎做有关该(及以上),只有核心(无模板宏)在600多个LOC重达

0

至少在给定的例子,我不明白为什么@b令牌将嵌套在@a令牌中。两人似乎没有彼此需要。你想在Perl中做这样的事吗?然后

$a = "b"; 
$b = "Hello World!"; 

print $$a; 

输出将是“Hello World”的

1

使用堆栈 - 放在上面array_push每个打开的元素和第一关闭标记评估最顶层array_pop