匹配(可能是嵌套的)BBCode 标签
如果元素是嵌套的,则需要多通道方法。这可以通过以下两种方式之一来完成;从内向外匹配(不需要递归表达式),或从外向内匹配(需要递归表达式)。(另请参阅我对类似问题的回答:PHP,preg_replace 中的嵌套模板)但是,由于 Javascript 正则表达式引擎不支持递归表达式,因此(正确)使用正则表达式执行此操作的唯一方法是由内而外。下面是一个经过测试的函数,它从内到外用 SPAN html 标签替换 BBCode SIZE 标签。请注意,下面的(快速)正则表达式很复杂(一方面它实现了 Jeffrey Friedl 的“展开循环”效率技术 - 请参阅:掌握正则表达式(第 3 版)有关详细信息),并且 IMO 所有复杂的正则表达式都应进行彻底的注释和格式化以提高可读性。由于 Javascript 没有自由间距模式,因此下面的正则表达式首先在 PHP 自由间距模式下完全注释。实际使用的未注释 js 正则表达式与详细注释的相同。
正则表达式匹配最里面的(可能是嵌套的)大小标签:
// Regular expression in commented (PHP string) format.
$re = '% # Match innermost [size=ddd]...[/size] structure.
\[size= # Literal start tag name, =.
(\d+)\] # $1: Size number, ending-"]".
( # $2: Element contents.
# Use Friedls "Unrolling-the-Loop" technique:
# Begin: {normal* (special normal*)*} construct.
[^[]* # {normal*} Zero or more non-"[".
(?: # Begin {(special normal*)*}.
\[ # {special} Tag open literal char,
(?! # but only if NOT start of
size=\d+\] # [size=ddd] open tag
| \/size\] # or [/size] close tag.
) # End negative lookahead.
[^[]* # More {normal*}.
)* # Finish {(special normal*)*}.
) # $2: Element contents.
\[\/size\] # Literal end tag.
%ix';
Javascript函数:parseSizeBBCode(text)
function parseSizeBBCode(text) {
// Here is the same regular expression in javascript syntax:
var re = /\[size=(\d+)\]([^[]*(?:\[(?!size=\d+\]|\/size\])[^[]*)*)\[\/size\]/ig;
while(text.search(re) !== -1) {
text = text.replace(re, '<span style="font-size: $1pt">$2</span>');
}
return text;
}
示例输入:
r'''
[size=10] size 10 stuff
[size=20] size 20 stuff
[size=30] size 30 stuff [/size]
[/size]
[/size]
'''
示例输出:
r'''
<span style="font-size: 10pt"> size 10 stuff
<span style="font-size: 20pt"> size 20 stuff
<span style="font-size: 30pt"> size 30 stuff </span>
</span>
</span>
'''
免责声明 - 不要使用此解决方案!
请注意,使用正则表达式解析 BBCode 充满危险!(这里没有提到很多“陷阱”。)很多人会说这是不可能的。但是,我强烈反对并且实际上已经编写了一个完整的 BBCode 解析器(在 PHP 中),它使用递归正则表达式并且工作得非常好(而且速度很快)。您可以在这里看到它的实际效果:New 2011 FluxBB Parser(请注意,它使用了一些非常复杂的正则表达式,不适合胆小的人)。
但总的来说,我强烈警告不要使用正则表达式解析 BBCode,除非你对正则表达式有非常深刻和透彻的理解(这可以通过仔细研究和实践Friedl 的杰作来获得)。换句话说,如果您不是 regex 的大师(即 regex guru),请避免将它们用于除最琐碎的应用程序之外的任何应用程序。