1

我正在尝试构建一个 bbcode 解析器,但是在弄清楚如何避免匹配过于广泛时遇到了很多问题。例如,我想实现一个 [list] 到这样的转换:

\[list\](.*)\[/list\]

将被替换为:

<ul>$1</ul>

这很好用,除非我有两个列表,其中正则表达式与第一个列表的开始标记和第二个列表的结束标记匹配。所以这

[list]list1[/list] [list]list2[/list]

变成这样:

<ul>list1[/list] [list]list2</ul>

这会产生非常丑陋的输出。关于如何解决这个问题的任何想法?

4

2 回答 2

8

您使用的方法可能最终不是一个特别好的方法,但要解决该特定问题,只需更改为非贪婪匹配:

\[list\](.*?)\[\/list\]

请注意,这种方式会遇到嵌套列表而不是背靠背列表的问题。

于 2009-02-20T00:27:00.647 回答
4

如果您正在做的不仅仅是轻量级的 hack,而是更永久的东西,您可能希望转向真正的解析器。Java 中的正则表达式特别慢(即使使用预编译模式)并且匹配嵌套结构(尤其是不同的嵌套结构,如 "foo [u][i] bar [s]baz[/s][/i][/u]" )将成为皇家的痛苦。

相反,请尝试使用基于状态的解析器,它会反复将您的句子分成“foo”/(u)/“[i] bar [s]baz[/s][/i][/u]”等部分,并且维护一组在遇到匹配构造分隔符时翻转的状态。

于 2009-02-20T01:32:24.810 回答