高性能的简单Java正则表达式

时间:2011-09-21 18:59:14

标签: java regex

我正在处理的部分代码使用一堆正则表达式来搜索一些简单的字符串模式(例如,像“foo [0-9] {3,4} bar”这样的模式。目前,我们使用静态编译的Java模式,然后调用Pattern#matcher来检查字符串是否包含与模式的匹配(我不需要匹配,只需要一个布尔值来指示是否存在匹配)。这会导致显着的内存分配量,从而影响性能。

对于Java正则表达式匹配是否有更好的选择更快或至少在每次搜索字符串中的模式时都不分配内存?

4 个答案:

答案 0 :(得分:13)

尝试matcher.reset("newinputtext")方法,以避免每次调用Pattern.matcher时都创建新的匹配器。

答案 1 :(得分:4)

如果您预计匹配正则表达式的行数少于50%,您可以首先尝试通过String.indexOf()测试一些子序列,与正则表达式匹配器相比,简单序列的速度快3到20倍:

if (line.indexOf("foo")>-1) && pattern.matcher(line).matches()) {
    ...

如果您在代码中添加这样的启发式方法,请记住要始终记录它们,并使用分析器验证代码与简单代码相比确实更快。

答案 2 :(得分:2)

如果您想避免为每个模式创建新的匹配器,请使用usePattern()方法,如下所示:

Pattern[] pats = {
  Pattern.compile("123"),
  Pattern.compile("abc"),
  Pattern.compile("foo")
};
String s = "123 abc";
Matcher m = Pattern.compile("dummy").matcher(s);
for (Pattern p : pats)
{
  System.out.printf("%s : %b%n", p.pattern(), m.reset().usePattern(p).find());
}

<强> see the demo on Ideone

你也必须使用matcher的reset()方法,或find()只会搜索上一场比赛结束的点(假设比赛成功)。

答案 3 :(得分:0)

您可以尝试使用只返回布尔值的Pattern.matches()静态方法。这不会返回Matcher对象,因此它可以帮助解决内存分配问题。

有人说正则表达式模式不会被预编译,所以它就是性能与资源的关系。