Explain Codes LogoExplain Codes Logo

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

java
string-manipulation
regex
performance
Anton ShumikhinbyAnton Shumikhin·Aug 19, 2024
TLDR

To check a string for a substring without considering case, use the toLowerCase() method on both strings in combination with contains():

String str = "Java Programming"; boolean found = str.toLowerCase().contains("java"); // Modesty beats loudness: found is now true

Why uppercase can be a safer bet

However, one should favor toUpperCase() over toLowerCase(), as in some languages the translation from uppercase to lowercase has multiple variants for the same letter:

String str = "Java Programming"; boolean found = str.toUpperCase().contains("PROGRAMMING".toUpperCase()); // The louder the better: 'found' still holds the truth.

Regular Expression for more flexibility

If there's a need for more adaptability, Regular expressions allow us to find substrings case-insensitively flexibly:

String str = "Java Programming"; boolean found = Pattern.compile(Pattern.quote("programming"), Pattern.CASE_INSENSITIVE).matcher(str).find(); // The ninja way of finding substrings: 'found' is true

Be smart with Apache Commons Lang

Apache Commons Lang, an open-source utility library, offers a set of useful string operations including the method StringUtils.containsIgnoreCase():

String str = "Java Programming"; boolean found = StringUtils.containsIgnoreCase(str, "java"); // Rockstar way of doing things: found is true

Customize comparison logic for the win

For cases when you don't want to depend on external libraries, you could implement a custom method with careful handling for null values:

public static boolean containsIgnoreCase(String str, String substr) { return str != null && substr != null && str.toUpperCase().contains(substr.toUpperCase()); }

Performance does matter

When dealing with huge Strings, performance could be a concern. Be mindful about using toLowerCase() or toUpperCase() with contains() and indexOf() while performing case-insensitive check.

Edge cases are often ignored

Avoid errors due to unexpected circumstances like a shorter substring length than the string or null values when matching strings character-by-character.

Reusability for future flexibility

Encapsulate frequent use cases in reusable methods, promotes future code flexibility and maintenance.

Respecting null values enhances robustness

A well-behaved method takes care of null inputs to prevent any uncalled for NullPointerExceptions:

public static boolean containsIgnoreCase(String str, String substr) { if (str == null || substr == null) { return false; } return str.toUpperCase().contains(substr.toUpperCase()); }

Going literal with regex for efficiency

When working with regex, go for Pattern.CASE_INSENSITIVE + Pattern.LITERAL for efficient matching:

String str = "Java Programming"; boolean found = Pattern.compile(Pattern.quote("programming"), Pattern.CASE_INSENSITIVE + Pattern.LITERAL).matcher(str).find(); // This is Sparta: found is true

Right tool for the right job

Sometimes, a contains() might seem like an easy bet, but a specific case might demand the use of startsWith() or endsWith() for precise execution:

String str = "Java Programming"; boolean startsWithJava = str.toLowerCase().startsWith("java".toLowerCase()); // Heard of premature optimization? startsWithJava is true boolean endsWithProgramming = str.toLowerCase().endsWith("programming".toLowerCase()); // Postmature optimization anyone? endsWithProgramming is true