Uji apakah string berisi string dari array

153

Bagaimana cara menguji string untuk melihat apakah string berisi salah satu string dari array?

Alih-alih menggunakan

if (string.contains(item1) || string.contains(item2) || string.contains(item3))
arowell
sumber
4
Apakah Anda bertanya apakah string sama dengan salah satu string dalam array, atau berisi string apa pun dari dalam array?
Natix
1
Anda ingin memeriksa apakah ada string dari array yang merupakan substring dari string input Anda? Atau Anda ingin memeriksa apakah string input Anda sama dengan salah satu string dalam array? Bisakah Anda lebih tepat?
Savino Sguera
1
mengandung, sehingga dibutuhkan garis dan melihat apakah mengandung salah satu kata dari daftar (disimpan sebagai array string)
arowell

Jawaban:

188

EDIT: Ini adalah pembaruan menggunakan Java 8 Streaming API. Jauh lebih bersih. Masih bisa dikombinasikan dengan ekspresi reguler juga.

public static boolean stringContainsItemFromList(String inputStr, String[] items) {
    return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
}

Juga, jika kita mengubah tipe input ke Daftar, bukan array yang bisa kita gunakan items.parallelStream().anyMatch(inputStr::contains).

Anda juga dapat menggunakan .filter(inputStr::contains).findAny()jika Anda ingin mengembalikan string yang cocok.


Jawaban asli yang sedikit bertanggal:

Berikut adalah metode statis (SANGAT DASAR). Perhatikan bahwa case sensitif pada string perbandingan. Cara primitif untuk membuatnya case sensitive adalah dengan memanggil toLowerCase()atau toUpperCase()pada kedua input dan string tes.

Jika Anda perlu melakukan sesuatu yang lebih rumit dari ini, saya akan merekomendasikan melihat kelas Pattern and Matcher dan belajar bagaimana melakukan beberapa ekspresi reguler. Setelah Anda memahami itu, Anda bisa menggunakan kelas-kelas itu atau String.matches()metode helper.

public static boolean stringContainsItemFromList(String inputStr, String[] items)
{
    for(int i =0; i < items.length; i++)
    {
        if(inputStr.contains(items[i]))
        {
            return true;
        }
    }
    return false;
}
gnomed
sumber
1
Cara menggunakannya dengan ekspresi reguler @gnomed
Praneeth
Bagaimana kita bisa membuat kasus implementasi pertama menjadi sensitif?
thanos.a
Implementasinya sudah peka terhadap huruf besar-kecil. Saya juga memiliki instruksi bagaimana membuatnya case-sensitive dalam paragraf bawah dari jawaban.
Dibelalai
52
import org.apache.commons.lang.StringUtils;

Utilitas Tali

Menggunakan:

StringUtils.indexOfAny(inputString, new String[]{item1, item2, item3})

Ini akan mengembalikan indeks dari string yang ditemukan atau -1 jika tidak ada yang ditemukan.

renanleandrof
sumber
7
JFI: Saya berharap implementasi ini untuk beralih hanya sekali atas inputString, tapi saya melihat kode di StringUtils, dan sayangnya itu hanya melakukan panggilan N dari indexOf default.
alfonx
Mungkin pada commons3 implementasinya lebih baik!
renanleandrof
1
Tidak, masih hanya mengulangi Strings di org.apache.commons.lang3.StringUtils: for (int i = 0; i <searchStrs.length; i ++) {CharSequenceUtils.indexOf (str, search, 0); ....
alfonx
Ini tidak mengembalikan indeks string yang ditemukan (dari array), hanya indeks posisi string yang ditemukan.
Pluto
33

Anda dapat menggunakan metode String # cocok seperti ini:

System.out.printf("Matches - [%s]%n", string.matches("^.*?(item1|item2|item3).*$"));
anubhava
sumber
16

Cara termudah mungkin adalah dengan mengubah array menjadi java.util.ArrayList. Setelah berada dalam daftar array, Anda dapat dengan mudah memanfaatkan metode berisi.

public static boolean bagOfWords(String str)
{
    String[] words = {"word1", "word2", "word3", "word4", "word5"};  
    return (Arrays.asList(words).contains(str));
}
Roy Kachouh
sumber
70
Ini salah. OP bertanya apakah stringberisi Strings dalam array, bukan jika ada Stringdalam array string.
Beau Grantham
3
@BeauGrantham Saya juga memikirkan hal ini, tetapi OP menggunakan .equals()pos mereka, yang sangat membingungkan. Saya rasa mereka perlu mengedit pertanyaan mereka
gnomed
@BeauGrantham Man aku tidak bisa bersumpah aku mengerti masalahnya. Mungkin pertanyaannya perlu diklarifikasi sedikit lagi?
Roy Kachouh
1
Tidak, jenis arah terbalik ini tidak akan berfungsi, Anda harus memeriksa apakah String berisi SATU dari nilai yang diberikan dan BUKAN jika nilai memberi mengandung string.
Vladimir Stazhilov
2
Pertanyaannya adalah sebaliknya
Stéphane GRILLON
16

Jika Anda menggunakan Java 8 atau lebih tinggi, Anda bisa mengandalkan Stream API untuk melakukan hal seperti itu:

public static boolean containsItemFromArray(String inputString, String[] items) {
    // Convert the array of String items as a Stream
    // For each element of the Stream call inputString.contains(element)
    // If you have any match returns true, false otherwise
    return Arrays.stream(items).anyMatch(inputString::contains);
}

Dengan asumsi bahwa Anda memiliki array besar Stringuntuk menguji Anda juga bisa meluncurkan pencarian secara paralel dengan menelepon parallel(), kode itu kemudian menjadi:

return Arrays.stream(items).parallel().anyMatch(inputString::contains); 
Nicolas Filotto
sumber
Satu hal aneh yang saya perhatikan, saya memiliki dua item dalam daftar String, saya tahu, ketika saya menggunakan 'paralel' itu tidak akan mengembalikan hasil yang benar. (bahkan jika itu mengandung nilai).
CharlesC
@ Charles.C itu aneh aku tidak bisa mereproduksi di sisiku.
Nicolas Filotto
Saya cukup yakin memparalelkan aliran akan menjadi suboptimal di sini kecuali string input panjang (~ 500 karakter). Alih-alih jika array berukuran besar, mungkin akan lebih baik untuk mempartisi array dan menjalankan masing-masing secara paralel.
Lifesoordinary
2

Berikut ini satu solusinya:

public static boolean containsAny(String str, String[] words)
{
   boolean bResult=false; // will be set, if any of the words are found
   //String[] words = {"word1", "word2", "word3", "word4", "word5"};

   List<String> list = Arrays.asList(words);
   for (String word: list ) {
       boolean bFound = str.contains(word);
       if (bFound) {bResult=bFound; break;}
   }
   return bResult;
}
serup
sumber
2

Sejak versi 3.4 Apache umum Lang 3 melaksanakan containsAny metode.

Arthur Vaïsse
sumber
Itu memeriksa array Char
Saikat
1

Pendekatan yang lebih groovyesque adalah menggunakan suntikan dalam kombinasi dengan metaClass :

Saya ingin mengatakan:

String myInput="This string is FORBIDDEN"
myInput.containsAny(["FORBIDDEN","NOT_ALLOWED"]) //=>true

Dan metodenya adalah:

myInput.metaClass.containsAny={List<String> notAllowedTerms->
   notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}

Jika Anda membutuhkan Containny untuk hadir untuk variabel String di masa mendatang, tambahkan metode ke kelas, bukan objek:

String.metaClass.containsAny={notAllowedTerms->
   notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}
Ivan Arrizabalaga
sumber
1

Coba ini:

if (Arrays.asList(item1, item2, item3).stream().anyMatch(string::contains))
Óscar López
sumber
15
Pertanyaannya sebaliknya: Apakah string target berisi salah satu string daftar.
Basil Bourque
1
Pertanyaannya adalah sebaliknya
Stéphane GRILLON
0

Dan jika Anda mencari kecocokan huruf besar-kecil, gunakan pola

Pattern pattern = Pattern.compile("\\bitem1 |item2\\b",java.util.regex.Pattern.CASE_INSENSITIVE);

    Matcher matcher = pattern.matcher(input);
    if(matcher.find() ){ 

}
vsingh
sumber
0

Jika Anda seraching untuk seluruh kata Anda dapat melakukan ini yang bekerja case- sensitive .

private boolean containsKeyword(String line, String[] keywords)
{
    String[] inputWords = line.split(" ");

    for (String inputWord : inputWords)
    {
        for (String keyword : keywords)
        {
            if (inputWord.equalsIgnoreCase(keyword))
            {
                return true;
            }
        }
    }

    return false;
}
thanos.a
sumber
0

Kita juga bisa melakukan ini:

if (string.matches("^.*?((?i)item1|item2|item3).*$"))
(?i): used for case insensitive
.*? & .*$: used for checking whether it is present anywhere in between the string.
Chandan Kolambe
sumber
-3

Di bawah ini akan berfungsi untuk Anda dengan asumsi Strings adalah array yang Anda cari di dalam:

Arrays.binarySearch(Strings,"mykeytosearch",mysearchComparator);

di mana mykeytosearch adalah string yang ingin Anda uji keberadaannya dalam array. mysearchComparator - adalah pembanding yang akan digunakan untuk membandingkan string.

Lihat Arrays.binarySearch untuk informasi lebih lanjut.

Prahalad Deshpande
sumber
2
Perlu dicatat bahwa binarySearch hanya berfungsi pada array yang diurutkan, baik secara alami atau oleh pembanding yang diberikan (jika itu diberikan).
Natix
-4
if (Arrays.asList(array).contains(string))
Garrett Hall
sumber
10
Pertanyaannya sebaliknya: Apakah string target berisi salah satu string daftar.
Basil Bourque
2
Pertanyaannya adalah sebaliknya
Stéphane GRILLON