解析BBCode的最佳方法

9
我希望为一个php网站制作bbcode过滤器(我正在使用cakephp,它将是一个bbcode助手)。我有一些要求。 Bbcodes可以嵌套。所以像这样的东西是有效的。
[block]  
    [block]  
    [/block]  
    [block]  
        [block]  
        [/block]  
    [/block]  
[/block]  
BBCode 可以有 0 个或多个参数。
例如:
[video: url="url", width="500", height="500"]Title[/video]

BBCodes可能具有多种行为。

例如,[url]text[/url]将被转换为[url:url="text"]text[/url],或者视频bbcode将能够在youtube、dailymotion等之间选择...

我认为这已经满足了我的大部分需求。我已经用正则表达式做了一些工作。但是我的最大问题是匹配参数。事实上,我已经使嵌套的bbcode和没有参数的bbcode正常工作了。但当我添加一个正则表达式来匹配参数时,它不能正确地匹配嵌套的bbcode。

"\[($tag)(=.*)\"\](.*)\[\/\1\]"// 不是.*而是非贪婪匹配器

我现在没有完整的正则表达式,但我有一些看起来像那样的东西(上面的代码)。

那么有没有一种有效地使用正则表达式或其他方法来匹配bbcode的方法呢?我唯一能想到的就是使用访问者模式,并且根据每个可能的标签拆分我的文本,这样,我可以对我的文本解析有更多的控制,并且我可能会验证我的文档,以便如果输入文本没有有效的bbcode,我可以在保存任何内容之前向用户发出错误提示。

我将使用sablecc创建我的文本解析器。 http://sablecc.org/

有更好的想法吗?或者任何可以导致有效灵活的bbcode解析器的东西?

谢谢,对我的糟糕英语感到抱歉...

5个回答

8

有几个已存在的库可以用于解析BBCode,使用这些库来代替自己尝试编写可能更容易:

下面是其中一些库,如果你继续搜索,肯定会找到更多:
PECL bbcode
PEAR HTML_BBCodeParser


1
http://jbbcode.com/ 是最好的选择。它了解标签堆叠并且不使用正则表达式。更不用说添加自定义标签有多容易了。 - petrica.martinescu

8
我最近一直在研究bbcode解析器。大部分使用正则表达式和PHP4,会在PHP 5.2+上产生错误或根本无法工作。PECL bbcode和PEAR HTML_BBCodeParser似乎不再维护(截至2012年末),也不容易安装到我要使用的共享托管设置中。StringParser_BBCode需要一些小修改才能在5.2+上工作,但添加新标签的方法很笨拙,而且它的最后更新时间是2008年。
在Bing搜索的第四页上(我有些绝望了)我找到了jBBCode,它似乎很新,并且需要PHP 5.3。MIT许可证。我还没有尝试过构建自定义标签,但到目前为止,它是我尝试过的唯一一个可以在使用PHP 5.3的共享托管帐户上开箱即用的解析器。

这篇文章相当古老,说实话我很惊讶它仍然相关。如果我必须再次实现它,我不会使用正则表达式。BBCode 可以与 HTML 相似,因为它是一种使用方括号而不是 <> 的标记语言。我可能会适应一个 XML 解析器来检查 []。这样,您就可以在 bbcode 中获得所有 XML 的好处,而几乎没有任何问题。在解析 bbcode 时,您可以做几乎任何事情。 - Loïc Faure-Lacroix

5

有一个PECLPEAR BBCode解析库可供使用。软件本来就不易开发,不要重复造轮子。

如果以上两个选项都不能使用,我建议将BBCode转化为有效的XML字符串,然后使用您喜欢的XML解析工具进行处理。以下是一个非常简单的想法:

  1. 通过htmlspecialchars运行代码,以转义任何需要转义的字符实体

  2. 将所有[和]字符分别转换为<和>

  3. 不要忘记在类似[tagname:的情况下考虑冒号

如果BBCode嵌套正确,则可以将此字符串传递到XML解析对象(SimpleXML、DOMDocument等)中进行处理。


13
这个主意很可怕,[script]...[/script] 会做什么? - user47322
4
如果你计划输出 HTML,那么这很糟糕。我写的内容是假设你正在解析 BBCode 来提取信息。如果你使用非官方的 BBCode 解析器(第一段中提到),那么你就会暴露于 XSS 攻击之中。 - Alana Storm
1
@AlanStorm 我不会这么说。将bbcode解析为类似xml的标记实际上是一个好主意,而且不太容易受到xss攻击,除非你实际上没有解析内容,只是将标记替换为html标记。这并不是重点。您不需要使用xml解析器将'['替换为'<'。但是通过xml解析器扩展bbcode非常有意义。它允许您定义在找到对象时要执行的严格规则,然后您可以将其输出回html,并且任何不安全的内容都可以轻松过滤在您的“伪DOM”对象中。 - Loïc Faure-Lacroix

3

回复:“还有更好的想法吗?”(我假设这是一个邀请,不仅仅是针对bbcode特定建议的改进)

我们最近考虑采用bbcode方法,但最终决定使用htmlpurifier。这个决定部分基于htmlpurifier小组在此处列出的(可能有偏见的)各种方法之间的比较,以及关于bbcode的讨论(同样来自htmlpurifer小组)在此处

顺便说一下,我认为你的英语非常好。我相信它比我的母语好多了。


啊,谢谢,我可能会包含HTML净化器。但是因为我不是很喜欢像FCK编辑器这样的东西。我想它主要用于净化HTML输出。但它看起来非常好。 - Loïc Faure-Lacroix

2
使用 preg_split() 函数和 PREG_DELIM_CAPTURE 标志将源代码分成标签和非标签。然后在迭代标签时,保持打开块的堆栈(即,当您看到开放标记时,将其添加到数组中。当您看到关闭标记时,请从数组末尾删除元素,直到关闭标记与开放标记匹配。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接