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

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;
}

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.


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).*$"));

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

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

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;
}


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)})
}


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

}

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;
}

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.

-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.


2
Perlu dicatat bahwa binarySearch hanya berfungsi pada array yang diurutkan, baik secara alami atau oleh pembanding yang diberikan (jika itu diberikan).
Natix

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.