测试字符串是否包含数组中的任何字符串


153

如何测试字符串以查看其是否包含数组中的任何字符串?

而不是使用

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

4
您是在问一个字符串是否等于数组中的任何字符串,或者是否包含数组中的任何字符串?
Natix 2012年

1
您想检查数组中的任何字符串是否是您输入字符串的子字符串?还是要检查您的输入字符串是否等于数组中的字符串之一?你能更精确吗?
Savino Sguera

1
包含,因此它需要一行,并查看它是否包含列表中的任何单词(存储为字符串数组)
arowell 2012年

Answers:


187

编辑:这是使用Java 8 Streaming 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()如果希望返回匹配的字符串,也可以使用。


原始的过时的答案:

这是(VERY BASIC)静态方法。请注意,在比较字符串上区分大小写。使它不区分大小写的一种原始方法是在输入和测试字符串上调用toLowerCase()toUpperCase()同时调用。

如果您需要做的事情比这更复杂,我建议您查看一下PatternMatcher类,并学习如何做一些正则表达式。了解这些内容后,就可以使用这些类或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 '18

如何使第一个实现区分大小写?
thanos.a

这些实现已经区分大小写。在答案的底部,我也有说明如何使其不区分大小写。
忽略

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

字符串实用程序

用:

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

它将返回找到的字符串的索引;如果找不到,则返回-1。


7
JFI:我希望该实现只对inputString进行一次迭代,但是我查看了StringUtils中的代码,可悲的是,它只对默认indexOf进行了N次调用。
alfonx

也许在commons3上实现更好!
renanleandrof

1
不,仍然只是遍历org.apache.commons.lang3.StringUtils中的字符串:for(int i = 0; i <searchStrs.length; i ++){CharSequenceUtils.indexOf(str,search,0); ....
alfonx

这不会返回(从数组中)找到的字符串的索引,而只返回找到该字符串的位置的索引。
冥王星


16

最简单的方法可能是将数组转换为java.util.ArrayList。将其放入数组列表后,即可轻松利用contains方法。

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

69
这是不正确的。OP正在询问数组中是否string包含任何String,而不是String数组中是否包含string
博·格兰瑟姆

3
@BeauGrantham我也在想这个,但是OP .equals()在他们的帖子中使用了,这非常令人困惑。我认为他们需要编辑他们的问题
2012年

@BeauGrantham男人我不能发誓我理解这个问题。也许这个问题需要进一步澄清?
罗伊·卡乔

1
不,这种相反的方向不起作用,您应该检查String是否包含给定值之一,如果给出的值包含字符串,则不检查。
弗拉基米尔·斯塔吉洛夫

2
问题是相反
斯特凡Grillon的

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要测试的数组很大,那么您还可以通过调用并行启动搜索parallel(),代码如下:

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

我注意到的一件奇怪的事是,我发现String列表中有两项,当我使用“ parallel”时,它不会返回正确的结果。(即使其中包含该值)。
CharlesC

@ Charles.C这很奇怪,我无法在我这一边进行复制。
尼古拉斯·菲洛托

我非常确定,除非输入字符串很长(〜500个字符),否则并行化流在此处将不是最佳选择。相反,如果数组很大,最好对数组进行分区并并行运行每个数组。
生命普通'18年

2

这是一种解决方案:

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结合使用

我很想说:

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

如果将来任何String变量都需要包含containsAny,则将方法添加到类中而不是对象中:

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


0

如果您要查找不区分大小写的匹配项,请使用pattern

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

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

}

0

如果您seraching为整个 单词,你可以做到这一点,工作的情况下, 不区分大小写

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

假设Strings是您要在其中搜索的数组,那么以下内容将为您工作:

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

其中,mykeytosearch是要测试数组中是否存在的字符串。mysearchComparator-是用于比较字符串的比较器。

有关更多信息,请参考Arrays.binarySearch


2
应当注意,binarySearch仅对自然排序或由给定比较器(如果已给出)进行排序的数组起作用。
Natix 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.