web-dev-qa-db-ja.com

Java Regexにおけるmatches()とfind()の違い

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

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

その仮定が正しければ、見つかった一致の数を数えたくなければ、matches()の代わりにfind()を使いたいと思うときはいつでもわかりません。

私の意見では、Stringクラスは組み込みメソッドとしてfind()の代わりにmatches()を持つべきです。

要約すると:

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

matchesは、文字列全体に対して式を照合し、暗黙的にパターンの先頭に^を、末尾に$を追加しようとします。つまり、部分文字列は検索されません。したがって、このコードの出力は以下のとおりです。

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
*/

123a123bのサブストリングであるため、find()メソッドはtrueを出力します。 matches()a123bのみを '見る'ので、これは123と同じではないのでfalseを出力します。

275

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

73
khachik

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 
 ----------- 
 Found:true  - 位置0 
 Found:false [:____]見つかったもの:false 
一致したもの:true 
一致したもの:true 
一致したもの:true 
一致したもの:true 

そのため、正規表現が^$で囲まれている場合でも、Matcherオブジェクトがリセットされなかった場合は、find()を複数回呼び出すときには注意が必要です。

49
L. Holanda

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
        }
    }
5
Sumanth Varada

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]で指定されたインデックスへのインデックス。少なくとも1つの一致を見つけます。そのような一致が見つかった場合、それはインデックス付けされ、ループはインデックス付けされた結果に基づいて実行され、そうでなければ、matches();のように事前計算を行わなかった場合、ループは実行されます。アルファベットではありません。

3
user5767743