ChatGPT解决这个技术问题 Extra ChatGPT

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

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

而不是使用

if (string.contains(item1) || string.contains(item2) || string.contains(item3))
您是在问一个字符串是否等于数组中的任何字符串,或者是否包含数组中的任何字符串?
您想检查数组中的任何字符串是否是输入字符串的子字符串?或者您想检查您的输入字符串是否等于数组中的字符串之一?你能更精确一点吗?
包含,因此它需要一行并查看它是否包含列表中的任何单词(存储为字符串数组)

g
gnomed

编辑:这是使用 Java 8 Streaming API 的更新。干净多了。仍然可以与正则表达式结合使用。

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

此外,如果我们将输入类型更改为 List 而不是数组,我们可以使用 items.stream().anyMatch(inputStr::contains)

如果您希望返回匹配的字符串,也可以使用 .filter(inputStr::contains).findAny()

重要提示:上述代码可以使用 parallelStream() 完成,但大多数情况下这实际上会影响性能。请参阅this question for more details on parallel streaming

原始的稍微过时的答案:

这是一个(非常基本的)静态方法。请注意,比较字符串区分大小写。使其不区分大小写的原始方法是在输入字符串和测试字符串上调用 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;
}

如何使用正则表达式@gnomed
我们如何使第一个实现区分大小写?
这些实现已经区分大小写。我还有关于如何在答案的底部段落中使其不区分大小写的说明。
parallelStream 使用的最小批量大小为 1024,它实际上不会并行化小列表。是脚枪。
@CallumRogers 是的,我有点把它留给人们思考它,但同意绝大多数情况下它与非并行流相比不会产生太大影响(或实际上是有害的)。将尝试在答案中更多地指出这一点。
f
ford prefect
import org.apache.commons.lang.StringUtils;

String Utils

利用:

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

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


JFI:我希望这个实现只对 inputString 进行一次迭代,但我查看了 StringUtils 中的代码,遗憾的是它只是对默认 indexOf 进行了 N 次调用。
也许在 commons3 上实现更好!
不,仍然只是迭代 org.apache.commons.lang3.StringUtils 中的字符串: for (int i = 0; i < searchStrs.length; i++) { CharSequenceUtils.indexOf(str, search, 0); ……
这不返回找到的字符串的索引(从数组中),只返回找到字符串的位置的索引。
a
anubhava

您可以像这样使用 String#matches 方法:

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

N
Nicolas Filotto

如果您使用 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); 

我注意到一件奇怪的事情,我在字符串列表中有两个项目,我发现,当我使用“并行”时,它不会返回正确的结果。 (即使它包含值)。
@Charles.C 这很奇怪,我无法在我身边复制。
我很确定在这里并行化流不是最理想的,除非输入字符串很长(~ 500 个字符)。相反,如果数组很大,最好对数组进行分区并并行运行每个数组。
J
JAN

最简单的方法可能是将数组转换为 java.util.ArrayList。一旦它在一个数组列表中,您就可以轻松地利用 contains 方法。

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

这是不正确的。 OP 询问 string 是否包含数组中的任何 String,而不是数组中的任何 String 是否包含 string
@BeauGrantham 我也在想这个,但是 OP 在他们的帖子中使用了 .equals(),这非常令人困惑。我认为他们需要编辑他们的问题
@BeauGrantham Man 我不能发誓我理解这个问题。也许这个问题需要再澄清一点?
不,这种相反的方向不起作用,您应该检查 String 是否包含给定的值之一,而不是如果给出的值包含字符串。
问题是相反的
s
serup

这是一种解决方案:

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

A
Arthur Vaïsse

自 3.4 版以来,Apache Common Lang 3 实现了 containsAny 方法。


检查 Char 数组
Ó
Óscar López

尝试这个:

if (Arrays.stream(new String[] {item1, item2, item3}).anyMatch(inputStr::contains))

问题是相反的:目标字符串是否包含列表的任何字符串。
stream()anyMatch() 需要 API 级别 24 或更高
@DilankaLaksiri 不是真的,这些方法从 Java 8 开始就可用。最新版本的 Java 是 16,那么你指的是什么“API 级别 24”?
@ÓscarLópez 我说的是 Android API 级别。
好的,很好。但这个问题与 Android 无关 :)
I
Ivan Arrizabalaga

一种更常规的方法是将注入与 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)})
}

C
Chandan Kolambe

我们也可以这样做:

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

我相信用 .* 包装结尾会使 ?$ 变得多余,因为 .* 表示“零个或多个任何字符”(带有一些控制字符警告)
t
thanos.a

如果您正在搜索整个单词,您可以这样做不区分大小写。

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

f
fdermishin

如果您正在寻找不区分大小写的匹配,请使用模式

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

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

H
H.Step

在科特林

if (arrayOf("one", "two", "three").find { "onetw".contains(it) } != null){
            doStuff()
        }

不确定以与 9 年前要求的语言不同的语言添加格式错误的答案是否合适。
P
Prahalad Deshpande

假设 Strings 是您要在其中搜索的数组,以下内容应该适用于您:

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

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

有关详细信息,请参阅 Arrays.binarySearch


应该注意的是,binarySearch 仅适用于自然排序或通过给定比较器(如果已给出)排序的数组。
G
Garrett Hall
if (Arrays.asList(array).contains(string))

问题是相反的:目标字符串是否包含列表的任何字符串。