diff --git a/src/java/org/apache/commons/lang3/StringUtils.java b/src/java/org/apache/commons/lang3/StringUtils.java index b6cfa759d..f561ca199 100644 --- a/src/java/org/apache/commons/lang3/StringUtils.java +++ b/src/java/org/apache/commons/lang3/StringUtils.java @@ -914,6 +914,87 @@ public class StringUtils { return str.indexOf(searchStr, startPos); } + /** + *

Case in-sensitive find of the first index within a String.

+ * + *

A null String will return -1. + * A negative start position is treated as zero. + * An empty ("") search String always matches. + * A start position greater than the string length only matches + * an empty search String.

+ * + *
+     * StringUtils.indexOfIgnoreCase(null, *)          = -1
+     * StringUtils.indexOfIgnoreCase(*, null)          = -1
+     * StringUtils.indexOfIgnoreCase("", "")           = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "a")  = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "b")  = 2
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return the first index of the search String, + * -1 if no match or null string input + * @since 3.0 + */ + public static int indexOfIgnoreCase(String str, String searchStr) { + return indexOfIgnoreCase(str, searchStr, 0); + } + + /** + *

Case in-sensitive find of the first index within a String + * from the specified position.

+ * + *

A null String will return -1. + * A negative start position is treated as zero. + * An empty ("") search String always matches. + * A start position greater than the string length only matches + * an empty search String.

+ * + *
+     * StringUtils.indexOfIgnoreCase(null, *, *)          = -1
+     * StringUtils.indexOfIgnoreCase(*, null, *)          = -1
+     * StringUtils.indexOfIgnoreCase("", "", 0)           = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+     * StringUtils.indexOfIgnoreCase("abc", "", 9)        = 3
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @param startPos the start position, negative treated as zero + * @return the first index of the search String, + * -1 if no match or null string input + * @since 3.0 + */ + public static int indexOfIgnoreCase(String str, String searchStr, int startPos) { + if (str == null || searchStr == null) { + return -1; + } + if (startPos < 0) { + startPos = 0; + } + int endLimit = (str.length() - searchStr.length()) + 1; + if (startPos > endLimit) { + return -1; + } + if (searchStr.length() == 0) { + return startPos; + } + for (int i = startPos; i < endLimit; i++) { + if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) { + return i; + } + } + return -1; + } + // LastIndexOf //----------------------------------------------------------------------- /** @@ -1077,6 +1158,85 @@ public class StringUtils { return str.lastIndexOf(searchStr, startPos); } + /** + *

Case in-sensitive find of the last index within a String.

+ * + *

A null String will return -1. + * A negative start position returns -1. + * An empty ("") search String always matches unless the start position is negative. + * A start position greater than the string length searches the whole string.

+ * + *
+     * StringUtils.lastIndexOfIgnoreCase(null, *)          = -1
+     * StringUtils.lastIndexOfIgnoreCase(*, null)          = -1
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A")  = 7
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B")  = 5
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return the first index of the search String, + * -1 if no match or null string input + * @since 3.0 + */ + public static int lastIndexOfIgnoreCase(String str, String searchStr) { + if (str == null || searchStr == null) { + return -1; + } + return lastIndexOfIgnoreCase(str, searchStr, str.length()); + } + + /** + *

Case in-sensitive find of the last index within a String + * from the specified position.

+ * + *

A null String will return -1. + * A negative start position returns -1. + * An empty ("") search String always matches unless the start position is negative. + * A start position greater than the string length searches the whole string.

+ * + *
+     * StringUtils.lastIndexOfIgnoreCase(null, *, *)          = -1
+     * StringUtils.lastIndexOfIgnoreCase(*, null, *)          = -1
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8)  = 7
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8)  = 5
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9)  = 5
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0)  = -1
+     * 
+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @param startPos the start position + * @return the first index of the search String, + * -1 if no match or null string input + * @since 3.0 + */ + public static int lastIndexOfIgnoreCase(String str, String searchStr, int startPos) { + if (str == null || searchStr == null) { + return -1; + } + if (startPos > (str.length() - searchStr.length())) { + startPos = str.length() - searchStr.length(); + } + if (startPos < 0) { + return -1; + } + if (searchStr.length() == 0) { + return startPos; + } + + for (int i = startPos; i >= 0; i--) { + if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) { + return i; + } + } + return -1; + } + // Contains //----------------------------------------------------------------------- /** diff --git a/src/test/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java b/src/test/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java index ba947d61b..fbef90543 100644 --- a/src/test/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java +++ b/src/test/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java @@ -113,6 +113,37 @@ public class StringUtilsEqualsIndexOfTest extends TestCase { assertEquals(0, StringUtils.indexOf("aabaabaa", "")); } + public void testIndexOfIgnoreCase_String() { + assertEquals(-1, StringUtils.indexOfIgnoreCase(null, null)); + assertEquals(-1, StringUtils.indexOfIgnoreCase(null, "")); + assertEquals(-1, StringUtils.indexOfIgnoreCase("", null)); + assertEquals(0, StringUtils.indexOfIgnoreCase("", "")); + assertEquals(0, StringUtils.indexOfIgnoreCase("aabaabaa", "a")); + assertEquals(0, StringUtils.indexOfIgnoreCase("aabaabaa", "A")); + assertEquals(2, StringUtils.indexOfIgnoreCase("aabaabaa", "b")); + assertEquals(2, StringUtils.indexOfIgnoreCase("aabaabaa", "B")); + assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "ab")); + assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB")); + assertEquals(0, StringUtils.indexOfIgnoreCase("aabaabaa", "")); + } + + public void testIndexOfIgnoreCase_StringInt() { + assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", -1)); + assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0)); + assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 1)); + assertEquals(4, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 2)); + assertEquals(4, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 3)); + assertEquals(4, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 4)); + assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 5)); + assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 6)); + assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 7)); + assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 8)); + assertEquals(1, StringUtils.indexOfIgnoreCase("aab", "AB", 1)); + assertEquals(5, StringUtils.indexOfIgnoreCase("aabaabaa", "", 5)); + assertEquals(-1, StringUtils.indexOfIgnoreCase("ab", "AAB", 0)); + assertEquals(-1, StringUtils.indexOfIgnoreCase("aab", "AAB", 1)); + } + public void testOrdinalIndexOf() { assertEquals(-1, StringUtils.ordinalIndexOf(null, null, Integer.MIN_VALUE)); assertEquals(-1, StringUtils.ordinalIndexOf("", null, Integer.MIN_VALUE)); @@ -267,6 +298,47 @@ public class StringUtilsEqualsIndexOfTest extends TestCase { assertEquals(0, StringUtils.lastIndexOf("aabaabaa", "a", 0)); } + public void testLastIndexOfIgnoreCase_String() { + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, null)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", null)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, "")); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", "a")); + assertEquals(0, StringUtils.lastIndexOfIgnoreCase("", "")); + assertEquals(8, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "")); + assertEquals(7, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "a")); + assertEquals(7, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A")); + assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "b")); + assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B")); + assertEquals(4, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "ab")); + assertEquals(4, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB")); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("ab", "AAB")); + assertEquals(0, StringUtils.lastIndexOfIgnoreCase("aab", "AAB")); + } + + public void testLastIndexOfIgnoreCase_StringInt() { + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, null, 0)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, null, -1)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, "", 0)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, "", -1)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", null, 0)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", null, -1)); + assertEquals(0, StringUtils.lastIndexOfIgnoreCase("", "", 0)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", "", -1)); + assertEquals(0, StringUtils.lastIndexOfIgnoreCase("", "", 9)); + assertEquals(0, StringUtils.lastIndexOfIgnoreCase("abc", "", 0)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("abc", "", -1)); + assertEquals(3, StringUtils.lastIndexOfIgnoreCase("abc", "", 9)); + assertEquals(7, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8)); + assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8)); + assertEquals(4, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8)); + assertEquals(2, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 3)); + assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1)); + assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0)); + assertEquals(0, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0)); + assertEquals(1, StringUtils.lastIndexOfIgnoreCase("aab", "AB", 1)); + } + //----------------------------------------------------------------------- public void testContainsChar() { assertEquals(false, StringUtils.contains(null, ' '));