Pattern.compile()方法的重要性是什么? 为什么在获取Matcher对象之前需要编译正则表达式字符串?
Pattern.compile()
Matcher
例如 :
String regex = "((\\S+)\\s*some\\s*"; Pattern pattern = Pattern.compile(regex); // why do I need to compile Matcher matcher = pattern.matcher(text);
compile()总是在某个时候调用该方法。这是创建Pattern对象的唯一方法。所以问题是,为什么要 显式地 调用它?原因之一是您需要对Matcher对象的引用,以便可以使用其方法,例如group(int)检索捕获组的内容。保留Matcher对象的唯一方法是通过Pattern对象的matcher()方法,而保留Pattern对象的唯一方法是通过compile()方法。然后是与String或Pattern类find()不同的方法,它不同于matches()。
compile()
group(int)
matcher()
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选项时:
RegexOptions.Compiled
Compiled
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
…它将正则表达式直接编译为CIL字节码,从而使其执行得更快,但是在前期处理和内存使用方面却付出了高昂的代价- 将其视为正则表达式的类固醇。Java没有等效的功能。在幕后创建的Pattern String#matches(String)和使用显式创建的Pattern之间没有区别Pattern#compile(String)。
String#matches(String)
Pattern#compile(String)
(编辑:我原来是说,所有的.NET regex对象缓存,这是不正确由于.NET 2.0,只能用静态的方法,如自动缓存发生。Regex.Matches(),而不是当你直接调用正则表达式的构造。REF)
Regex.Matches()