web-dev-qa-db-fra.com

En Java, comment vérifier si une chaîne contient une sous-chaîne (en ignorant la casse)?

J'ai deux Strings, str1 et str2. Comment vérifier si str2 est contenu dans str1, sans tenir compte de la casse?

507
trinity
str1.toLowerCase().contains(str2.toLowerCase())
1008
Igor Artamonov

Que diriez-vous de 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.*");
122
Jim Raynor

Si vous pouvez utiliser org.Apache.commons.lang.StringUtils, je suggère d'utiliser les éléments suivants:

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

Vous pouvez utiliser la méthode 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() )
}

Puis appelez-le en utilisant:

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

Notez qu'en créant votre propre méthode, vous pouvez la réutiliser. Ensuite, lorsque quelqu'un vous indique que vous devez utiliser contains au lieu de indexOf, vous n'avez qu'une seule ligne de code à modifier.

21
Vincent Ramdhanie

Je privilégie également la solution RegEx. Le code sera beaucoup plus propre. J'hésiterais à utiliser toLowerCase () dans les situations où je savais que les chaînes allaient être volumineuses, car celles-ci sont immuables et doivent être copiées. En outre, la solution matches () peut prêter à confusion car elle prend une expression régulière comme argument (la recherche de "Need $ le" est problématique).

S'appuyant sur certains des exemples ci-dessus:

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 + "." );
}

(Remarque: vous voudrez peut-être traiter les chaînes NULL et vides différemment en fonction de vos besoins. Je pense que, de la manière dont je l'ai, il est plus proche de la spécification Java des chaînes.)

Les solutions critiques en termes de vitesse peuvent inclure une itération caractère par caractère à la recherche d'une botte de foin à la recherche du premier caractère de l'aiguille. Lorsque le premier caractère est mis en correspondance (sans tenir compte de la casse), commencez à effectuer une itération aiguille, caractère par caractère, en recherchant le caractère correspondant dans la botte de foin et en renvoyant la valeur "true" si tous les caractères sont mis en correspondance. Si un caractère non apparié est rencontré, reprenez l'itération dans la botte de foin au caractère suivant, en renvoyant "false" si la position> haystack.length () - needle.length () est atteinte.

10
Michael Cooper

J'utiliserais une combinaison de la méthode includes et de la méthode toUpper faisant partie de la classe String. Un exemple est ci-dessous:

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

Cela retournera:

Search1 = true
Search2 = false

7
SOA Nerd