BBCode正则表达式解析问题

时间:2010-12-19 01:50:12

标签: javascript regex bbcode

所以我有一些将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]

变为

  

str1 str2

哪个好;这就是我想要的。但是,当我尝试匹配引用标签时,如此

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

其中str是

  

[quote] Nest level 1 [quote] Nest level 2 [/ quote] [/ quote]

只有第一个标签匹配并转换,所以我最终会得到类似

的输出
  

Nest level 1   [引用] Nest level 2

[/报价]

使用引号框之外的最后一个引号标记 - 它应该嵌套在另一个引号框中。帮助

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

  

.quotebox {
   边框:1px插入黑色;
   显示:块;
   边距:5像素;
   边距:5像素;
   填充:2px 2px 2px 4px;
  }

1 个答案:

答案 0 :(得分:1)

你刚刚被(真正的)正则表达式只能描述regular languages这一事实所困扰。正则表达式无法描述的显着特征是递归。这个典型的例子是Dyck language,这种语言由所有平衡括号的字符串组成,例如()(())()((()))((((()))))等。这是非常规,并且本质上是您尝试解决的问题:匹配适当嵌套的[b][/b][quote][/quote]等。换句话说,用正则表达式完全不可能做到你想要的东西。但是,您可能已经注意到我说“真实”。像JavaScript这样的语言提供的正则表达式不是真正的正则表达式;他们有额外的权力,大部分(完全?)源于反向引用。例如,正则表达式(.*)\1描述了非常规语言。尽管如此,我认为你不能匹配Dyck语言。 1

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


1:我不是百分百肯定,但是我所见过的正则表达式匹配平衡括号的唯一例子是Perl,它嵌入了Perl代码,JavaScript不能做。无论哪种方式,它都是不可取的 - 你试图使用一种工具来使你的任务变得更加复杂。)