0

所以我有一些将 BBCode 转换为 HTML 的 Javascript,这似乎工作得很好,但我有一个问题。

这是我用来将 BB 标签 [b] 和 [/b] 转换为 <b> 和 </b>的表达式之一。

str = str.replace(/\[b\]((\s|\S)*?)\[\/b\]/ig, '<b>$1</b>');

这也会转换连续的标签。例如

[b]str1[/b] [b]str2[/b]

变成

字符串 1 字符串 2

哪个好;这就是我想要它做的。但是,当我尝试像这样匹配引号标签时

str = str.replace(/\[quote\]((\s|\S)*?)\[\/quote\]/ig, '<span class="quotebox">$1</span>');

str 在哪里

[quote]1 级嵌套[quote]2 级嵌套[/quote][/quote]

只有第一个标签被匹配和转换,所以我最终得到的输出看起来像

嵌套级别 1 [quote]嵌套级别 2

[/引用]

使用引号框外的最后一个引号标签 - 它应该嵌套在另一个引号内。帮助?

另外,如果它是相关的,quotebox 类如下

.quotebox{
边框:1px 内嵌黑色;
显示:块;
边距底部:5px;
边距顶部:5px;
填充:2px 2px 2px 4px;
}

4

1 回答 1

1

您刚刚被(真正的)正则表达式只能描述正则语言的事实所困扰。正则表达式无法描述的显着特征是递归。典型的例子是Dyck 语言,该语言由所有平衡括号字符串组成,例如(), (())()((())),((((()))))等。这是非常规的,本质上是您要解决的问题:匹配适当嵌套[b][/b]年代,[quote][/quote]s 等。换句话说,用正则表达式做你想做的事实际上是不可能的。但是,您可能已经注意到我说的是“真实”。JavaScript 等语言中提供的正则表达式不是真正的正则表达式。他们有额外的权力,主要(完全?)源于反向引用。例如,正则表达式(.*)\1描述了一种非常规语言。但是,即使考虑到这一点,我也不认为您可以匹配 Dyck 语言。1

那么,有什么解决办法呢?找到一个预先存在的用 JavaScript 编写的 BBCode 到 HTML 转换器!这绝对会让你的生活变得最简单。不幸的是,我不知道有哪一个在我脑海中浮现,因为我没有做太多的 JavaScript 编程。 这个 StackOverflow 问题表示这样的事情可能不存在,在这种情况下,您唯一的选择是滚动您自己的解析器。当然,更复杂,但肯定是可行的。在我的脑海中(我不是专家),您可能想要扫描字符串直到找到标签。(识别标签可能是正则表达式的一项好任务。)如果它是开始标签,则将其压入堆栈。如果它是结束标记,则弹出堆栈,确保结束标记与开始标记匹配,然后将您目前看到的字符串包装在适当的 HTML 中。这可能行不通,或者可能太复杂了——这只是我快速思考问题后的 2 美分。


1:我不是 100% 确定,但是我见过的唯一一个匹配平衡括号的正则表达式的例子是在 Perl 中,它嵌入了 Perl 代码,这是 JavaScript 无法做到的。无论哪种方式,这都是不可取的——您正在尝试使用一种会使您的任务变得更加复杂的工具。)

于 2010-12-19T02:11:57.170 回答