1

我有正则表达式,它解析模板中使用的 freemarker 宏的所有名称(例如来自<@macroName />I need only macroName)。模板通常很大(大约 3 万个字符)。带有正则表达式的 Java 代码如下所示:

Pattern pattern = Pattern.compile(".*?<@(.*?)[ /].*?", 
                                  Pattern.DOTALL | Pattern.UNIX_LINES);
Matcher matcher = pattern.matcher(inputText);
while(matcher.find()){
    //... some code
}

但有时会发生我得到这个异常:

java.util.regex.Pattern$Curly.match1(Pattern.java:3814)
java.util.regex.Pattern$Curly.match(Pattern.java:3763)
java.util.regex.Pattern$Start.match(Pattern.java:3072)
java.util.regex.Matcher.search(Matcher.java:1116)
java.util.regex.Matcher.find(Matcher.java:552)
...

有人知道为什么会发生这种情况,或者有人可以确定我使用的正则表达式是否优化得很好吗?谢谢你

4

2 回答 2

3

因为<@macro macroName />您的正则表达式看起来有点复杂。要么有些事情(特殊情况)<@macro macroName />没有描述,要么正则表达式太努力了。尝试:

<@macro\s+(\S+)\s+/>

您现在应该在组#1 中有宏的名称。

于 2012-05-31T11:22:25.277 回答
1

您可以摆脱领先.*?,因为您不需要在匹配之前/之间使用文本。正则表达式引擎将负责扫描下一场比赛,它会比你正在做的更有效。只需给它标签本身的模式,然后别挡道。

您可以摆脱尾随 .*?,因为它从不做任何事情。想一想:它不情愿地尝试匹配零个或多个任何字符。这意味着它尝试做的第一件事就是什么都不匹配。该尝试将成功(总是可能不匹配任何内容),因此它永远不会尝试消耗更多字符。

你可能想要这样的东西():

<@(\w+)[\s/]

...或用 Java 语言:

Pattern p= Pattern.compile("<@(\\w+)[ /]");

您不需要 DOTALL(无点)或任何其他修饰符。

于 2012-05-31T19:22:29.563 回答