2010-05-17 68 views
0

是否有方法在正则表达式I.e中查找自定义标记?匹配在Regexp中查找打开和关闭标记

{a}sometext{/a} 

除了

{c=#fff}sometext{/c} 

所以它找到的内内容的整个块?问题是sometext可能有其他标签,如:

{a=http://www.google.com}{b}Hello, world{/b}{/a} 

唯一的解决方案,我可以想出将从匹配{一...到.../B}当我想{A ...到.../a}是否有单一的正则表达式解决方案,或者最好是匹配开始,然后使用另一种方法从备份中找到结尾,并以这种方式抓取它?我使用PHP 5.2,所以我有所有的选择。

回答

1

听起来像你正在尝试做MediaWiki已经用wiki标记语言做的事情。我会建议使用他们的解析器和他们的标记,或者如果您选择自己推出,您可能会从看到他们如何做到这一点中找到灵感。

Manual for Parser.php

Source for Parser.php

+0

这正是我试图找到的,谢谢!我试图推出自己的,学习体验以及因为我只想要某些功能。 – Rixius 2010-05-17 03:05:12

2

这工作:

$subject = 'bla bla{a=http://www.google.com}{b}Hello, world{/b}{/a} bla'; 
$regex = '~\\{a(?:=[^}]+)?\\}(.*?)\\{/a\\}~'; 
preg_match($regex, $subject, $matches); 
var_dump($matches); 

给出:

array(2) { 
    [0]=> 
    string(48) "{a=http://www.google.com}{b}Hello, world{/b}{/a}" 
    [1]=> 
    string(19) "{b}Hello, world{/b}" 
} 

BEGIN编辑 你可以做正则表达式的更为宽泛的反向引用

$regex = '~\\{([a-z]+)(?:=[^}]+)?\\}(.*?)\\{/\\1\\}~'; 

,但在这种情况下,我没有想法如何匹配任意深度的内部标签。 END编辑

但是,我强烈建议不要使用正则表达式来达到此目的。我建议你迭代字符串,一次一个数组,并使用辅助堆栈来跟踪你发现的标签(使用array_pusharray_popend来查看)。

+0

感谢工作正则表达式,但我不太明白你的建议。如果它会更有效率,那么我很乐意使用它。你知道有关它的任何文章吗? – Rixius 2010-05-17 02:55:11

+0

谷歌对于“解析器标签嵌套堆栈”或类似的东西,你会发现有关如何解析嵌套标签的文章。 – Artefacto 2010-05-17 03:11:33