Prueba si una cadena contiene alguna de las cadenas de una matriz

153

¿Cómo pruebo una cadena para ver si contiene alguna de las cadenas de una matriz?

En lugar de usar

if (string.contains(item1) || string.contains(item2) || string.contains(item3))
arowell
fuente
44
¿Pregunta si una cadena es igual a alguna de las cadenas de la matriz o si contiene alguna de las cadenas de la matriz?
Natix
1
¿Desea verificar si alguna cadena de la matriz es una subcadena de su cadena de entrada? ¿O desea verificar si su cadena de entrada es igual a una de la cadena en la matriz? puedes ser mas preciso?
Savino Sguera
1
contiene, para que tome una línea y vea si contiene alguna de las palabras de una lista (almacenada como una serie de cadenas)
arowell

Respuestas:

188

EDITAR: Aquí hay una actualización que usa la API Java 8 Streaming. Mucho más limpio. Todavía se puede combinar con expresiones regulares también.

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

Además, si cambiamos el tipo de entrada a una Lista en lugar de una matriz que podemos usar items.parallelStream().anyMatch(inputStr::contains).

También puede usar .filter(inputStr::contains).findAny()si desea devolver la cadena coincidente.


Respuesta original ligeramente anticuada:

Aquí hay un método estático (MUY BÁSICO). Tenga en cuenta que distingue entre mayúsculas y minúsculas en las cadenas de comparación. Una forma primitiva de hacer que no distinga entre mayúsculas y minúsculas sería llamar toLowerCase()o toUpperCase()en las cadenas de entrada y prueba.

Si necesita hacer algo más complicado que esto, le recomendaría que mire las clases de Patrón y Matcher y aprenda a hacer algunas expresiones regulares. Una vez que los comprenda, puede usar esas clases o el 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;
}
gnomed
fuente
1
Cómo usarlo con expresión regular @gnomed
Praneeth
¿Cómo podemos hacer que la primera implementación distinga entre mayúsculas y minúsculas?
thanos.a
Las implementaciones ya distinguen entre mayúsculas y minúsculas. También tengo instrucciones sobre cómo hacer que no se distinga entre mayúsculas y minúsculas en los párrafos inferiores de la respuesta.
Gnomed
52
import org.apache.commons.lang.StringUtils;

Utilidades de cadena

Utilizar:

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

Devolverá el índice de la cadena encontrada o -1 si no se encuentra ninguno.

renanleandrof
fuente
77
JFI: esperaba que esta implementación iterara solo una vez sobre inputString, pero miré el código en StringUtils, y lamentablemente solo hace N llamadas del indexOf predeterminado.
alfonx
¡Quizás en commons3 la implementación sea mejor!
renanleandrof
1
No, todavía solo itera sobre las cadenas en org.apache.commons.lang3.StringUtils: for (int i = 0; i <searchStrs.length; i ++) {CharSequenceUtils.indexOf (str, search, 0); ....
alfonx
Esto no devuelve el índice de la cadena encontrada (de la matriz), solo el índice de la posición en la que se encontró la cadena.
Plutón
33

Puede usar el método String # coincide de esta manera:

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

La forma más fácil probablemente sería convertir la matriz en java.util.ArrayList. Una vez que se encuentra en una lista de arrays, puede aprovechar fácilmente el método contiene.

public static boolean bagOfWords(String str)
{
    String[] words = {"word1", "word2", "word3", "word4", "word5"};  
    return (Arrays.asList(words).contains(str));
}
Roy Kachouh
fuente
70
Esto es incorrecto. OP pregunta si stringcontiene alguna Strings en la matriz, no si alguna Strings en la matriz contiene string.
Beau Grantham
3
@BeauGrantham También estaba pensando en esto, pero el OP lo está usando .equals()en su publicación, lo cual es muy confuso. Supongo que necesitan editar su pregunta
Recibió el
@BeauGrantham Man No podía jurar que entendía el problema. ¿Quizás la pregunta necesita aclararse un poco más?
Roy Kachouh
1
No, este tipo de dirección inversa no funcionará, debe verificar si String contiene UNO de los valores dados y NO si los valores dados contienen la cadena.
Vladimir Stazhilov
2
La pregunta es lo opuesto
Stéphane GRILLON
16

Si usa Java 8 o superior, puede confiar en Stream API para hacer lo siguiente:

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

Suponiendo que tiene una gran variedad de grandes Stringpara probar, también podría iniciar la búsqueda en paralelo llamando parallel(), el código sería:

return Arrays.stream(items).parallel().anyMatch(inputString::contains); 
Nicolas Filotto
fuente
Una cosa extraña que noté, tengo dos elementos en la lista de cadenas, descubrí que cuando uso 'paralelo' no devolverá los resultados correctos. (incluso si contiene el valor).
CharlesC
@ Charles.C eso es raro, no puedo reproducirlo de mi lado.
Nicolas Filotto
Estoy bastante seguro de que la paralelización de la secuencia sería subóptima aquí a menos que la cadena de entrada sea larga (~ 500 caracteres). En cambio, si la matriz era grande, probablemente sería mejor dividirla y ejecutar cada una de ellas en paralelo.
Lifesoordinary
2

Aquí hay una solución:

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;
}
serup
fuente
2

Desde la versión 3.4, Apache Common Lang 3 implementa el método contiene cualquier .

Arthur Vaïsse
fuente
Eso comprueba la matriz de Char
Saikat
1

Un enfoque más groovyesco sería usar inyectar en combinación con metaClass :

Me encantaría decir:

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

Y el método sería:

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

Si necesita contieneAny para estar presente en cualquier variable de cadena futura, agregue el método a la clase en lugar del objeto:

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

Prueba esto:

if (Arrays.asList(item1, item2, item3).stream().anyMatch(string::contains))
Óscar López
fuente
15
La pregunta es lo contrario: ¿la cadena de destino contiene alguna de las cadenas de la lista?
Basil Bourque
1
La pregunta es lo contrario
Stéphane GRILLON
0

Y si está buscando una coincidencia entre mayúsculas y minúsculas, use el patrón

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

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

}
vsingh
fuente
0

Si está buscando palabras completas , puede hacer esto que no distingue entre mayúsculas y 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;
}
thanos.a
fuente
0

También podemos hacer así:

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

Lo siguiente debería funcionar para usted suponiendo que Strings es la matriz en la que está buscando:

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

donde mykeytosearch es la cadena que desea probar para la existencia dentro de la matriz. mysearchComparator: es un comparador que se usaría para comparar cadenas.

Consulte Arrays.binarySearch para obtener más información.

Prahalad Deshpande
fuente
2
Cabe señalar que binarySearch funciona solo en una matriz que está ordenada, ya sea de forma natural o por el comparador dado (si se proporciona).
Natix
-4
if (Arrays.asList(array).contains(string))
Garrett Hall
fuente
10
La pregunta es lo contrario: ¿la cadena de destino contiene alguna de las cadenas de la lista?
Basil Bourque
2
La pregunta es lo contrario
Stéphane GRILLON