2010-02-16 13 views
432

Tengo dos String s, str1 y str2. ¿Cómo puedo verificar si str2 está dentro de str1, ignorando el estuche?En Java, ¿cómo puedo verificar si una cadena contiene una subcadena (ignorando el caso)?

+1

Tanto indexOf como contains van carácter por carácter, por lo que si necesita una búsqueda más rápida de cadenas (que puede obtener), entonces tendría que implementar uno de muchos algoritmos publicados. –

+2

Tengo la misma pregunta aquí es la respuesta :) http: // stackoverflow.com/a/86832/621951 –

Respuesta

878
str1.toLowerCase().contains(str2.toLowerCase()) 
+4

por alguna razón me estoy poniendo falso cuando llamo "2014-03-25T17: 55: 00" .contains ("T") –

+3

¿Hay función que devuelve y posición donde se produce que contiene (str2)? – RadijatoR

+6

@RadijatoR sí, se llama indexOf, como 'int pos = str1.indexOf (str2)' o insensible a mayúsculas como 'int pos = str1.toLowerCase(). IndexOf (str2.toLowerCase())' –

20

Puede utilizar el método toLowerCase():

public boolean contains(String haystack, String needle) { 
    haystack = haystack == null ? "" : haystack; 
    needle = needle == null ? "" : needle; 

    // Works, but is not the best. 
    //return haystack.toLowerCase().indexOf(needle.toLowerCase()) > -1 

    return haystack.toLowerCase().contains(needle.toLowerCase()) 
} 

Entonces llaman usando:

if(contains(str1, str2)) { 
    System.out.println("Found " + str2 + " within " + str1 + "."); 
} 

en cuenta que mediante la creación de su propio método, se puede reutilizar. Luego, cuando alguien le indique que debe usar contains en lugar de indexOf, solo tiene una línea de código para cambiar.

+5

Recuerde agregar Javadoc sobre el comportamiento al pasar objetos nulos. –

+0

Ayudas a la solución :) – akash89

6

que haría uso de una combinación del método contains y el método toUpper que forman parte de la clase String. Un ejemplo es el siguiente:

String string1 = "AAABBBCCC"; 
String string2 = "DDDEEEFFF"; 
String searchForThis = "AABB"; 

System.out.println("Search1="+string1.toUpperCase().contains(searchForThis.toUpperCase())); 

System.out.println("Search2="+string2.toUpperCase().contains(searchForThis.toUpperCase())); 

Esto devolverá:

Search1 = true
Search2 = false

+4

No funcionará. Algunos caracteres internacionales extraños se convierten en varios caracteres cuando se convierten en mayúsculas/minúsculas. Por ejemplo: '" ß ".toUpperCase(). Equals (" SS ")' – Simon

+1

Eso figuraría. Así es como una doble s está escrita en alemán. –

111

¿Qué tal matches()?

String string = "Madam, I am Adam"; 

// Starts with 
boolean b = string.startsWith("Mad"); // true 

// Ends with 
b = string.endsWith("dam");    // true 

// Anywhere 
b = string.indexOf("I am") >= 0;  // true 

// To ignore case, regular expressions must be used 

// Starts with 
b = string.matches("(?i)mad.*"); 

// Ends with 
b = string.matches("(?i).*adam"); 

// Anywhere 
b = string.matches("(?i).*i am.*"); 
+12

Su ejemplo "indexOf" debería usar> = 0, no> 0, ya que 0 es válido si la subcadena se produce al comienzo de la cadena. (No en su ejemplo, pero podría en otros casos.) Agregué esta respuesta ya que las personas obviamente siguen buscando y encontrando esta respuesta. –

29

Si usted es capaz de utilizar org.apache.commons.lang.StringUtils, se sugiere emplear el siguiente:

String container = "aBcDeFg"; 
String content = "dE"; 
boolean containerContainsContent = StringUtils.containsIgnoreCase(container, content); 
9

también estoy a favor de la solución de expresiones regulares. El código será mucho más limpio. Yo dudaría en usar toLowerCase() en situaciones donde sabía que las cadenas iban a ser grandes, ya que las cadenas son inmutables y tendrían que ser copiadas. Además, la solución de matches() puede ser confusa porque toma una expresión regular como argumento (la búsqueda de "Need $ le" puede ser problemática).

Sobre la base de algunos de los ejemplos anteriores:

public boolean containsIgnoreCase(String haystack, String needle) { 
    if(needle.equals("")) 
    return true; 
    if(haystack == null || needle == null || haystack .equals("")) 
    return false; 

    Pattern p = Pattern.compile(needle,Pattern.CASE_INSENSITIVE+Pattern.LITERAL); 
    Matcher m = p.matcher(haystack); 
    return m.find(); 
} 

example call: 

String needle = "Need$le"; 
String haystack = "This is a haystack that might have a need$le in it."; 
if(containsIgnoreCase(haystack, needle)) { 
    System.out.println("Found " + needle + " within " + haystack + "."); 
} 

(Nota:. Es posible que desee para manejar cadenas NULL y vacíos de forma diferente en función de sus necesidades Creo que como yo tienen que está más cerca de la especificación de Java para cadenas.)

Las soluciones de velocidad crítica podrían incluir iterar a través del carácter de pajar por carácter buscando el primer carácter de la aguja. Cuando el primer personaje coincida (caso insensato), comience a recorrer la aguja carácter por carácter, busque el carácter correspondiente en el pajar y devuelva "verdadero" si todos los caracteres coinciden. Si se encuentra un carácter no coincidente, reanude la iteración a través del pajar en el siguiente carácter, devolviendo "falso" si se alcanza una posición> haystack.length() - needle.length().

+2

Lo haría: 'Pattern.CASE_INSENSITIVE | Pattern.LITERAL' –

+0

@mikejones ¿Cómo puedo comprobar esto solo por palabras? Considere el caso debajo de 1) "Este es un pajar que podría necesitar $ le en él"; 2) "Este es un pajar que podría necesitar $ lesss"; Quiero que coincida solo el caso 1, ya que en ese caso necesita $ le está presente como palabra. No quiero que coincida el segundo caso. ¿Cómo puedo lograr esto? –

Cuestiones relacionadas