Teste se uma string contém alguma das strings de uma matriz


153

Como testar uma string para ver se ela contém alguma das strings de uma matriz?

Ao invés de usar

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

4
Você está perguntando se uma string é igual a qualquer uma das strings da matriz ou contém alguma das strings da matriz?
Natix

1
Deseja verificar se alguma string da matriz é uma substring da sua string de entrada? Ou você deseja verificar se sua sequência de entrada é igual a uma sequência na matriz? Você pode ser mais preciso?
Savino Sguera

1
contém, para que ele leva uma linha e vê se ele contém qualquer uma das palavras de uma lista (armazenado como uma matriz de strings)
arowell

Respostas:


188

EDIT: Aqui está uma atualização usando o Java 8 Streaming API. Muito mais limpo. Ainda pode ser combinado com expressões regulares também.

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

Além disso, se alterarmos o tipo de entrada para uma lista em vez de uma matriz, podemos usar items.parallelStream().anyMatch(inputStr::contains).

Você também pode usar .filter(inputStr::contains).findAny()se desejar retornar a sequência correspondente.


Resposta original ligeiramente datada:

Aqui está um método estático (MUITO BÁSICO). Observe que diferencia maiúsculas de minúsculas nas seqüências de comparação. Uma maneira primitiva de diferenciar maiúsculas de minúsculas seria chamar toLowerCase()ou toUpperCase()nas cadeias de entrada e de teste.

Se você precisar fazer algo mais complicado do que isso, recomendo examinar as classes Pattern e Matcher e aprender a fazer algumas expressões regulares. Depois de entender essas, você pode usar essas classes ou o String.matches()método auxiliar.

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
Como usá-lo com expressão regular @gnomed
Praneeth

Como podemos diferenciar o primeiro caso de implementação?
thanos.a

As implementações já diferenciam maiúsculas de minúsculas. Também tenho instruções sobre como torná-lo sem distinção entre maiúsculas e minúsculas nos parágrafos inferiores da resposta.
gnomed

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

Utilitários de String

Usar:

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

Ele retornará o índice da sequência encontrada ou -1 se nenhuma for encontrada.


7
JFI: Eu esperava que essa implementação repetisse apenas uma vez sobre o inputString, mas observei o código no StringUtils e, infelizmente, ele está apenas fazendo N chamadas do indexOf padrão.
Alfonx

Talvez no commons3 a implementação seja melhor!
Renanleandrof 17/11/2015

1
Não, ainda apenas itera sobre as Strings em org.apache.commons.lang3.StringUtils: for (int i = 0; i <searchStrs.length; i ++) {CharSequenceUtils.indexOf (str, search, 0); ....
alfonx

Isso não retorna o índice da sequência encontrada (da matriz), apenas o índice da posição em que a sequência foi encontrada.
Plutão


16

A maneira mais fácil provavelmente seria converter a matriz em um java.util.ArrayList. Uma vez em uma lista de matrizes, você pode facilmente aproveitar o método contains.

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

70
Isto está incorreto. OP está perguntando se stringcontém algum Strings na matriz, não se houver algum Strings na matriz string.
Beau Grantham

3
@BeauGrantham Eu também estava pensando nisso, mas o OP está usando .equals()no post deles, o que é muito confuso. Eu acho que eles precisam editar sua pergunta
gnomed

@BeauGrantham Cara, eu não podia jurar que entendi o problema. Talvez a questão precise ser esclarecida um pouco mais?
Roy Kachouh

1
Não, esse tipo de direção inversa não funcionará; verifique se String contém UM dos valores fornecidos e NOT se os valores fornecidos contêm a string.
Vladimir Stazhilov 18/08/16

2
A questão é o oposto #
Stéphane GRILLON 7/16/16

16

Se você usa o Java 8 ou superior, pode confiar na API Stream para fazer isso:

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

Supondo que você tenha uma grande variedade de coisas grandes Stringpara testar, você também pode iniciar a pesquisa em paralelo chamando parallel(), o código seria:

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

Uma coisa estranha que eu notei, eu tenho dois itens na lista String, eu descobri, quando eu uso 'paralelo', ele não retornará os resultados corretos. (mesmo que contenha o valor).
CharlesC

@ Charles.C é estranho, não consigo reproduzir do meu lado.
Nicolas Filotto

Eu tenho certeza que paralelizar o fluxo seria abaixo do ideal aqui, a menos que a string de entrada fosse longa (~ 500 caracteres). Em vez disso, se a matriz fosse grande, provavelmente seria melhor particionar a matriz e executar cada uma delas em paralelo.
lifesoordinary

2

Aqui está uma solução:

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

Uma abordagem mais groovyesque seria usar injetar em combinação com metaClass :

Eu adoraria dizer:

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

E o método seria:

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

Se você precisar que o containsAny esteja presente para qualquer variável String futura, adicione o método à classe em vez do objeto:

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


0

E se você estiver procurando por correspondência sem distinção entre maiúsculas e minúsculas, use o padrão

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

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

}

0

Se você busca palavras inteiras, pode fazer isso que não diferencia maiúsculas de minúsculas .

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

Também podemos fazer assim:

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

O abaixo deve funcionar para você, assumindo que Strings é a matriz em que você está pesquisando:

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

onde mykeytosearch é a sequência que você deseja testar quanto à existência na matriz. mysearchComparator - é um comparador que seria usado para comparar strings.

Consulte Arrays.binarySearch para obter mais informações.


2
Deve-se notar que o binarySearch funciona apenas em uma matriz classificada naturalmente ou pelo comparador fornecido (se for fornecido).
Natix

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.