我正在编写一个项目,其中包含模板引擎和一些新定义的标签,如LOOP
或IF
等......
假设这是PHP应处理并转换为PHP脚本的模板块:
<LOOP products>
{{name}}
{{id}}
<LOOP comments>
{{name}}
</LOOP>
{{quantity}}
</LOOP>
我想转换所有{{variables}}
根据循环变量的属性将它们打印出来,但我想为每个循环排除内部LOOP
标记。 < / p>
因为第一个LOOP
{{name}}
标记应为$product->name
,第二个LOOP
的名称应为$comment->name
< / p>
此正则表达式会将所有{{variables}}
转换为LOOP
的第一个product
变量。
$pattern = '/\s*\{\{(\w+)+\}\}\s*/';
以上输出
<LOOP products>
{{name}} // $product->name
{{id}} // $product->id
<LOOP comments>
{{name}} // $product->name ! <-- this {{variable}} should
// be exculde of first loop converting.
</LOOP>
{{quantity}} // $product->quantity
</LOOP>
我也试过这个:
(?!<LOOP[^>]*?>)\{\{(\w+)+\}\}(?![^<]*?</LOOP>)
// this works for 2 level of nested LOOPs.
// when I add another LOOP as third level ...
// ... contents of level2 are changing too, which is not corrent.
// ONLY first level should change.
答案 0 :(得分:2)
首先应该从文本中创建数据树。之后,您可以应用变量替换。
搜索循环标记并拆分文档,以便获得如下数据结构:
浏览所有LOOP数据条目并用正则表达式替换所有TEXT字符串
通过遍历数据结构重建文本文档
在增强模板系统时,这将为您提供极大的灵活性。它也更容易维护。
答案 1 :(得分:1)
Dreamlab是正确的:don't try to parse XML/HTML with regex。使用XML / HTML解析器处理数据,并以这种方式排除内部循环。这是一个特别复杂的问题,使用正则表达式来解决这个问题,当您使用适当的工具进行工作时,这会非常容易。在您的情况下,将XML抛出到SimpleXML并遍历树或使用一些XPath。
当正则表达式是你的锤子时,所有东西有时看起来像钉子,但它在很多情况下都是一个非常糟糕的工具 - 对你的问题来说是一个特别糟糕的工具。正则表达式并不是为解决这类问题而建立的,如果你试图这样做,你就会发现痛苦。
旁注:似乎你可能也在试图发明一种新的模板语言。如果是这样,你可能不需要。捆绑Mustache或Smarty或Twig或其他众多已经存在且经过充分测试和运行的模板引擎。
听起来你可能正在编写某种框架,所以这可能不适用,但根据你的用例,你可以只使用PHP,因为PHP 是一种模板语言:< / p>
<?php for($products as $p): ?>
<?=$p['name']?>
<?=$p['id']?>
<?php for($p['comments'] as $c): ?>
<?=$c['name']?>
<?php endforeach ?>
<?=$p['quantity']?>
<?php endforeach ?>