Skiftlägeskänslig strängmatchning i Java

1. Översikt

Det finns många sätt att kontrollera om en sträng innehåller en delsträng. I den här artikeln letar vi efter strängar i en sträng medan vi fokuserar på skiftlägeskänsliga lösningar till String.contains () i Java. Viktigast av allt kommer vi att ge exempel på hur man löser problemet.

2. Den enklaste lösningen: String.toLowerCase

Den enklaste lösningen är att använda String.toLowerCase () . I det här fallet kommer vi att omvandla båda strängarna till gemener och sedan använda metoden innehåller () :

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

Vi kan också använda String.toUpperCase () och det skulle ge samma resultat.

3. Strängmatcher med reguljära uttryck

Ett annat alternativ är att använda String.matches () med reguljära uttryck:

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

Den träffar () metod tar en S tring att representera det reguljära uttrycket. (? i) möjliggör skiftlägeskänslighet och . * använder alla tecken utom radbrytningar.

4. String.regionMatches

Vi kan också använda String.regionMatches () . Den kontrollerar om två strängregioner matchar, med true för ignorCase- parametern:

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));

För att förbättra prestanda, börjar den matchar regionen, med hänsyn till längden på destinations String . Då minskar iteratorn.

5. Mönster med alternativet CASE_INSENSITIVE

Den java.util.regex.Pattern klassen ger oss ett sätt att matcha strängar med användning av anpassaren () metoden. I det här fallet kan vi använda citat () -metoden för att undkomma specialtecken och CASE_INSENSITIVE- flaggan. Låt oss ta en titt:

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

6. Apache Commons StringUtils.containsIgnoreCase

Slutligen kommer vi att dra nytta av klassen Apache Commons StringUtils :

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

7. Jämförelse av prestanda

Som i den här allmänna artikeln om att söka efter substrat med metoden innehåller använde vi open source-ramverket Java Microbenchmark Harness (JMH) för att jämföra prestandan hos metoderna i nanosekunder :

  1. Mönster CASE_INSENSITIVE Regeluttryck : 399,387 ns
  2. String toLowerCase : 434.064 ns
  3. Apache Commons StringUtils : 496.313 ns
  4. String Region Matches : 718.842 ns
  5. Strängmatchningar med Regular Expression : 3964.346 ns

Som vi kan se är vinnaren Mönster med CASE_INSENSITIVE- flaggan aktiverad, följt tätt av toLowerCase () . Vi märkte också en tydlig förbättring av prestandan mellan Java 8 och Java 11.

8. Slutsats

I den här handledningen tittade vi på några olika sätt att kontrollera en sträng för en substring medan vi ignorerade fallet i Java.

Vi tittade på att använda String.toLowerCase () och toUpperCase () , String.matches () , String.regionMatches () , Apache Commons StringUtils.containsIgnoreCase () och Pattern.matcher (). Hitta () .

Vi utvärderade också prestandan för varje lösning och fann att metoden compile () från java.util.regex.Pattern med CASE_INSENSITIVE- flaggan presterade bäst .

Som alltid finns koden tillgänglig på GitHub.