解析文件中的嵌套标记

Parsing of nested tags in a file

提问人:David 提问时间:10/18/2008 更新时间:10/18/2008 访问量:1541

问:

我想知道 - 解析类似内容的最有效方法是什么:

{{HEADER}}

Hello my name is {{NAME}}

{{#CONTENT}}
    This is the content ...

    {{#PERSONS}}

        <p>My name is {{NAME}}.</p>

    {{/PERSONS}}

{{/CONTENT}}

{{FOOTER}}

当然,这最终在某种程度上是一个模板系统,所以我的计划是创建一个哈希图来“铺设”模板,就像这样

$hash = array(
    'HEADER' => 'This is a header',
    'NAME' => 'David',
    'CONTENT' => array('PERSONS' => array(array('NAME' => 'Heino'), array('NAME' => 'Sebastian')),
    'FOOTER' => 'This is the footer'
    );

值得注意的是,“部分”(以 # 开头的标签)可以重复不止一次,我认为这就是绊倒我的原因......

此外,任何部分都可以包含任意数量的其他部分和常规标签......

所以。。你是怎么做到的?

PHP 解析 递归 模板 嵌套

评论


答:

0赞 Kibbee 10/18/2008 #1

你最好使用现有的解析器,如XML或JSON,这样你就不必编写自己的解析器,这样其他人就可以轻松地为你的解析器编写文档,而不需要专门的工具。但是,如果您想编写自己的解析器,您可能需要考虑使用 LexYacc

0赞 Jesse Dearing 10/18/2008 #2

我会使用第三方解析器,因为我喜欢更聪明地工作,而不是更努力地工作,但如果你这样做是为了练习,或者你真的想构建自己的模板引擎(在PHP中,我假设是因为标签),我会从审查设计模式开始,特别是复合设计模式

复合模式在 Java 框架中被大量用于此类操作,包括 XML 解析。

1赞 Troy Howard 10/18/2008 #3

这个的预期输出是这样的吗:

这是一个标头

你好,我的名字是大卫

This is the content ...

My name is Heino.

My name is Sebastian.

这是页脚


您如何管理哈希映射中的嵌套数组与模板中可重复部分的关系?模板的实际行为应该是什么?如果为非 section 元素提供了数组,它将做什么?如果为一个 section 元素提供了一个值,它是否会被视为与只有一个元素的数组相同(我假设是这样)?

无论如何,关于模板的解析器(无论您最终对数据映射做什么)......我要做的是为每种类型的令牌创建一个类,包括一个用于非令牌内容的通用类。它们将继承自具有可重写的 Parse、Render 和 Map 方法的公共令牌基类。

绘制出状态图,并找出每个状态的进入点和退出点,然后将其编码到令牌之间的调用结构中。最后,您希望生成一个描述模板的可枚举标记集合。

以抽象形式获得它后,您可以迭代调用标记的集合,以将哈希映射中的数据分配给标记,然后调用 Render 将模板呈现为其最终形式。

希望能有所帮助。

评论

0赞 David 10/18/2008
如果标签没有“适合”,则应忽略并剥离该标签。否则我喜欢你的想法 - 尽管它可能比我最初想象的要复杂一些。
0赞 magabriel 10/18/2008 #4

我会在 .php 单独的文件中使用这样的东西:

<?php echo $HEADER ?>

Hello my name is <?php echo $NAME?>

<div id="CONTENT">
    This is the content ...

    <?php foreach ($PERSONS as $PERSON) : ?>

        <p>My name is <?php echo $PERSON['NAME']?>.</p>

    <?php endforeach ?>

</div>

<?php echo $FOOTER ?>

只需将上述文件包含在填充引用变量的文件中即可。

信不信由你,PHP已经提供了模板系统声称要实现的所有功能。没有必要在PHP之上再添加一层抽象(和复杂性)。

评论

0赞 David 10/18/2008
是的,这将是一件简单的事情,但在我所处的情况下,这还不够。模板中根本无法嵌入任何 PHP/逻辑。
0赞 10/18/2008
我假设您没有任何PHP逻辑的要求来自模板将由非程序员生成的事实。但我敢肯定,如果你能教他们写{{#PERSONS}},当需要每个人的迭代时,你也可以教他们写foreach等价物。
0赞 Scott Reynen 10/18/2008 #5

为此,我使用 PHP 的 DOM。我的模板语言只是带有 ID 和类属性的 HTML。但是,如果您想坚持您的计划,我会使用具有与您的语法匹配的模式的 preg_replace_callback 和一个回调函数,该函数在您的哈希中找到适当的替换,在容器元素上递归调用自己。

评论

0赞 David 10/18/2008
这正是我现在正在摆弄的。但想知道是否有其他方法可以解析这样的结构。
1赞 Bob Fanger 10/18/2008 #6

最有效的方法是将模板编译为 php 代码。并且只包括编译版本。

Smarty 模板引擎执行类似的操作。您还可以查看智能源并检查它们如何解析标签。