Case-Insensitive String Matching in Java

1. Overview

There are many ways to check if a String contains a substring. In this article, we’ll be looking for substrings within a String while focusing on case-insensitive workarounds to String.contains() in Java. Most importantly, we’ll provide examples of how to solve this issue.

2. The Simplest Solution: String.toLowerCase

The simplest solution is by using String.toLowerCase(). In this case, we’ll transform both strings to lowercase and then use the contains() method:

assertTrue(src.toLowerCase().contains(dest.toLowerCase()));

We can also use String.toUpperCase() and it would provide the same result.

3. String.matches With Regular Expressions

Another option is by using String.matches() with regular expressions:

assertTrue(src.matches("(?i).*" + dest + ".*"));

The matches() method takes a String to represent the regular expression. (?i) enables case-insensitivity and .* uses every character except line breaks.

4. String.regionMatches

We can also use String.regionMatches(). It checks if two String regions match, using true for the ignoreCase parameter:

public static boolean processRegionMatches(String src, String dest) {
    for (int i = src.length() - dest.length(); i >= 0; i--) 
        if (src.regionMatches(true, i, dest, 0, dest.length())) 
            return true; 
    return false;
}
assertTrue(processRegionMatches(src, dest));

To improve the performance, it starts matching the region, taking into account the length of the destination String. Then, it diminishes the iterator.

5. Pattern With the CASE_INSENSITIVE Option

The java.util.regex.Pattern class provides us a way of matching strings using the matcher() method. In this case, we can use the quote() method to escape any special characters, and the CASE_INSENSITIVE flag. Let’s take a look:

assertTrue(Pattern.compile(Pattern.quote(dest), Pattern.CASE_INSENSITIVE)
    .matcher(src)
    .find());

6. Apache Commons StringUtils.containsIgnoreCase

Finally, we’ll take advantage of the Apache Commons StringUtils class:

assertTrue(StringUtils.containsIgnoreCase(src, dest));

7. Performance Comparison

As in this general article about checking for substrings using the contains method, we used the open-source framework Java Microbenchmark Harness (JMH) to compare the performance of the methods in nanoseconds:

  1. Pattern CASE_INSENSITIVE Regular Expression: 399.387 ns
  2. String toLowerCase: 434.064 ns
  3. Apache Commons StringUtils: 496.313 ns
  4. String Region Matches: 718.842 ns
  5. String matches with Regular Expression: 3964.346 ns

As we can see, the winner is Pattern with the CASE_INSENSITIVE flag enabled, closely followed by toLowerCase(). We also noticed a clear improvement in the performance between Java 8 and Java 11.

8. Conclusion

In this tutorial, we looked at a few different ways to check a String for a substring, while ignoring the case in Java.

We looked at using String.toLowerCase() and toUpperCase()String.matches()String.regionMatches(), Apache Commons StringUtils.containsIgnoreCase(), and Pattern.matcher().find().

Also, we evaluated the performance of each solution and found that using the compile() method from java.util.regex.Pattern with the CASE_INSENSITIVE flag performed the best.

As always, the code is available over on GitHub.

Related posts:

Java Program to Find Number of Articulation points in a Graph
Getting Started with Forms in Spring MVC
Jackson Annotation Examples
Java Program to Generate Random Numbers Using Multiply with Carry Method
Constructor Injection in Spring with Lombok
Giới thiệu Google Guice – Dependency injection (DI) framework
Hướng dẫn Java Design Pattern – Flyweight
Arrays.asList vs new ArrayList(Arrays.asList())
Hướng dẫn sử dụng Java Annotation
How to Add a Single Element to a Stream
Java Program to Use Boruvka’s Algorithm to Find the Minimum Spanning Tree
Guide to ThreadLocalRandom in Java
Hướng dẫn Java Design Pattern – Iterator
Java Program to Find Minimum Element in an Array using Linear Search
JUnit 5 @Test Annotation
Python String rindex()
Guide to UUID in Java
Simultaneous Spring WebClient Calls
Java Program to Find Strongly Connected Components in Graphs
Java Program to Remove the Edges in a Given Cyclic Graph such that its Linear Extension can be Found
Java Program to Generate All Pairs of Subsets Whose Union Make the Set
Java Program to Implement Hash Tables Chaining with Doubly Linked Lists
Java 8 Predicate Chain
Converting a Stack Trace to a String in Java
Java Program to Implement Maximum Length Chain of Pairs
Java Program to Implement Cartesian Tree
Java Program to Implement Kosaraju Algorithm
Java Program to Implement Skip List
Java Program to Represent Graph Using 2D Arrays
DynamoDB in a Spring Boot Application Using Spring Data
Java Program to Implement VList
Java Program to Implement Unrolled Linked List