Java Regexでのmatches()とfind()の違い


250

との違いを理解しようmatches()としていfind()ます。

Javadocによると(私が理解しているところから)、matches()探しているものが見つかっても文字列全体を検索し、探しfind()ているものが見つかったときに停止します。

その仮定が正しい場合、一致の数を数えたいmatches()find()でない限り、の代わりに使用したいときはいつでもわかりません。

私の意見では、Stringクラスは組み込みのメソッドとしてではfind()なく、持つ必要がありmatches()ます。

要約すると:

  1. 私の仮定は正しいですか?
  2. matches()代わりにfind()いつ使用すると便利ですか?

2
find()複数回呼び出すと、同じ結果が異なる場合があることに注意してくださいMatcher。以下の私の答えを参照してください。
L.ホランダ2013

回答:


300

matches文字列全体に対して式を照合し、パターンの^最初と$最後に暗黙的にa を追加しようとします。つまり、部分文字列を検索しません。したがって、このコードの出力:

public static void main(String[] args) throws ParseException {
    Pattern p = Pattern.compile("\\d\\d\\d");
    Matcher m = p.matcher("a123b");
    System.out.println(m.find());
    System.out.println(m.matches());

    p = Pattern.compile("^\\d\\d\\d$");
    m = p.matcher("123");
    System.out.println(m.find());
    System.out.println(m.matches());
}

/* output:
true
false
true
true
*/

123の部分文字列なa123bので、find()メソッドはtrueを出力します。と同じではなく、したがってfalseを出力するmatches()「見る」だけです。a123b123


25
この答えは誤解を招くものです。matchers()単にfind()暗黙の^と$で囲まれたa ではありません。を前に付けないと、.find()複数回呼び出しても結果が異なる場合があることに注意してください。ただしreset()matches()常に同じ結果が返されます。以下の私の答えを参照してください。
L. Holanda

80

matches文字列全体が指定されたパターンに一致する場合はtrueを返します。findパターンに一致する部分文字列を見つけようとします。


35
それmatches(p)はそれがfind("^" + p + "$")より明確であるかのように同じであると言うことができます。
jensgram

4
答えを明確にするための単なる例: "[az] +"と文字列 "123abc123"は、matches()を使用すると失敗しますが、find()を使用すると成功します。
bezmax

3
@Max正確に、"123abc123".matches("[a-z]+")同じように失敗し"123abc123".find("^[a-z]+$")ます。私の要点は、開始アンカーと終了アンカーの両方matches()と同じように、完全に一致することfind()です。
jensgram

5
Pattern.compile("some pattern").matcher(str).matches()次と等しいPattern.compile("^some pattern$").matcher(str).find()
AlexR

3
@AlexR / @jensgram:完全に同じで...("some pattern").matcher(str).matches()はありません...("^some pattern$").matcher(str).find()。最初の呼び出しでのみ当てはまります。以下の私の答えを参照してください。
L.ホランダ

62

matches()文字列全体が一致した場合にのみtrueを返します。 正規表現に一致する部分文字列内の次の出現find()を見つけようとします。「次へ」に重点が置かれていることに注意してください。つまり、複数回呼び出した結果は同じではない可能性があります。さらに、を使用して、部分文字列が一致した位置を返すように呼び出すことができます。find()find()start()

final Matcher subMatcher = Pattern.compile("\\d+").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + subMatcher.matches());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find());
System.out.println("Found: " + subMatcher.find());
System.out.println("Matched: " + subMatcher.matches());

System.out.println("-----------");
final Matcher fullMatcher = Pattern.compile("^\\w+$").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + fullMatcher.find() + " - position " + fullMatcher.start());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());

出力されます:

見つかった:false
見つかった:true-位置4
見つかった:true-17位
見つかった:true-20位
見つかった:false
見つかった:false
一致:false
-----------
見つかった:true-位置0
見つかった:false
見つかった:false
一致:true
一致:true
一致:true
一致:true

呼び出したときに、気をつけてfind()複数回の場合はMatcher、オブジェクトがリセットされませんでした正規表現がで囲まれている場合でも、^および$完全な文字列にマッチします。


2
非常に役立つ仲間
DockYard

6

find()は正規表現に対して部分文字列matches()を考慮し、完全な表現を考慮します。

find() 式の部分文字列がパターンに一致する場合にのみtrueを返します。

public static void main(String[] args) {
        Pattern p = Pattern.compile("\\d");
        String candidate = "Java123";
        Matcher m = p.matcher(candidate);

        if (m != null){
            System.out.println(m.find());//true
            System.out.println(m.matches());//false
        }
    }

3

matches();バッファリングはしませんが、find()バッファリングします。find()最初に文字列の最後まで検索し、結果にインデックスを付け、ブール値と対応するインデックスを返します。

そのため、次のようなコードがある場合

1:Pattern.compile("[a-z]");

2:Pattern.matcher("0a1b1c3d4");

3:int count = 0;

4:while(matcher.find()){

5:count++: }

4:で指定されたコードインデックス(インデックスの全体を通しますパターン構造を使用して正規表現エンジンregex[single character]。そのような一致が見つかった場合、それはその後、インデックス付けされる少なくとも一つの一致を見つけるためにループに基づいて実行されますmatches();のような事前計算を行わなかった場合のインデックス付き結果else 一致しない文字列の最初の文字がアルファベットではないため、whileステートメントは実行されません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.