用于捕获 BBCode 中第一个结束标记的正则表达式

RegEx for capturing the first closing tag in BBCode

我有这个正则表达式 (Regex101):

\[tag(?:=(["']?)(.+))?\](.*?)\[\/tag\]

它允许四种不同的形式:

[tag=foo]foo[/tag]
[tag="foo"]foo[/tag]
[tag='foo']foo[/tag]
[tag]sdfo[/tag]

所有表格都有效,但如果我尝试在每个表格的末尾添加另一个 [/tag],第一个表格将继续捕获直到最后一个结束标记(如链接页面所示)。有没有可能让它不继续捕获,保持所有表格仍然有效?

此外,任何其他捕获任何其他奇怪行为的建议都被接受。

This expression 可能会帮助您捕获到第一个想要的 [\tag]:

(\[tag?[=A-Za-z0-9\x22\x27]+\])([A-Za-z]+)(\[\/tag\])

如果您想增加或减少边界,您可以这样做。例如,如有必要,您可以在 [] 中允许更多字符。

图表

此图显示了表达式的工作原理,您可以在此 link 中可视化您的表达式。我在 g 后面添加了一个外观,作为一个技巧,以通过 [tag]。这也可以改变,我假设你的输入都有 [tag].

性能

这个 JavaScript 片段显示了使用简单的 100 万次 for 循环时该表达式的性能。

repeat = 1000000;
start = Date.now();

for (var i = repeat; i >= 0; i--) {
 var string = '[tag=foo]foo[/tag]foo[/tag]';
 var regex = /^((\[tag?[=A-Za-z0-9\x22\x27]+\])([A-Za-z]+)(\[\/tag\]))(.*)/g;
 var match = string.replace(regex, "");
}

end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match  ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test.  ");

只需制作 .+ non-greedy 即可。

\[tag(?:=(["']?)(.+?))?\](.*?)\[\/tag\]