How to Check If a String Contains Another String in a Case Insensitive Manner in Java?
Say I Have Two Strings, String S1 = "Abbacca"; String S2 = "Bac"; I Want to Perform a Check Returning That S2 Is Contained Within S1. I Can Do This with...
Say I have two strings,
String s1 = "AbBaCca";
String s2 = "bac";
I want to perform a check returning that s2 is contained within s1. I can do this with:
return s1.contains(s2);
I am pretty sure that contains() is case sensitive, however I can't determine this for sure from reading the documentation. If it is then I suppose my best method would be something like:
return s1.toLowerCase().contains(s2.toLowerCase());
All this aside, is there another (possibly better) way to accomplish this without caring about case-sensitivity?
19 Answers
Yes, contains is case sensitive. You can use java.util.regex.Pattern with the CASE_INSENSITIVE flag for case insensitive matching:
Pattern.compile(Pattern.quote(wantedStr), Pattern.CASE_INSENSITIVE).matcher(source).find();
EDIT: If s2 contains regex special characters (of which there are many) it's important to quote it first. I've corrected my answer since it is the first one people will see, but vote up Matt Quail's since he pointed this out.
One problem with the answer by Dave L. is when s2 contains regex markup such as \d, etc.
You want to call Pattern.quote() on s2:
Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(s1).find();
You can use
org.apache.commons.lang3.StringUtils.containsIgnoreCase("AbBaCca", "bac");
The Apache Commons library is very useful for this sort of thing. And this particular one may be better than regular expressions as regex is always expensive in terms of performance.
Must Read
A Faster Implementation: Utilizing String.regionMatches()
Using regexp can be relatively slow. It (being slow) doesn't matter if you just want to check in one case. But if you have an array or a collection of thousands or hundreds of thousands of strings, things can get pretty slow.
The presented solution below doesn't use regular expressions nor toLowerCase() (which is also slow because it creates another strings and just throws them away after the check).
The solution builds on the String.regionMatches() method which seems to be unknown. It checks if 2 String regions match, but what's important is that it also has an overload with a handy ignoreCase parameter.
public static boolean containsIgnoreCase(String src, String what) {
final int length = what.length();
if (length == 0)
return true; // Empty string is contained
final char firstLo = Character.toLowerCase(what.charAt(0));
final char firstUp = Character.toUpperCase(what.charAt(0));
for (int i = src.length() - length; i >= 0; i--) {
// Quick check before calling the more expensive regionMatches() method:
final char ch = src.charAt(i);
if (ch != firstLo && ch != firstUp)
continue;
if (src.regionMatches(true, i, what, 0, length))
return true;
}
return false;
}