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

- 30,738
- 21
- 105
- 131

- 10,394
- 15
- 49
- 67
-
1Both indexOf and contains go character by character, so if you need faster string searching (which you can get), then you would need to implement one of many published algorithms. – Stefan Kendall Feb 16 '10 at 17:55
-
2I have the same question here is the answer:) http://stackoverflow.com/a/86832/621951 – Günay Gültekin Apr 08 '13 at 20:19
6 Answers
str1.toUpperCase().contains(str2.toUpperCase())
UPD:
Original answer was using toLowerCase()
method. But as some people correctly noticed, there are some exceptions in Unicode and it's better to use toUpperCase()
. Because:
There are languages knowing more than one lower case variant for one upper case variant.

- 35,450
- 10
- 82
- 113
-
7for some reason I'm getting false when I call "2014-03-25T17:55:00".contains("T") – Jeremy List Mar 25 '14 at 08:45
-
3Is there function that returns and position where is occured that contain (str2) ? – RadijatoR Jun 23 '15 at 12:38
-
6@RadijatoR yes, it's called indexOf, like `int pos = str1.indexOf(str2)` or case insensitive as `int pos = str1.toLowerCase().indexOf(str2.toLowerCase())` – Igor Artamonov Jun 23 '15 at 12:41
-
1Seems to be working now. No idea what happened earlier. Same code. – frostymarvelous Aug 20 '15 at 23:38
-
@frostymarvelous i am having same issue, bug in java... i was trying to match "success" with "Successful".toLowerCase(), would fail, changed it to "ccess" and then it worked. very weird. strangely though, matching "SUCCESS" with "Successful".toUpperCase() also worked – Fonix Jan 08 '16 at 02:44
-
-
@frostymarvelous "Successful" was str 1, so it was `"Successful".toLowerCase().contains("success");` ("Successful" was a variable i got back from a json response from server) – Fonix Jan 10 '16 at 16:06
-
2
-
1
-
This accepted answer is correct in suggesting `contains()`, but it has it backwards with using `toLowerCase()`. Ideally a locale-aware uppercase function should be used; if not possible or not desired, then **toUpperCase()** is preferable for normalizing strings. See https://stackoverflow.com/a/14128850/3665087 – j1elo Oct 15 '21 at 13:42
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.*");

- 379,657
- 97
- 704
- 746

- 2,268
- 3
- 31
- 36
-
15Your "indexOf" example should use >= 0, not > 0, since 0 is valid if the substring occurs at the beginning of the string. (Doesn't in your example, but could in other cases.) Added this response since people are obviously still searching and finding this answer. – Andrew Cottrell Aug 20 '13 at 16:59
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.

- 30,436
- 41
- 178
- 315

- 102,349
- 23
- 137
- 192
-
5Remember to add Javadoc about the behaviour when passing null objects. – Thorbjørn Ravn Andersen Feb 16 '10 at 18:25
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 ) {
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 + "." );
}
(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.

- 101
- 1
- 2
-
2
-
@mikejones How can I check this for only words ? Consider the case below 1) "This is a haystack that might have a need$le in it."; 2) "This is a haystack that might have a need$lesss in it."; I want only case 1 to be matched as in that case need$le is present as a word. I don't want the 2nd case to be matched. How can I achieve this ? – KK_07k11A0585 Jul 06 '15 at 11:02
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";
System.out.println("Search1="+string1.toUpperCase().contains(searchForThis.toUpperCase()));
System.out.println("Search2="+string2.toUpperCase().contains(searchForThis.toUpperCase()));
This will return:
Search1=true
Search2=false
-
5Won't work. Some weird, international characters are converted to multiple characters when converted to lower-/upper-case. For example: `"ß".toUpperCase().equals("SS")` – Simon Apr 05 '13 at 22:36
-
2