In Java, how do I check if a string contains a substring (ignoring case)?


I have two Strings, str1 and str2. How do I check if str2 is contained within str1, ignoring case?

10/30/2015 4:33:22 PM

Accepted Answer

2/16/2010 5:49:47 PM

How about 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.*");

If you are able to use org.apache.commons.lang.StringUtils, I suggest using the following:

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

You can use the toLowerCase() method:

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

Then call it using:

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

Notice that by creating your own method, you can reuse it. Then, when someone points out that you should use contains instead of indexOf, you have only a single line of code to change.


I also favor the RegEx solution. The code will be much cleaner. I would hesitate to use toLowerCase() in situations where I knew the strings were going to be large, since strings are immutable and would have to be copied. Also, the matches() solution might be confusing because it takes a regular expression as an argument (searching for "Need$le" cold be problematic).

Building on some of the above examples:

public boolean containsIgnoreCase( String haystack, String needle ) {
    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 + "." );

(Note: you might want to handle NULL and empty strings differently depending on your needs. I think they way I have it is closer to the Java spec for strings.)

Speed critical solutions could include iterating through the haystack character by character looking for the first character of the needle. When the first character is matched (case insenstively), begin iterating through the needle character by character, looking for the corresponding character in the haystack and returning "true" if all characters get matched. If a non-matched character is encountered, resume iteration through the haystack at the next character, returning "false" if a position > haystack.length() - needle.length() is reached.


I'd use a combination of the contains method and the toUpper method that are part of the String class. An example is below:

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



This will return: