文字列に配列の文字列が含まれているかどうかをテストする


153

文字列をテストして、配列の文字列が含まれているかどうかを確認するにはどうすればよいですか?

使用する代わりに

if (string.contains(item1) || string.contains(item2) || string.contains(item3))

4
文字列が配列内の文字列のいずれかに等しいか、または配列内の文字列のいずれかが含まれているかどうかを尋ねていますか?
Natix

1
配列の文字列が入力文字列の部分文字列であるかどうかを確認したいですか?または、入力文字列配列内の文字列の1つと等しいかどうかを確認したいですか?もっと正確にできますか?
Savino Sguera、2012年

1
それは行を取るように、含まれており、それは、(文字列の配列として格納されている)リストから単語のいずれかが含まれている場合に見
arowell

回答:


188

編集:Java 8ストリーミングAPIを使用したアップデートです。とてもきれい。正規表現と組み合わせることもできます。

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

また、入力タイプを配列ではなくリストに変更すると、を使用できますitems.parallelStream().anyMatch(inputStr::contains)

.filter(inputStr::contains).findAny()一致する文字列を返したい場合にも使用できます。


元のわずかに日付の付いた回答:

これは(非常に基本的な)静的メソッドです。比較文字列では大文字と小文字が区別されることに注意してください。原始それケース小文字を区別しないを作るための方法は、呼び出すことであろうtoLowerCase()か、toUpperCase()両方の入力およびテスト文字列に。

あなたはこれ以上複雑何もする必要がある場合は、私が見て推薦するパターンMatcherのクラスといくつかの正規表現を行う方法を学びます。それらを理解したら、それらのクラスまたはString.matches()ヘルパーメソッドを使用できます。

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
正規表現@gnomedでの使用方法
Praneeth

最初の実装で大文字と小文字を区別するにはどうすればよいですか?
thanos.a

実装ではすでに大文字と小文字が区別されます。また、回答の最後の段落で大文字と小文字を区別しないようにする方法についても説明しています。
無視

52
import org.apache.commons.lang.StringUtils;

文字列ユーティリティ

使用する:

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

見つかった文字列のインデックスを返すか、見つからない場合は-1を返します。


7
JFI:この実装がinputStringに対して1回だけ繰り返されることを望みましたが、StringUtilsのコードを調べたところ、残念ながら、デフォルトのindexOfのN回の呼び出しを行っています。
alfonx 2015

たぶんcommons3では実装の方がいいです!
renanleandrof 2015年

1
いいえ、まだorg.apache.commons.lang3.StringUtilsの文字列を反復処理します:for(int i = 0; i <searchStrs.length; i ++){CharSequenceUtils.indexOf(str、search、0); ....
alfonx 2015年

これは、見つかった文字列のインデックスを(配列から)返しません。文字列が見つかった位置のインデックスのみを返します。
冥王星


16

最も簡単な方法は、おそらく配列をjava.util.ArrayListに変換することです。それがarraylistに含まれると、containsメソッドを簡単に活用できます。

public static boolean bagOfWords(String str)
{
    String[] words = {"word1", "word2", "word3", "word4", "word5"};  
    return (Arrays.asList(words).contains(str));
}

69
これは誤りです。OPは、配列のにが含まれているかどうかではなく、配列にstringが含まれているかどうかを尋ねています。StringStringstring
Beau Grantham 2012年

3
@BeauGrantham私もこれを考えていましたが、OPが.equals()投稿で使用しているため、非常に混乱しています。彼らは質問を編集する必要があると思います
2012年

@BeauGrantham Man私は問題を理解したと誓うことができませんでした。たぶん、質問をもう少し明確にする必要がありますか?
Roy Kachouh、2012年

1
いいえ、この種の逆方向は機能しません。文字列に指定された値のいずれかが含まれているかどうかを確認し、値に文字列が含まれているかどうかを確認する必要があります。
Vladimir Stazhilov

2
質問は反対である
ステファン・グリオン

16

Java 8以降を使用している場合は、Stream API使用してそのようなことを行うことができます。

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

Stringテストするbigの大きな配列があるとすると、を呼び出して検索を並行して起動することもできるとするとparallel()、コードは次のようになります。

return Arrays.stream(items).parallel().anyMatch(inputString::contains); 

私が気付いた奇妙なことの1つは、「文字列」リストに2つの項目があることです。「並列」を使用すると、正しい結果が返されません。(値が含まれている場合でも)。
CharlesC

@ Charles.C奇妙なことに、自分の側では再現できません。
Nicolas Filotto

入力文字列が長い(約500文字)でない限り、ストリームの並列化はここでは最適とは言えません。代わりに、配列が大きい場合は、配列を分割して、それぞれを並列に実行する方が良いでしょう。
臨時の

2

ここに1つの解決策があります:

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

よりグルーヴィーなアプローチは、metaClassと組み合わせてinjectを使用することです

私は言いたいと思います:

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

そして、方法は次のようになります:

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

containsAnyを将来のString変数に含める必要がある場合は、オブジェクトではなくメソッドをクラスに追加します。

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


0

大文字と小文字を区別しない一致を探している場合は、パターンを使用します

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

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

}

0

単語全体 を検索する場合は、大文字と小文字を区別せずにこれを行うことができます。

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

次のようにすることもできます:

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

以下は、文字列が検索対象の配列であると想定して機能するはずです。

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

mykeytosearchは、配列内に存在するかどうかをテストする文字列です。mysearchComparator-文字列を比較するために使用されるコンパレータです。

詳細については、Arrays.binarySearchを参照してください。


2
binarySearchは、自然に、または指定されたコンパレーター(指定されている場合)によってソートされた配列でのみ機能することに注意してください。
Natix

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.