PHP如何进行递归函数调用?

时间:2008-10-30 20:15:25

标签: php string recursion

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

我该怎么做呢?这有意义吗?如果没有,我可以尝试更好地解释。

4 个答案:

答案 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”