我有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)
...


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

最佳答案

您可以删除开头的.*?,因为您不需要在匹配之前/之间消耗文本。正则表达式引擎将负责扫描下一场比赛,并且比您做的要有效得多。只需为其提供标签本身的模式,就可以摆脱它。

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

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

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


...或用Java讲:

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


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

10-08 08:39