compile()总是在某个时候调用该方法。这是创建Pattern对象的唯一方法。所以问题是,为什么要 显式地
调用它?原因之一是您需要对Matcher对象的引用,以便可以使用其方法,例如
group(int)检索捕获组的内容。保留Matcher对象的唯一方法是通过Pattern对象的
matcher()方法,而保留Pattern对象的唯一方法是通过
compile()方法。然后是与String或Pattern类
find()不同的方法,它不同于
matches()。
另一个原因是避免一遍又一遍地创建相同的Pattern对象。每次您使用String中正则表达式支持的方法之一(或
matches()Pattern中的静态方法)时,它都会创建一个新的Pattern和一个Matcher。因此,此代码段:
for (String s : myStringList) { if ( s.matches("\d+") ) { doSomething(); }}…完全等于:
for (String s : myStringList) { if ( Pattern.compile("\d+").matcher(s).matches() ) { doSomething(); }}显然,这做了很多不必要的工作。实际上,与执行实际匹配相比,编译正则表达式和实例化Pattern对象要花很长时间。因此,将这一步骤从循环中拉出来通常是有意义的。您也可以提前创建Matcher,尽管它们并不那么昂贵:
Pattern p = Pattern.compile("\d+");Matcher m = p.matcher("");for (String s : myStringList) { if ( m.reset(s).matches() ) { doSomething(); }}如果您熟悉.NET正则表达式,您可能想知道Java的
compile()方法是否与.NET的
RegexOptions.Compiled修饰符相关;答案是不。Java的
Pattern.compile()方法仅等效于.NET的Regex构造函数。指定
Compiled选项时:
Regex r = new Regex(@"d+", RegexOptions.Compiled);
…它将正则表达式直接编译为CIL字节码,从而使其执行得更快,但是在前期处理和内存使用方面却付出了高昂的代价-
将其视为正则表达式的类固醇。Java没有等效的功能。在幕后创建的Pattern
String#matches(String)和使用显式创建的Pattern之间没有区别
Pattern#compile(String)。
(编辑:我原来是说,所有的.NET regex对象缓存,这是不正确由于.NET
2.0,只能用静态的方法,如自动缓存发生。
Regex.Matches(),而不是当你直接调用正则表达式的构造。REF)



