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 和 0 参数的 bbcode。但是当我为参数添加正则表达式匹配时,它没有正确匹配嵌套的 bbcode。

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

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

那么有没有办法用正则表达式或其他东西有效地匹配 bbcode。我唯一能想到的是使用访问者模式并以这种方式将我的文本与每个可能的标签分开,我可以对我的文本解析有更多的控制,我可能可以验证我的文档,所以如果输入文本没有'没有有效的 bbcode。我可以在保存任何内容之前通知用户错误。

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

有更好的主意吗?或任何可能导致高效灵活的 bbcode 解析器的东西?

谢谢你,对不起我的英语不好......

4

5 回答 5

8

有几个现有的用于解析 BBCode 的库,查看这些库可能比尝试使用自己的库更容易:

这是一对,如果你环顾四周,我相信还有更多:
PECL bbcode
PEAR HTML_BBCodeParser

于 2009-01-28T19:36:02.553 回答
8

我自己一直在研究 bbcode 解析器。他们中的大多数使用正则表达式和 PHP4 并在 PHP 5.2+ 上产生错误或根本不工作。PECL bbcode 和 PEAR HTML_BBCodeParser 似乎不再维护(2012 年末),并且不容易安装在我必须使用的共享主机设置上。StringParser_BBCode对 5.2+ 进行了一些小的调整,但添加新标签的方法很笨拙,最后一次更新是在 2008 年。

埋在 Bing 搜索的第 4 页(我快绝望了),我找到了 jBBCode,它看起来很新,需要 PHP 5.3。麻省理工学院执照。我还没有尝试构建自定义标签,但到目前为止,它是我尝试过的唯一一个在使用 PHP 5.3 的共享主机帐户上开箱即用的标签。

于 2012-10-18T04:46:39.167 回答
6

有一个peclPEAR BBCode 解析库。无需重新发明您自己多年的工作,软件就足够难了。

如果这些都不是一个选项,我会专注于将 BBCode 转换为有效的 XML 字符串,然后使用您最喜欢的 XML 解析例程。这里非常非常粗略的想法,但是

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

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

  3. 不要忘记在 [tagname:

如果 BBCode 嵌套正确,您应该都可以将此字符串传递给 XML 解析对象(SimpleXML、DOMDocument 等)

于 2009-01-28T21:06:59.407 回答
3

回应:“有更好的主意吗?” (我假设这不仅仅是为了改进 bbcode 特定建议的邀请)

我们最近研究了 bbcode 路线,并决定改用htmlpurifier。该决定部分基于此处 htmlpurifier 组列出的各种方法之间的比较(诚然可能有偏见)以及此处对 bbcode 的讨论(同样,由 htmlpurifer 组

而且我认为你的英语非常好。我相信这比我用你的母语做的要好得多。

于 2009-01-28T19:32:48.583 回答
2

使用preg_split()with PREG_DELIM_CAPTUREflag 将源代码拆分为标签和非标签。然后迭代保持打开块堆栈的标签(即,当您看到开始标签时,将其添加到数组中。当您看到结束标签时,从数组末尾删除元素,直到结束标签与开始标签匹配。)

于 2010-03-09T20:47:26.450 回答