Periksa Jika String Mengandungi Beberapa Kata Kunci di Java

1. Pengenalan

Dalam tutorial ringkas ini, kita akan mengetahui cara mengesan banyak kata di dalam rentetan .

2. Contoh Kita

Katakan kita mempunyai rentetan:

String inputString = "hello there, Baeldung";

Tugas kami adalah untuk mengetahui apakah inputString mengandung kata-kata "hello" dan "Baeldung" .

Oleh itu, mari masukkan kata kunci kami ke dalam larik:

String[] words = {"hello", "Baeldung"};

Lebih-lebih lagi, susunan kata-kata tidak penting, dan padanannya harus peka huruf besar kecil.

3. Menggunakan String.contains ()

Sebagai permulaan, kami akan menunjukkan cara menggunakan kaedah String.contains () untuk mencapai matlamat kami .

Mari kita perhatikan susunan kata kunci dan periksa kejadian setiap item di dalam inputString:

public static boolean containsWords(String inputString, String[] items) { boolean found = true; for (String item : items) { if (!inputString.contains(item)) { found = false; break; } } return found; }

Kaedah mengandung () akan kembali benar jika inputString mengandungi item yang diberikan . Apabila kita tidak mempunyai kata kunci di dalam rentetan kita, kita boleh berhenti bergerak maju dan mengembalikan yang salah langsung .

Walaupun kita perlu menulis lebih banyak kod, penyelesaian ini pantas untuk kes penggunaan yang mudah.

4. Menggunakan String.indexOf ()

Sama dengan penyelesaian yang menggunakan String.contains () kaedah, kita boleh menyemak indeks kata kunci dengan menggunakan String.indexOf () kaedah . Untuk itu, kita memerlukan kaedah untuk menerima inputString dan senarai kata kunci:

public static boolean containsWordsIndexOf(String inputString, String[] words) { boolean found = true; for (String word : words) { if (inputString.indexOf(word) == -1) { found = false; break; } } return found; }

Kaedah indexOf () mengembalikan indeks kata di dalam inputString . Apabila kita tidak mempunyai kata dalam teks, indeks akan menjadi -1.

5. Menggunakan Ungkapan Biasa

Sekarang, mari gunakan ungkapan biasa untuk memadankan kata-kata kita. Untuk itu, kami akan menggunakan kelas Corak .

Pertama, mari tentukan ungkapan rentetan. Oleh kerana kami perlu memadankan dua kata kunci, kami akan membina peraturan regex kami dengan dua kepala pandang:

Pattern pattern = Pattern.compile("(?=.*hello)(?=.*Baeldung)");

Dan untuk kes umum:

StringBuilder regexp = new StringBuilder(); for (String word : words) { regexp.append("(?=.*").append(word).append(")"); }

Selepas itu, kami akan menggunakan kaedah matcher () untuk mencari () kejadian:

public static boolean containsWordsPatternMatch(String inputString, String[] words) { StringBuilder regexp = new StringBuilder(); for (String word : words) { regexp.append("(?=.*").append(word).append(")"); } Pattern pattern = Pattern.compile(regexp.toString()); return pattern.matcher(inputString).find(); }

Tetapi, ungkapan biasa mempunyai kos prestasi. Sekiranya kita mempunyai banyak kata untuk mencari, prestasi penyelesaian ini mungkin tidak optimum.

6. Menggunakan Java 8 dan List

Dan akhirnya, kita dapat menggunakan API Stream Java 8. Tetapi pertama, mari kita lakukan beberapa transformasi kecil dengan data awal kami:

List inputString = Arrays.asList(inputString.split(" ")); List words = Arrays.asList(words);

Sekarang, sudah tiba masanya untuk menggunakan Stream API:

public static boolean containsWordsJava8(String inputString, String[] words) { List inputStringList = Arrays.asList(inputString.split(" ")); List wordsList = Arrays.asList(words); return wordsList.stream().allMatch(inputStringList::contains); }

Saluran operasi di atas akan kembali benar jika rentetan input mengandungi semua kata kunci kami.

Sebagai alternatif, kita hanya boleh menggunakan kaedah mengandungAll () kerangka Koleksi untuk mencapai hasil yang diinginkan:

public static boolean containsWordsArray(String inputString, String[] words) { List inputStringList = Arrays.asList(inputString.split(" ")); List wordsList = Arrays.asList(words); return inputStringList.containsAll(wordsList); }

Walau bagaimanapun, kaedah ini berfungsi untuk keseluruhan perkataan sahaja. Oleh itu, kata kunci kami hanya akan dijumpai jika dipisahkan dengan ruang kosong dalam teks.

7. Menggunakan Algoritma Aho-Corasick

Ringkasnya, algoritma Aho-Corasick adalah untuk pencarian teks dengan pelbagai kata kunci . Ia mempunyai kerumitan waktu O (n) tidak kira berapa banyak kata kunci yang kita cari atau berapa lama panjang teksnya.

Mari sertakan ketergantungan algoritma Aho-Corasick dalam pom.xml kami :

 org.ahocorasick ahocorasick 0.4.0 

Pertama, mari kita membina saluran paip indone dengan kata-kata pelbagai kata kunci. Untuk itu, kami akan menggunakan struktur data Trie:

Trie trie = Trie.builder().onlyWholeWords().addKeywords(words).build();

Selepas itu, mari panggil kaedah penghurai dengan teks inputString di mana kami ingin mencari kata kunci dan menyimpan hasilnya dalam koleksi pancaran :

Collection emits = trie.parseText(inputString);

Dan akhirnya, jika kami mencetak hasil kami:

emits.forEach(System.out::println);

Untuk setiap kata kunci, kita akan melihat kedudukan awal kata kunci dalam teks, kedudukan akhir, dan kata kunci itu sendiri:

0:4=hello 13:20=Baeldung

Akhirnya, mari kita lihat pelaksanaannya yang lengkap:

public static boolean containsWordsAhoCorasick(String inputString, String[] words) { Trie trie = Trie.builder().onlyWholeWords().addKeywords(words).build(); Collection emits = trie.parseText(inputString); emits.forEach(System.out::println); boolean found = true; for(String word : words) { boolean contains = Arrays.toString(emits.toArray()).contains(word); if (!contains) { found = false; break; } } return found; }

Dalam contoh ini, kami hanya mencari keseluruhan perkataan. Jadi, jika kita ingin mencocokkan tidak hanya inputString tetapi "helloBaeldung" juga, kita harus menghapus atribut onlyWholeWords () dari saluran pembangun Trie .

Di samping itu, ingatlah bahawa kami juga membuang unsur pendua dari koleksi emisi , kerana mungkin terdapat banyak padanan untuk kata kunci yang sama.

8. Kesimpulannya

Dalam artikel ini, kami belajar bagaimana mencari beberapa kata kunci dalam rentetan. Selain itu, kami menunjukkan contoh dengan menggunakan JDK inti, dan juga dengan perpustakaan Aho-Corasick .

Seperti biasa, kod lengkap untuk artikel ini terdapat di GitHub.