高性能简单Java正则表达式

高性能简单Java正则表达式,java,regex,Java,Regex,我正在处理的部分代码使用一组正则表达式来搜索一些简单的字符串模式(例如,“foo[0-9]{3,4}bar”等模式)。目前,我们使用静态编译的Java模式,然后调用Pattern#matcher来检查字符串是否包含与模式的匹配(我不需要匹配,只需要一个布尔值来指示是否存在匹配)。这会导致明显的内存分配量,从而影响性能 有没有更好的Java正则表达式匹配选项更快,或者至少不会在每次搜索字符串时分配内存?您可以尝试使用pattern.matches()静态方法,该方法只返回布尔值。这不会返回匹配器对

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


有没有更好的Java正则表达式匹配选项更快,或者至少不会在每次搜索字符串时分配内存?

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


也就是说,regex模式不会被预编译,因此这将是一个性能与资源的问题。

尝试
matcher.reset(“newinputtext”)
方法以避免每次调用pattern.matcher时创建新的匹配器。

如果要避免为每个模式创建新的匹配器,请使用该方法,像这样:

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());
}


您还必须使用matcher的
reset()
方法,或者
find()
将只从上一次匹配结束的点进行搜索(假设匹配成功)。

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

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

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

这会返回什么结果boolean@c0mrade.matches()与Pattern.matches(,)的作用相同,后者与Pattern.compile()的作用相同,但他说他使用的是模式/匹配器,而不是字符串matches@c0mrade最大的区别在于,他说他使用的是静态编译模式,使用.matches每次调用时都会编译相同的模式,这需要更多的时间和内存,这应该在一定程度上提高速度。。请参阅我的[公认较弱]测试:这很好,但请注意Matcher类不是线程安全的。在线程环境中,为每个线程初始化一个匹配器,或者只使用一个预编译的静态模式(模式类是线程安全的,但这会给您带来与开始时相同的内存分配问题)。
Pattern#matches
在该方法内创建一个匹配器对象。@jonderry:非常好的观点+1。它实际上通过编译正则表达式来创建这两种模式,并为给定的输入创建Mather。此外,还添加了测试,以确保优化的版本与普通正则表达式执行相同的操作。如果有人更改了正则表达式而忘记了其余的,这会很方便。很好的提示-这也适用于contains,并且匹配不一定是完美的-它只需要足以将模式匹配器的内容数量减少至少50%