In Java, how do I check if a string contains a substring (ignoring case)? [duplicate]
I have two String
s, str1
and str2
. How do I check i开发者_如何转开发f str2
is contained within str1
, ignoring case?
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.
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 ) {
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.
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
精彩评论