我有regexp解析模板中所用的freemarker宏的所有名称(例如来自<@macroName />
我只需要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)
...
有人知道它为什么会发生,或者任何人都可以确定我使用的正则表达式是否得到了很好的优化? 谢谢
答案 0 :(得分:3)
对于<@macro macroName />
,你的正则表达式看起来有点复杂。要么<@macro macroName />
没有描述的事情(特殊情况),要么正则表达式都在努力。尝试:
<@macro\s+(\S+)\s+/>
您现在应该拥有组#1中的宏名称。
答案 1 :(得分:1)
您可以删除前导.*?
,因为您不需要在匹配之前/之间使用文本。正则表达式引擎将负责扫描下一场比赛,它将比你正在做的更有效率。只需给它标签本身的模式,然后就可以了。
你可以摆脱尾随 .*?
,因为它永远不会做任何事情。想一想:它不情愿地试图匹配零个或多个任何角色。这意味着它试图做的第一件事就是什么都不匹配。该尝试将成功(它总是可以匹配任何东西),所以它永远不会尝试消耗更多的字符。
你可能想要这样的东西():
<@(\w+)[\s/]
......或者说Java:
Pattern p= Pattern.compile("<@(\\w+)[ /]");
您不需要DOTALL(无点)或任何其他修饰符。