我正在尝试构建一个bbcode解析器,但是我在解决如何避免过于广泛匹配时遇到了一些问题。例如,我想像这样实现[list]转换:
\[list\](.*)\[/list\]
将被替换为:
<ul>$1</ul>
这很好用,除非我有两个列表,其中正则表达式匹配第一个列表的开始标记和第二个列表的结束标记。所以这个
[list]list1[/list] [list]list2[/list]
成为这个:
<ul>list1[/list] [list]list2</ul>
产生非常难看的输出。关于如何解决这个问题的任何想法?
答案 0 :(得分:8)
您使用的方法可能不会成为一种特别好的方法,但要解决该特定问题,只需更改为非贪婪匹配:
\[list\](.*?)\[\/list\]
请注意,这种方式会遇到嵌套列表而不是背靠背列表的问题。
答案 1 :(得分:4)
如果你正在做的不只是一个轻量级的黑客,而是更永久的东西,你可能想要转移到一个真正的解析器。 Java中的Regexp特别慢(即使使用预编译模式)和匹配的嵌套构造(尤其是不同的嵌套构造,如“foo [u] [i] bar [s] baz [/ s] [/ i] [/ u]“)将成为王室的痛苦。
相反,尝试使用基于状态的解析器,在“foo”/(u)/“[i] bar [s] baz [/ s] [/ i] [/ u]等部分重复剪切句子“并保持一组状态,只要遇到匹配的构造分隔符就会翻转。