RegEx用于捕获BBCode中的第一个结束标记

时间:2019-05-08 02:33:22

标签: regex regex-lookarounds regex-group regex-greedy bbcode

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

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

它允许四种不同的形式:

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

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

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

2 个答案:

答案 0 :(得分:2)

This expression可能会帮助您捕获第一个所需的[\tag]

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

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

enter image description here

该图显示了表达式的工作方式,您可以在此link中可视化表达式。作为一种技巧,我在g之后添加了一个外观,以传递[tag]。这也可以更改,我假设您的输入都包含[tag]

enter image description here

性能

此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, "$1");
}

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

答案 1 :(得分:2)

只需将.+设为非贪婪,它就应该可以正常工作。

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