Browse Source

Add ignoreCase variants to PatternMatchUtils

See gh-34801
6.1.x
rstoyanchev 8 months ago
parent
commit
89ae20b9ff
  1. 61
      spring-core/src/main/java/org/springframework/util/PatternMatchUtils.java
  2. 21
      spring-core/src/test/java/org/springframework/util/PatternMatchUtilsTests.java

61
spring-core/src/main/java/org/springframework/util/PatternMatchUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,13 +37,24 @@ public abstract class PatternMatchUtils { @@ -37,13 +37,24 @@ public abstract class PatternMatchUtils {
* @return whether the String matches the given pattern
*/
public static boolean simpleMatch(@Nullable String pattern, @Nullable String str) {
return simpleMatch(pattern, str, false);
}
/**
* Variant of {@link #simpleMatch(String, String)} that ignores upper/lower case.
*/
public static boolean simpleMatchIgnoreCase(@Nullable String pattern, @Nullable String str) {
return simpleMatch(pattern, str, true);
}
private static boolean simpleMatch(@Nullable String pattern, @Nullable String str, boolean ignoreCase) {
if (pattern == null || str == null) {
return false;
}
int firstIndex = pattern.indexOf('*');
if (firstIndex == -1) {
return pattern.equals(str);
return (ignoreCase ? pattern.equalsIgnoreCase(str) : pattern.equals(str));
}
if (firstIndex == 0) {
@ -52,25 +63,43 @@ public abstract class PatternMatchUtils { @@ -52,25 +63,43 @@ public abstract class PatternMatchUtils {
}
int nextIndex = pattern.indexOf('*', 1);
if (nextIndex == -1) {
return str.endsWith(pattern.substring(1));
String part = pattern.substring(1);
return (ignoreCase ? StringUtils.endsWithIgnoreCase(str, part) : str.endsWith(part));
}
String part = pattern.substring(1, nextIndex);
if (part.isEmpty()) {
return simpleMatch(pattern.substring(nextIndex), str);
return simpleMatch(pattern.substring(nextIndex), str, ignoreCase);
}
int partIndex = str.indexOf(part);
int partIndex = indexOf(str, part, 0, ignoreCase);
while (partIndex != -1) {
if (simpleMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length()))) {
if (simpleMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length()), ignoreCase)) {
return true;
}
partIndex = str.indexOf(part, partIndex + 1);
partIndex = indexOf(str, part, partIndex + 1, ignoreCase);
}
return false;
}
return (str.length() >= firstIndex &&
pattern.startsWith(str.substring(0, firstIndex)) &&
simpleMatch(pattern.substring(firstIndex), str.substring(firstIndex)));
checkStartsWith(pattern, str, firstIndex, ignoreCase) &&
simpleMatch(pattern.substring(firstIndex), str.substring(firstIndex), ignoreCase));
}
private static boolean checkStartsWith(String pattern, String str, int index, boolean ignoreCase) {
String part = str.substring(0, index);
return (ignoreCase ? StringUtils.startsWithIgnoreCase(pattern, part) : pattern.startsWith(part));
}
private static int indexOf(String str, String otherStr, int startIndex, boolean ignoreCase) {
if (!ignoreCase) {
return str.indexOf(otherStr, startIndex);
}
for (int i = startIndex; i <= (str.length() - otherStr.length()); i++) {
if (str.regionMatches(true, i, otherStr, 0, otherStr.length())) {
return i;
}
}
return -1;
}
/**
@ -94,4 +123,18 @@ public abstract class PatternMatchUtils { @@ -94,4 +123,18 @@ public abstract class PatternMatchUtils {
return false;
}
/**
* Variant of {@link #simpleMatch(String[], String)} that ignores upper/lower case.
*/
public static boolean simpleMatchIgnoreCase(@Nullable String[] patterns, @Nullable String str) {
if (patterns != null) {
for (String pattern : patterns) {
if (simpleMatch(pattern, str, true)) {
return true;
}
}
}
return false;
}
}

21
spring-core/src/test/java/org/springframework/util/PatternMatchUtilsTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -53,18 +53,22 @@ class PatternMatchUtilsTests { @@ -53,18 +53,22 @@ class PatternMatchUtilsTests {
assertMatches(new String[] { null, "" }, "");
assertMatches(new String[] { null, "123" }, "123");
assertMatches(new String[] { null, "*" }, "123");
testMixedCaseMatch("abC", "Abc");
}
@Test
void startsWith() {
assertMatches("get*", "getMe");
assertDoesNotMatch("get*", "setMe");
testMixedCaseMatch("geT*", "GetMe");
}
@Test
void endsWith() {
assertMatches("*Test", "getMeTest");
assertDoesNotMatch("*Test", "setMe");
testMixedCaseMatch("*TeSt", "getMeTesT");
}
@Test
@ -74,6 +78,10 @@ class PatternMatchUtilsTests { @@ -74,6 +78,10 @@ class PatternMatchUtilsTests {
assertMatches("*stuff*", "stuffTest");
assertMatches("*stuff*", "getstuff");
assertMatches("*stuff*", "stuff");
testMixedCaseMatch("*stuff*", "getStuffTest");
testMixedCaseMatch("*stuff*", "StuffTest");
testMixedCaseMatch("*stuff*", "getStuff");
testMixedCaseMatch("*stuff*", "Stuff");
}
@Test
@ -82,6 +90,8 @@ class PatternMatchUtilsTests { @@ -82,6 +90,8 @@ class PatternMatchUtilsTests {
assertMatches("on*Event", "onEvent");
assertDoesNotMatch("3*3", "3");
assertMatches("3*3", "33");
testMixedCaseMatch("on*Event", "OnMyEvenT");
testMixedCaseMatch("on*Event", "OnEvenT");
}
@Test
@ -122,18 +132,27 @@ class PatternMatchUtilsTests { @@ -122,18 +132,27 @@ class PatternMatchUtilsTests {
private void assertMatches(String pattern, String str) {
assertThat(PatternMatchUtils.simpleMatch(pattern, str)).isTrue();
assertThat(PatternMatchUtils.simpleMatchIgnoreCase(pattern, str)).isTrue();
}
private void assertDoesNotMatch(String pattern, String str) {
assertThat(PatternMatchUtils.simpleMatch(pattern, str)).isFalse();
assertThat(PatternMatchUtils.simpleMatchIgnoreCase(pattern, str)).isFalse();
}
private void testMixedCaseMatch(String pattern, String str) {
assertThat(PatternMatchUtils.simpleMatch(pattern, str)).isFalse();
assertThat(PatternMatchUtils.simpleMatchIgnoreCase(pattern, str)).isTrue();
}
private void assertMatches(String[] patterns, String str) {
assertThat(PatternMatchUtils.simpleMatch(patterns, str)).isTrue();
assertThat(PatternMatchUtils.simpleMatchIgnoreCase(patterns, str)).isTrue();
}
private void assertDoesNotMatch(String[] patterns, String str) {
assertThat(PatternMatchUtils.simpleMatch(patterns, str)).isFalse();
assertThat(PatternMatchUtils.simpleMatchIgnoreCase(patterns, str)).isFalse();
}
}

Loading…
Cancel
Save