このcompile()
メソッドは常にある時点で呼び出されます。これは、Patternオブジェクトを作成する唯一の方法です。だから問題は本当に、なぜあなたはそれを明示的に呼ぶ必要があるのですか?1つの理由は、Matcherオブジェクトへの参照が必要なgroup(int)
ため、キャプチャグループのコンテンツを取得するなど、そのメソッドを使用できるためです。Matcherオブジェクトを取得する唯一の方法は、Patternオブジェクトのmatcher()
メソッドを使用することであり、Patternオブジェクトを取得する唯一の方法は、compile()
メソッドを使用することです。次にfind()
、とは異なりmatches()
、StringクラスまたはPatternクラスで複製されないメソッドがあります。
もう1つの理由は、同じPatternオブジェクトを何度も作成しないようにするためです。Stringの正規表現を利用したメソッド(またはmatches()
Pattern の静的メソッド)を使用するたびに、新しいパターンとマッチャーが作成されます。したがって、このコードスニペット:
for (String s : myStringList) {
if ( s.matches("\\d+") ) {
doSomething();
}
}
...これとまったく同じです:
for (String s : myStringList) {
if ( Pattern.compile("\\d+").matcher(s).matches() ) {
doSomething();
}
}
明らかに、それは多くの不必要な作業を行っています。実際、正規表現をコンパイルしてパターンオブジェクトをインスタンス化するのは、実際に一致させるよりも簡単に時間がかかります。したがって、通常、そのステップをループから外すことは理にかなっています。事前に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には同等のものはありません。裏で作成されたパターンと、でString#matches(String)
明示的に作成したパターンに違いはありませんPattern#compile(String)
。
(編集:私はもともとすべての.NETの正規表現オブジェクトが間違っていた、キャッシュされていることを述べ、.NET 2.0ので、自動キャッシュのような静的メソッドでのみ発生Regex.Matches()
。ないあなたが直接正規表現のコンストラクタを呼び出し、REF)