该方法总是在某个时候被调用;这是创建 Pattern 对象的唯一方法。所以问题真的是,你为什么要明确地称呼它?一个原因是您需要对 Matcher 对象的引用,以便可以使用其方法,例如检索捕获组的内容。获得 Matcher 对象的唯一方法是通过 Pattern 对象的方法,而获得 Pattern 对象的唯一方法是通过该方法。然后是与 不同于 String 或 Pattern 类的方法。compile()
group(int)
matcher()
compile()
find()
matches()
另一个原因是为了避免一遍又一遍地创建相同的 Pattern 对象。每次在 String 中使用其中一个由正则表达式驱动的方法(或 Pattern 中的静态方法)时,它都会创建一个新的 Pattern 和一个新的 Matcher。所以这个代码片段:matches()
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 的方法是否与 有关。NET 的修饰符;答案是否定的。Java 的方法仅等效于 。NET 的正则表达式构造函数。指定选项时:compile()
RegexOptions.Compiled
Pattern.compile()
Compiled
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
...它将正则表达式直接编译为CIL字节代码,使其执行得更快,但在前期处理和内存使用方面付出了巨大的代价 - 将其视为正则表达式的类固醇。Java没有等价物;在幕后创建的模式与您使用 显式创建的模式之间没有区别。String#matches(String)
Pattern#compile(String)
(编辑:我最初说所有.NET正则表达式对象都被缓存,这是不正确的。从 .NET 2.0 开始,自动缓存仅使用静态方法(如 )发生,而不是直接调用正则表达式构造函数时。裁判Regex.Matches()
)