LANG-787: Add StringUtils#removeIgnoreCase
Patch by Gokul Nanthakumar C
diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java
index 31a572a..4e2e453 100644
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@ -4701,6 +4701,46 @@ public static String remove(final String str, final String remove) {
}
/**
+ * <p>
+ * Case insensitive removal of all occurrences of a substring from within
+ * the source string.
+ * </p>
+ *
+ * <p>
+ * A {@code null} source string will return {@code null}. An empty ("")
+ * source string will return the empty string. A {@code null} remove string
+ * will return the source string. An empty ("") remove string will return
+ * the source string.
+ * </p>
+ *
+ * <pre>
+ * StringUtils.removeIgnoreCase(null, *) = null
+ * StringUtils.removeIgnoreCase("", *) = ""
+ * StringUtils.removeIgnoreCase(*, null) = *
+ * StringUtils.removeIgnoreCase(*, "") = *
+ * StringUtils.removeIgnoreCase("queued", "ue") = "qd"
+ * StringUtils.removeIgnoreCase("queued", "zz") = "queued"
+ * StringUtils.removeIgnoreCase("quEUed", "UE") = "qd"
+ * StringUtils.removeIgnoreCase("queued", "zZ") = "queued"
+ * </pre>
+ *
+ * @param str
+ * the source String to search, may be null
+ * @param remove
+ * the String to search for (case insensitive) and remove, may be
+ * null
+ * @return the substring with the string removed if found, {@code null} if
+ * null String input
+ * @since 3.5
+ */
+ public static String removeIgnoreCase(String str, String remove) {
+ if (isEmpty(str) || isEmpty(remove)) {
+ return str;
+ }
+ return replaceIgnoreCase(str, remove, EMPTY, -1);
+ }
+
+ /**
* <p>Removes all occurrences of a character from within the source string.</p>
*
* <p>A {@code null} source string will return {@code null}.
@@ -4856,6 +4896,35 @@ public static String replaceOnce(final String text, final String searchString, f
}
/**
+ * <p>Case insensitively replaces a String with another String inside a larger String, once.</p>
+ *
+ * <p>A {@code null} reference passed to this method is a no-op.</p>
+ *
+ * <pre>
+ * StringUtils.replaceOnceIgnoreCase(null, *, *) = null
+ * StringUtils.replaceOnceIgnoreCase("", *, *) = ""
+ * StringUtils.replaceOnceIgnoreCase("any", null, *) = "any"
+ * StringUtils.replaceOnceIgnoreCase("any", *, null) = "any"
+ * StringUtils.replaceOnceIgnoreCase("any", "", *) = "any"
+ * StringUtils.replaceOnceIgnoreCase("aba", "a", null) = "aba"
+ * StringUtils.replaceOnceIgnoreCase("aba", "a", "") = "ba"
+ * StringUtils.replaceOnceIgnoreCase("aba", "a", "z") = "zba"
+ * StringUtils.replaceOnceIgnoreCase("FoOFoofoo", "foo", "") = "Foofoo"
+ * </pre>
+ *
+ * @see #replaceIgnoreCase(String text, String searchString, String replacement, int max)
+ * @param text text to search and replace in, may be null
+ * @param searchString the String to search for (case insensitive), may be null
+ * @param replacement the String to replace with, may be null
+ * @return the text with any replacements processed,
+ * {@code null} if null String input
+ * @since 3.5
+ */
+ public static String replaceOnceIgnoreCase(String text, String searchString, String replacement) {
+ return replaceIgnoreCase(text, searchString, replacement, 1);
+ }
+
+ /**
* <p>Replaces each substring of the source String that matches the given regular expression with the given
* replacement using the {@link Pattern#DOTALL} option. DOTALL is also know as single-line mode in Perl.</p>
*
@@ -5071,6 +5140,34 @@ public static String replace(final String text, final String searchString, final
}
/**
+ * <p>Case insensitively replaces all occurrences of a String within another String.</p>
+ *
+ * <p>A {@code null} reference passed to this method is a no-op.</p>
+ *
+ * <pre>
+ * StringUtils.replaceIgnoreCase(null, *, *) = null
+ * StringUtils.replaceIgnoreCase("", *, *) = ""
+ * StringUtils.replaceIgnoreCase("any", null, *) = "any"
+ * StringUtils.replaceIgnoreCase("any", *, null) = "any"
+ * StringUtils.replaceIgnoreCase("any", "", *) = "any"
+ * StringUtils.replaceIgnoreCase("aba", "a", null) = "aba"
+ * StringUtils.replaceIgnoreCase("abA", "A", "") = "b"
+ * StringUtils.replaceIgnoreCase("aba", "A", "z") = "zbz"
+ * </pre>
+ *
+ * @see #replaceIgnoreCase(String text, String searchString, String replacement, int max)
+ * @param text text to search and replace in, may be null
+ * @param searchString the String to search for (case insensitive), may be null
+ * @param replacement the String to replace it with, may be null
+ * @return the text with any replacements processed,
+ * {@code null} if null String input
+ * @since 3.5
+ */
+ public static String replaceIgnoreCase(String text, String searchString, String replacement) {
+ return replaceIgnoreCase(text, searchString, replacement, -1);
+ }
+
+ /**
* <p>Replaces a String with another String inside a larger String,
* for the first {@code max} values of the search String.</p>
*
@@ -5099,29 +5196,102 @@ public static String replace(final String text, final String searchString, final
* {@code null} if null String input
*/
public static String replace(final String text, final String searchString, final String replacement, int max) {
- if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
- return text;
- }
- int start = 0;
- int end = text.indexOf(searchString, start);
- if (end == INDEX_NOT_FOUND) {
- return text;
- }
- final int replLength = searchString.length();
- int increase = replacement.length() - replLength;
- increase = increase < 0 ? 0 : increase;
- increase *= max < 0 ? 16 : max > 64 ? 64 : max;
- final StringBuilder buf = new StringBuilder(text.length() + increase);
- while (end != INDEX_NOT_FOUND) {
- buf.append(text.substring(start, end)).append(replacement);
- start = end + replLength;
- if (--max == 0) {
- break;
- }
- end = text.indexOf(searchString, start);
- }
- buf.append(text.substring(start));
- return buf.toString();
+ return replace(text, searchString, replacement, max, false);
+ }
+
+ /**
+ * <p>Replaces a String with another String inside a larger String,
+ * for the first {@code max} values of the search String,
+ * case sensitively/insensisitively based on {@code ignoreCase} value.</p>
+ *
+ * <p>A {@code null} reference passed to this method is a no-op.</p>
+ *
+ * <pre>
+ * StringUtils.replace(null, *, *, *, false) = null
+ * StringUtils.replace("", *, *, *, false) = ""
+ * StringUtils.replace("any", null, *, *, false) = "any"
+ * StringUtils.replace("any", *, null, *, false) = "any"
+ * StringUtils.replace("any", "", *, *, false) = "any"
+ * StringUtils.replace("any", *, *, 0, false) = "any"
+ * StringUtils.replace("abaa", "a", null, -1, false) = "abaa"
+ * StringUtils.replace("abaa", "a", "", -1, false) = "b"
+ * StringUtils.replace("abaa", "a", "z", 0, false) = "abaa"
+ * StringUtils.replace("abaa", "A", "z", 1, false) = "abaa"
+ * StringUtils.replace("abaa", "A", "z", 1, true) = "zbaa"
+ * StringUtils.replace("abAa", "a", "z", 2, true) = "zbza"
+ * StringUtils.replace("abAa", "a", "z", -1, true) = "zbzz"
+ * </pre>
+ *
+ * @param text text to search and replace in, may be null
+ * @param searchString the String to search for (case insensitive), may be null
+ * @param replacement the String to replace it with, may be null
+ * @param max maximum number of values to replace, or {@code -1} if no maximum
+ * @param ignoreCase if true replace is case insensitive, otherwise case sensitive
+ * @return the text with any replacements processed,
+ * {@code null} if null String input
+ */
+ private static String replace(String text, String searchString, String replacement, int max, boolean ignoreCase) {
+ if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
+ return text;
+ }
+ String searchText = text;
+ if (ignoreCase) {
+ searchText = text.toLowerCase();
+ searchString = searchString.toLowerCase();
+ }
+ int start = 0;
+ int end = searchText.indexOf(searchString, start);
+ if (end == INDEX_NOT_FOUND) {
+ return text;
+ }
+ final int replLength = searchString.length();
+ int increase = replacement.length() - replLength;
+ increase = increase < 0 ? 0 : increase;
+ increase *= max < 0 ? 16 : max > 64 ? 64 : max;
+ final StringBuilder buf = new StringBuilder(text.length() + increase);
+ while (end != INDEX_NOT_FOUND) {
+ buf.append(text.substring(start, end)).append(replacement);
+ start = end + replLength;
+ if (--max == 0) {
+ break;
+ }
+ end = searchText.indexOf(searchString, start);
+ }
+ buf.append(text.substring(start));
+ return buf.toString();
+ }
+
+ /**
+ * <p>Case insensitively replaces a String with another String inside a larger String,
+ * for the first {@code max} values of the search String.</p>
+ *
+ * <p>A {@code null} reference passed to this method is a no-op.</p>
+ *
+ * <pre>
+ * StringUtils.replaceIgnoreCase(null, *, *, *) = null
+ * StringUtils.replaceIgnoreCase("", *, *, *) = ""
+ * StringUtils.replaceIgnoreCase("any", null, *, *) = "any"
+ * StringUtils.replaceIgnoreCase("any", *, null, *) = "any"
+ * StringUtils.replaceIgnoreCase("any", "", *, *) = "any"
+ * StringUtils.replaceIgnoreCase("any", *, *, 0) = "any"
+ * StringUtils.replaceIgnoreCase("abaa", "a", null, -1) = "abaa"
+ * StringUtils.replaceIgnoreCase("abaa", "a", "", -1) = "b"
+ * StringUtils.replaceIgnoreCase("abaa", "a", "z", 0) = "abaa"
+ * StringUtils.replaceIgnoreCase("abaa", "A", "z", 1) = "zbaa"
+ * StringUtils.replaceIgnoreCase("abAa", "a", "z", 2) = "zbza"
+ * StringUtils.replaceIgnoreCase("abAa", "a", "z", -1) = "zbzz"
+ * </pre>
+ *
+ * @param text text to search and replace in, may be null
+ * @param searchString the String to search for (case insensitive), may be null
+ * @param replacement the String to replace it with, may be null
+ * @param max maximum number of values to replace, or {@code -1} if no maximum
+ * @return the text with any replacements processed,
+ * {@code null} if null String input
+ * @since 3.5
+ */
+ public static String replaceIgnoreCase(String text, String searchString, String replacement, int max) {
+ return replace(text, searchString, replacement, max, true);
}
/**
diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
index 1fa164e..df48c27 100644
--- a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
@@ -1209,6 +1209,33 @@ public void testReplace_StringStringString() {
}
@Test
+ public void testReplaceIgnoreCase_StringStringString() {
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, null, null));
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, null, "any"));
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, "any", null));
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, "any", "any"));
+
+ assertEquals("", StringUtils.replaceIgnoreCase("", null, null));
+ assertEquals("", StringUtils.replaceIgnoreCase("", null, "any"));
+ assertEquals("", StringUtils.replaceIgnoreCase("", "any", null));
+ assertEquals("", StringUtils.replaceIgnoreCase("", "any", "any"));
+
+ assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", "", "any"));
+ assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", null, "any"));
+ assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", "F", null));
+ assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", null, null));
+
+ assertEquals("", StringUtils.replaceIgnoreCase("foofoofoo", "foo", ""));
+ assertEquals("barbarbar", StringUtils.replaceIgnoreCase("foofoofoo", "foo", "bar"));
+ assertEquals("farfarfar", StringUtils.replaceIgnoreCase("foofoofoo", "oo", "ar"));
+
+ // IgnoreCase
+ assertEquals("", StringUtils.replaceIgnoreCase("foofoofoo", "FOO", ""));
+ assertEquals("barbarbar", StringUtils.replaceIgnoreCase("fooFOOfoo", "foo", "bar"));
+ assertEquals("farfarfar", StringUtils.replaceIgnoreCase("foofOOfoo", "OO", "ar"));
+ }
+
+ @Test
public void testReplacePattern() {
assertNull(StringUtils.replacePattern(null, "", ""));
assertEquals("any", StringUtils.replacePattern("any", null, ""));
@@ -1331,6 +1358,43 @@ public void testReplace_StringStringStringInt() {
}
@Test
+ public void testReplaceIgnoreCase_StringStringStringInt() {
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, null, null, 2));
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, null, "any", 2));
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, "any", null, 2));
+ assertEquals(null, StringUtils.replaceIgnoreCase(null, "any", "any", 2));
+
+ assertEquals("", StringUtils.replaceIgnoreCase("", null, null, 2));
+ assertEquals("", StringUtils.replaceIgnoreCase("", null, "any", 2));
+ assertEquals("", StringUtils.replaceIgnoreCase("", "any", null, 2));
+ assertEquals("", StringUtils.replaceIgnoreCase("", "any", "any", 2));
+
+ String str = new String(new char[] { 'o', 'o', 'f', 'o', 'o' });
+ assertSame(str, StringUtils.replaceIgnoreCase(str, "x", "", -1));
+
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", -1));
+ assertEquals("oofoo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 0));
+ assertEquals("ofoo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 1));
+ assertEquals("foo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 2));
+ assertEquals("fo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 3));
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", 4));
+
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", -5));
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", 1000));
+
+ // IgnoreCase
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", -1));
+ assertEquals("oofoo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 0));
+ assertEquals("ofoo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 1));
+ assertEquals("foo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 2));
+ assertEquals("fo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 3));
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", 4));
+
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", -5));
+ assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", 1000));
+ }
+
+ @Test
public void testReplaceOnce_StringStringString() {
assertNull(StringUtils.replaceOnce(null, null, null));
assertNull(StringUtils.replaceOnce(null, null, "any"));
@@ -1350,6 +1414,29 @@ public void testReplaceOnce_StringStringString() {
assertEquals("foofoo", StringUtils.replaceOnce("foofoofoo", "foo", ""));
}
+ @Test
+ public void testReplaceOnceIgnoreCase_StringStringString() {
+ assertEquals(null, StringUtils.replaceOnceIgnoreCase(null, null, null));
+ assertEquals(null, StringUtils.replaceOnceIgnoreCase(null, null, "any"));
+ assertEquals(null, StringUtils.replaceOnceIgnoreCase(null, "any", null));
+ assertEquals(null, StringUtils.replaceOnceIgnoreCase(null, "any", "any"));
+
+ assertEquals("", StringUtils.replaceOnceIgnoreCase("", null, null));
+ assertEquals("", StringUtils.replaceOnceIgnoreCase("", null, "any"));
+ assertEquals("", StringUtils.replaceOnceIgnoreCase("", "any", null));
+ assertEquals("", StringUtils.replaceOnceIgnoreCase("", "any", "any"));
+
+ assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", "", "any"));
+ assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", null, "any"));
+ assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", "F", null));
+ assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", null, null));
+
+ assertEquals("foofoo", StringUtils.replaceOnceIgnoreCase("foofoofoo", "foo", ""));
+
+ // Ignore Case
+ assertEquals("Foofoo", StringUtils.replaceOnceIgnoreCase("FoOFoofoo", "foo", ""));
+ }
+
/**
* Test method for 'StringUtils.replaceEach(String, String[], String[])'
*/
@@ -2393,6 +2480,42 @@ public void testRemove_String() {
}
@Test
+ public void testRemoveIgnoreCase_String() {
+ // StringUtils.removeIgnoreCase(null, *) = null
+ assertEquals(null, StringUtils.removeIgnoreCase(null, null));
+ assertEquals(null, StringUtils.removeIgnoreCase(null, ""));
+ assertEquals(null, StringUtils.removeIgnoreCase(null, "a"));
+
+ // StringUtils.removeIgnoreCase("", *) = ""
+ assertEquals("", StringUtils.removeIgnoreCase("", null));
+ assertEquals("", StringUtils.removeIgnoreCase("", ""));
+ assertEquals("", StringUtils.removeIgnoreCase("", "a"));
+
+ // StringUtils.removeIgnoreCase(*, null) = *
+ assertEquals(null, StringUtils.removeIgnoreCase(null, null));
+ assertEquals("", StringUtils.removeIgnoreCase("", null));
+ assertEquals("a", StringUtils.removeIgnoreCase("a", null));
+
+ // StringUtils.removeIgnoreCase(*, "") = *
+ assertEquals(null, StringUtils.removeIgnoreCase(null, ""));
+ assertEquals("", StringUtils.removeIgnoreCase("", ""));
+ assertEquals("a", StringUtils.removeIgnoreCase("a", ""));
+
+ // StringUtils.removeIgnoreCase("queued", "ue") = "qd"
+ assertEquals("qd", StringUtils.removeIgnoreCase("queued", "ue"));
+
+ // StringUtils.removeIgnoreCase("queued", "zz") = "queued"
+ assertEquals("queued", StringUtils.removeIgnoreCase("queued", "zz"));
+
+ // IgnoreCase
+ // StringUtils.removeIgnoreCase("quEUed", "UE") = "qd"
+ assertEquals("qd", StringUtils.removeIgnoreCase("quEUed", "UE"));
+
+ // StringUtils.removeIgnoreCase("queued", "zZ") = "queued"
+ assertEquals("queued", StringUtils.removeIgnoreCase("queued", "zZ"));
+ }
+
+ @Test
public void testRemove_char() {
// StringUtils.remove(null, *) = null
assertNull(StringUtils.remove(null, 'a'));