Perbezaan Antara Java Matcher find () dan match ()

1. Gambaran keseluruhan

Apabila bekerja dengan ungkapan biasa di Java, kita biasanya ingin mencari urutan watak untuk Pola tertentu . Untuk mempermudah ini, Java Regular Expressions API menyediakan kelas Matcher , yang dapat kita gunakan untuk mencocokkan ekspresi reguler yang diberikan terhadap teks.

Sebagai peraturan umum, kami hampir selalu ingin menggunakan salah satu daripada dua kaedah popular dari kelas Matcher :

  • cari()
  • perlawanan ()

Dalam tutorial ringkas ini, kita akan belajar mengenai perbezaan antara kaedah ini menggunakan sekumpulan contoh ringkas.

2. find () Menghubungi

Sederhananya, kaedah find () cuba mencari berlakunya corak regex dalam rentetan yang diberikan . Sekiranya terdapat banyak kejadian dalam rentetan, maka panggilan pertama untuk mencari () akan melompat ke kejadian pertama. Selepas itu, setiap kaedah panggilan seterusnya untuk mencari () akan pergi ke kejadian pencocokan seterusnya, satu demi satu.

Bayangkan kita mahu mencari rentetan yang disediakan "selamat tinggal 2019 dan selamat datang 2020" untuk nombor empat digit sahaja.

Untuk ini kita akan menggunakan corak "\\ d \\ d \\ d \\ d" :

@Test public void whenFindFourDigitWorks_thenCorrect() { Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d"); Matcher m = stringPattern.matcher("goodbye 2019 and welcome 2020"); assertTrue(m.find()); assertEquals(8, m.start()); assertEquals("2019", m.group()); assertEquals(12, m.end()); assertTrue(m.find()); assertEquals(25, m.start()); assertEquals("2020", m.group()); assertEquals(29, m.end()); assertFalse(m.find()); }

Oleh kerana kita mempunyai dua kejadian dalam contoh ini - 2019 dan 2020 - kaedah find () akan kembali benar dua kali, dan setelah mencapai akhir kawasan pertandingan, itu akan kembali salah .

Sebaik sahaja kami menemui perlawanan, kami kemudian dapat menggunakan kaedah seperti permulaan () , kumpulan () , dan akhir () untuk mendapatkan lebih banyak perincian mengenai pertandingan , seperti yang ditunjukkan di atas.

Kaedah permulaan () akan memberikan indeks permulaan perlawanan, akhir () akan mengembalikan indeks terakhir watak setelah tamat perlawanan, dan kumpulan () akan mengembalikan nilai sebenar pertandingan .

3. find (int) Menghubungi

Kami juga mempunyai versi kaedah mencari yang berlebihan - cari (int) . Ia mengambil indeks permulaan sebagai parameter dan menganggap indeks permulaan sebagai titik permulaan untuk mencari kejadian dalam rentetan .

Mari lihat bagaimana menggunakan kaedah ini dalam contoh yang sama seperti sebelumnya:

@Test public void givenStartIndex_whenFindFourDigitWorks_thenCorrect() { Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d"); Matcher m = stringPattern.matcher("goodbye 2019 and welcome 2020"); assertTrue(m.find(20)); assertEquals(25, m.start()); assertEquals("2020", m.group()); assertEquals(29, m.end()); }

Oleh kerana kami telah menyediakan indeks permulaan 20 , kita dapat melihat bahawa sekarang hanya ada satu kejadian yang dijumpai - 2020, yang terjadi seperti yang diharapkan setelah indeks ini . Dan, seperti yang berlaku dengan find () , kita dapat menggunakan kaedah seperti start () , group () , dan end () untuk mengekstrak lebih banyak perincian mengenai pertandingan.

4. perlawanan () Menghubungi

Sebaliknya, yang dijumpai () kaedah cuba untuk perlawanan keseluruhan rentetan terhadap pola .

Untuk contoh yang sama, padanan () akan kembali palsu :

@Test public void whenMatchFourDigitWorks_thenFail() { Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d"); Matcher m = stringPattern.matcher("goodbye 2019 and welcome 2020"); assertFalse(m.matches()); } 

Ini kerana ia akan mencocokkan "\\ d \\ d \\ d \\ d" dengan keseluruhan rentetan " selamat tinggal 2019 dan selamat datang 2020" - tidak seperti kaedah find () dan find (int) , keduanya akan cari berlakunya corak di mana sahaja dalam rentetan .

Sekiranya kita menukar rentetan ke nombor empat digit "2019" , maka padanan () akan kembali benar :

@Test public void whenMatchFourDigitWorks_thenCorrect() { Pattern stringPattern = Pattern.compile("\\d\\d\\d\\d"); Matcher m = stringPattern.matcher("2019"); assertTrue(m.matches()); assertEquals(0, m.start()); assertEquals("2019", m.group()); assertEquals(4, m.end()); assertTrue(m.matches()); }

Seperti yang ditunjukkan di atas, kita juga dapat menggunakan kaedah seperti permulaan () , kumpulan () , dan akhir () untuk mengumpulkan lebih banyak perincian mengenai pertandingan. Satu perkara yang menarik untuk diperhatikan ialah panggilan mencari () berkali-kali dapat menghasilkan output yang berbeza setelah memanggil kaedah ini, seperti yang kita lihat dalam contoh pertama kita, tetapi padanan () akan selalu mengembalikan nilai yang sama.

5. Kesimpulan

Dalam artikel ini, kita telah melihat bagaimana mencari () , mencari (int) , dan padanan () berbeza antara satu sama lain dengan contoh praktikal. Kami juga telah melihat bagaimana pelbagai kaedah seperti permulaan () , kumpulan () dan akhir () dapat membantu kami mengekstrak lebih banyak perincian mengenai pertandingan tertentu .

Seperti biasa, kod sumber penuh artikel terdapat di GitHub.