Perbedaan antara kecocokan () dan temukan () di Java Regex

250

Saya mencoba memahami perbedaan antara matches()dan find().

Menurut Javadoc, (dari apa yang saya mengerti), matches()akan mencari seluruh string bahkan jika ia menemukan apa yang dicari, dan find()akan berhenti ketika menemukan apa yang dicari.

Jika asumsi itu benar, saya tidak dapat melihat kapan pun Anda ingin menggunakannya matches()sebagai pengganti find(), kecuali jika Anda ingin menghitung jumlah kecocokan yang ditemukannya.

Menurut pendapat saya, kelas String seharusnya find()bukan matches()sebagai metode inbuilt.

Jadi untuk meringkas:

  1. Apakah asumsi saya benar?
  2. Kapan itu berguna untuk digunakan, matches()bukan find()?
Shervin Asgari
sumber
2
Ketahuilah bahwa menelepon find()beberapa kali dapat memberikan hasil yang berbeda untuk hal yang sama Matcher. Lihat jawaban saya di bawah ini.
L. Holanda

Jawaban:

300

matchesmencoba untuk mencocokkan ekspresi dengan seluruh string dan secara implisit menambahkan ^di awal dan $di akhir pola Anda, artinya tidak akan mencari substring. Maka output dari kode ini:

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

123adalah substring a123bsehingga find()metode ini menghasilkan true. matches()hanya 'melihat' a123byang tidak sama dengan 123dan karenanya menghasilkan false.

Sanjay T. Sharma
sumber
25
Jawaban ini menyesatkan. matchers()bukan hanya find()dengan ^ dan $. Sadarilah bahwa menelepon .find()lebih dari satu kali dapat memiliki hasil yang berbeda jika tidak didahului oleh reset(), sementara matches()akan selalu mengembalikan hasil yang sama. Lihat jawaban saya di bawah ini.
L. Holanda
80

matchesmengembalikan true jika seluruh string cocok dengan pola yang diberikan. findmencoba menemukan substring yang cocok dengan pola.

khachik
sumber
35
Anda bisa mengatakan itu matches(p)sama seperti find("^" + p + "$")jika itu lebih jelas.
jensgram
4
Hanya sebuah contoh untuk mengklarifikasi jawabannya: "[az] +" dengan string "123abc123" akan gagal menggunakan kecocokan () tetapi akan berhasil menggunakan find ().
bezmax
3
@ Max Tepat, "123abc123".matches("[a-z]+")akan gagal seperti biasa "123abc123".find("^[a-z]+$"). Maksud saya adalah, itu matches()berlaku untuk pertandingan yang lengkap, seperti halnya find()dengan jangkar awal dan akhir.
jensgram
5
Pattern.compile("some pattern").matcher(str).matches()sama denganPattern.compile("^some pattern$").matcher(str).find()
AlexR
3
@AlexR / @jensgram: ...("some pattern").matcher(str).matches()ini tidak persis sama untuk ...("^some pattern$").matcher(str).find()yang hanya berlaku dalam panggilan pertama. Lihat jawaban saya di bawah ini.
L. Holanda
62

matches()hanya akan mengembalikan true jika string penuh cocok. find()akan mencoba menemukan kemunculan berikutnya dalam substring yang cocok dengan regex. Perhatikan penekanannya pada "selanjutnya". Itu berarti, hasil panggilan find()beberapa kali mungkin tidak sama. Selain itu, dengan menggunakan find()Anda dapat menelepon start()untuk mengembalikan posisi substring yang cocok.

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());

Akan menghasilkan:

Ditemukan: false
Ditemukan: true - posisi 4
Ditemukan: true - posisi 17
Ditemukan: true - posisi 20
Ditemukan: false
Ditemukan: false
Cocok: salah
-----------
Ditemukan: true - position 0
Ditemukan: false
Ditemukan: false
Cocok: benar
Cocok: benar
Cocok: benar
Cocok: benar

Jadi, berhati-hatilah saat memanggil find()beberapa kali jika Matcherobjek tidak disetel ulang, bahkan ketika regex dikelilingi dengan ^dan $untuk mencocokkan string penuh.

L. Holanda
sumber
2
sobat yang sangat membantu
DockYard
6

find()akan mempertimbangkan sub-string terhadap ekspresi reguler di mana matches()akan mempertimbangkan ekspresi lengkap.

find() akan mengembalikan true hanya jika sub-string dari ekspresi cocok dengan pola.

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
        }
    }
Sumanth Varada
sumber
3

matches();tidak buffer, tetapi find()buffer. find()pertama-tama mencari ke akhir string, mengindeks hasilnya, dan mengembalikan nilai boolean dan indeks yang sesuai.

Itu sebabnya ketika Anda memiliki kode seperti

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

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

3:int count = 0;

4:while(matcher.find()){

5:count++: }

Pada 4: Mesin regex menggunakan struktur pola akan membaca seluruh kode Anda (indeks ke indeks seperti yang ditentukan oleh regex[single character]untuk menemukan setidaknya satu kecocokan. Jika kecocokan ditemukan, itu akan diindeks maka loop akan dijalankan berdasarkan pada hasil yang diindeks lain jika itu tidak melakukan perhitungan di depan seperti itu matches(), tidak.Kesimpulan sementara tidak akan pernah dijalankan karena karakter pertama dari string yang cocok bukan alfabet.


sumber