Skip to content

Commit

Permalink
Add RegExUtils methods typed to CharSequence input and deprecate old
Browse files Browse the repository at this point in the history
versions typed to String
  • Loading branch information
garydgregory committed Jan 9, 2025
1 parent f43534e commit 744a8c3
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 8 deletions.
128 changes: 125 additions & 3 deletions src/main/java/org/apache/commons/lang3/RegExUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.commons.lang3;

import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -97,7 +98,46 @@ public static Matcher dotAllMatcher(final String regex, final String text) {
* @see #replaceAll(CharSequence, Pattern, String)
* @see java.util.regex.Matcher#replaceAll(String)
* @see java.util.regex.Pattern
* @since 3.18.0
*/
public static String removeAll(final CharSequence text, final Pattern regex) {
return replaceAll(text, regex, StringUtils.EMPTY);
}

/**
* Removes each substring of the text String that matches the given regular expression pattern.
*
* This method is a {@code null} safe equivalent to:
* <ul>
* <li>{@code pattern.matcher(text).replaceAll(StringUtils.EMPTY)}</li>
* </ul>
*
* <p>A {@code null} reference passed to this method is a no-op.</p>
*
* <pre>{@code
* StringUtils.removeAll(null, *) = null
* StringUtils.removeAll("any", (Pattern) null) = "any"
* StringUtils.removeAll("any", Pattern.compile("")) = "any"
* StringUtils.removeAll("any", Pattern.compile(".*")) = ""
* StringUtils.removeAll("any", Pattern.compile(".+")) = ""
* StringUtils.removeAll("abc", Pattern.compile(".?")) = ""
* StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("<.*>")) = "A\nB"
* StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("(?s)<.*>")) = "AB"
* StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("<.*>", Pattern.DOTALL)) = "AB"
* StringUtils.removeAll("ABCabc123abc", Pattern.compile("[a-z]")) = "ABC123"
* }</pre>
*
* @param text text to remove from, may be null
* @param regex the regular expression to which this string is to be matched
* @return the text with any removes processed,
* {@code null} if null String input
*
* @see #replaceAll(CharSequence, Pattern, String)
* @see java.util.regex.Matcher#replaceAll(String)
* @see java.util.regex.Pattern
* @deprecated Use {@link #removeAll(CharSequence, Pattern)}.
*/
@Deprecated
public static String removeAll(final String text, final Pattern regex) {
return replaceAll((CharSequence) text, regex, StringUtils.EMPTY);
}
Expand Down Expand Up @@ -179,7 +219,46 @@ public static String removeAll(final String text, final String regex) {
* @see #replaceFirst(String, Pattern, String)
* @see java.util.regex.Matcher#replaceFirst(String)
* @see java.util.regex.Pattern
* @since 3.18.0
*/
public static String removeFirst(final CharSequence text, final Pattern regex) {
return replaceFirst(text, regex, StringUtils.EMPTY);
}

/**
* Removes the first substring of the text string that matches the given regular expression pattern.
*
* This method is a {@code null} safe equivalent to:
* <ul>
* <li>{@code pattern.matcher(text).replaceFirst(StringUtils.EMPTY)}</li>
* </ul>
*
* <p>A {@code null} reference passed to this method is a no-op.</p>
*
* <pre>{@code
* StringUtils.removeFirst(null, *) = null
* StringUtils.removeFirst("any", (Pattern) null) = "any"
* StringUtils.removeFirst("any", Pattern.compile("")) = "any"
* StringUtils.removeFirst("any", Pattern.compile(".*")) = ""
* StringUtils.removeFirst("any", Pattern.compile(".+")) = ""
* StringUtils.removeFirst("abc", Pattern.compile(".?")) = "bc"
* StringUtils.removeFirst("A<__>\n<__>B", Pattern.compile("<.*>")) = "A\n<__>B"
* StringUtils.removeFirst("A<__>\n<__>B", Pattern.compile("(?s)<.*>")) = "AB"
* StringUtils.removeFirst("ABCabc123", Pattern.compile("[a-z]")) = "ABCbc123"
* StringUtils.removeFirst("ABCabc123abc", Pattern.compile("[a-z]+")) = "ABC123abc"
* }</pre>
*
* @param text text to remove from, may be null
* @param regex the regular expression pattern to which this string is to be matched
* @return the text with the first replacement processed,
* {@code null} if null String input
*
* @see #replaceFirst(String, Pattern, String)
* @see java.util.regex.Matcher#replaceFirst(String)
* @see java.util.regex.Pattern
* @deprecated Use {@link #removeFirst(CharSequence, Pattern)}.
*/
@Deprecated
public static String removeFirst(final String text, final Pattern regex) {
return replaceFirst(text, regex, StringUtils.EMPTY);
}
Expand Down Expand Up @@ -468,14 +547,57 @@ public static String replaceAll(final String text, final String regex, final Str
*
* @see java.util.regex.Matcher#replaceFirst(String)
* @see java.util.regex.Pattern
* @since 3.18.0
*/
public static String replaceFirst(final String text, final Pattern regex, final String replacement) {
public static String replaceFirst(final CharSequence text, final Pattern regex, final String replacement) {
if (text == null || regex == null || replacement == null) {
return text;
return toStringOrNull(text);
}
return regex.matcher(text).replaceFirst(replacement);
}

/**
* Replaces the first substring of the text string that matches the given regular expression pattern
* with the given replacement.
*
* This method is a {@code null} safe equivalent to:
* <ul>
* <li>{@code pattern.matcher(text).replaceFirst(replacement)}</li>
* </ul>
*
* <p>A {@code null} reference passed to this method is a no-op.</p>
*
* <pre>{@code
* StringUtils.replaceFirst(null, *, *) = null
* StringUtils.replaceFirst("any", (Pattern) null, *) = "any"
* StringUtils.replaceFirst("any", *, null) = "any"
* StringUtils.replaceFirst("", Pattern.compile(""), "zzz") = "zzz"
* StringUtils.replaceFirst("", Pattern.compile(".*"), "zzz") = "zzz"
* StringUtils.replaceFirst("", Pattern.compile(".+"), "zzz") = ""
* StringUtils.replaceFirst("abc", Pattern.compile(""), "ZZ") = "ZZabc"
* StringUtils.replaceFirst("<__>\n<__>", Pattern.compile("<.*>"), "z") = "z\n<__>"
* StringUtils.replaceFirst("<__>\n<__>", Pattern.compile("(?s)<.*>"), "z") = "z"
* StringUtils.replaceFirst("ABCabc123", Pattern.compile("[a-z]"), "_") = "ABC_bc123"
* StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "_") = "ABC_123abc"
* StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "") = "ABC123abc"
* StringUtils.replaceFirst("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2") = "Lorem_ipsum dolor sit"
* }</pre>
*
* @param text text to search and replace in, may be null
* @param regex the regular expression pattern to which this string is to be matched
* @param replacement the string to be substituted for the first match
* @return the text with the first replacement processed,
* {@code null} if null String input
*
* @see java.util.regex.Matcher#replaceFirst(String)
* @see java.util.regex.Pattern
* @deprecated Use {@link #replaceFirst(CharSequence, Pattern, String)}.
*/
@Deprecated
public static String replaceFirst(final String text, final Pattern regex, final String replacement) {
return replaceFirst((CharSequence) text, regex, replacement);
}

/**
* Replaces the first substring of the text string that matches the given regular expression
* with the given replacement.
Expand Down Expand Up @@ -617,7 +739,7 @@ public static String replacePattern(final String text, final String regex, final
}

private static String toStringOrNull(final CharSequence text) {
return text != null ? text.toString() : null;
return Objects.toString(text, null);
}

/**
Expand Down
66 changes: 61 additions & 5 deletions src/test/java/org/apache/commons/lang3/RegExUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,27 @@ public void testDotAllMatcherDeprecated() {
}

@Test
public void testRemoveAll_StringPattern() {
public void testRemoveAll() {
assertNull(RegExUtils.removeAll((CharSequence) null, Pattern.compile("")));
assertEquals("any", RegExUtils.removeAll((CharSequence) "any", (Pattern) null));

assertEquals("any", RegExUtils.removeAll((CharSequence) "any", Pattern.compile("")));
assertEquals("", RegExUtils.removeAll((CharSequence) "any", Pattern.compile(".*")));
assertEquals("", RegExUtils.removeAll((CharSequence) "any", Pattern.compile(".+")));
assertEquals("", RegExUtils.removeAll((CharSequence) "any", Pattern.compile(".?")));

assertEquals("A\nB", RegExUtils.removeAll((CharSequence) "A<__>\n<__>B", Pattern.compile("<.*>")));
assertEquals("AB", RegExUtils.removeAll((CharSequence) "A<__>\n<__>B", Pattern.compile("(?s)<.*>")));
assertEquals("ABC123", RegExUtils.removeAll((CharSequence) "ABCabc123abc", Pattern.compile("[a-z]")));

assertEquals("AB", RegExUtils.removeAll((CharSequence) "A<__>\n<__>B", Pattern.compile("<.*>", Pattern.DOTALL)));
assertEquals("AB", RegExUtils.removeAll((CharSequence) "A<__>\\n<__>B", Pattern.compile("<.*>")));
assertEquals("", RegExUtils.removeAll((CharSequence) "<A>x\\ny</A>", Pattern.compile("<A>.*</A>")));
assertEquals("", RegExUtils.removeAll((CharSequence) "<A>\nxy\n</A>", Pattern.compile("<A>.*</A>", Pattern.DOTALL)));
}

@Test
public void testRemoveAllDeprecated() {
assertNull(RegExUtils.removeAll(null, Pattern.compile("")));
assertEquals("any", RegExUtils.removeAll("any", (Pattern) null));

Expand Down Expand Up @@ -88,7 +108,23 @@ public void testRemoveAll_StringString() {
}

@Test
public void testRemoveFirst_StringPattern() {
public void testRemoveFirst() {
assertNull(RegExUtils.removeFirst((CharSequence) null, Pattern.compile("")));
assertEquals("any", RegExUtils.removeFirst((CharSequence) "any", (Pattern) null));

assertEquals("any", RegExUtils.removeFirst((CharSequence) "any", Pattern.compile("")));
assertEquals("", RegExUtils.removeFirst((CharSequence) "any", Pattern.compile(".*")));
assertEquals("", RegExUtils.removeFirst((CharSequence) "any", Pattern.compile(".+")));
assertEquals("bc", RegExUtils.removeFirst((CharSequence) "abc", Pattern.compile(".?")));

assertEquals("A\n<__>B", RegExUtils.removeFirst((CharSequence) "A<__>\n<__>B", Pattern.compile("<.*>")));
assertEquals("AB", RegExUtils.removeFirst((CharSequence) "A<__>\n<__>B", Pattern.compile("(?s)<.*>")));
assertEquals("ABCbc123", RegExUtils.removeFirst((CharSequence) "ABCabc123", Pattern.compile("[a-z]")));
assertEquals("ABC123abc", RegExUtils.removeFirst((CharSequence) "ABCabc123abc", Pattern.compile("[a-z]+")));
}

@Test
public void testRemoveFirstDeprecated() {
assertNull(RegExUtils.removeFirst(null, Pattern.compile("")));
assertEquals("any", RegExUtils.removeFirst("any", (Pattern) null));

Expand Down Expand Up @@ -235,7 +271,28 @@ public void testReplaceAll_StringStringString() {
}

@Test
public void testReplaceFirst_StringPatternString() {
public void testReplaceFirst() {
assertNull(RegExUtils.replaceFirst((CharSequence) null, Pattern.compile(""), ""));

assertEquals("any", RegExUtils.replaceFirst((CharSequence) "any", (Pattern) null, ""));
assertEquals("any", RegExUtils.replaceFirst((CharSequence) "any", Pattern.compile(""), null));

assertEquals("zzz", RegExUtils.replaceFirst((CharSequence) "", Pattern.compile(""), "zzz"));
assertEquals("zzz", RegExUtils.replaceFirst((CharSequence) "", Pattern.compile(".*"), "zzz"));
assertEquals("", RegExUtils.replaceFirst((CharSequence) "", Pattern.compile(".+"), "zzz"));
assertEquals("ZZabc", RegExUtils.replaceFirst((CharSequence) "abc", Pattern.compile(""), "ZZ"));

assertEquals("z\n<__>", RegExUtils.replaceFirst((CharSequence) "<__>\n<__>", Pattern.compile("<.*>"), "z"));
assertEquals("z", RegExUtils.replaceFirst((CharSequence) "<__>\n<__>", Pattern.compile("(?s)<.*>"), "z"));

assertEquals("ABC_bc123", RegExUtils.replaceFirst((CharSequence) "ABCabc123", Pattern.compile("[a-z]"), "_"));
assertEquals("ABC_123abc", RegExUtils.replaceFirst((CharSequence) "ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "_"));
assertEquals("ABC123abc", RegExUtils.replaceFirst((CharSequence) "ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), ""));
assertEquals("Lorem_ipsum dolor sit", RegExUtils.replaceFirst((CharSequence) "Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2"));
}

@Test
public void testReplaceFirstDeprecated() {
assertNull(RegExUtils.replaceFirst(null, Pattern.compile(""), ""));

assertEquals("any", RegExUtils.replaceFirst("any", (Pattern) null, ""));
Expand All @@ -252,8 +309,7 @@ public void testReplaceFirst_StringPatternString() {
assertEquals("ABC_bc123", RegExUtils.replaceFirst("ABCabc123", Pattern.compile("[a-z]"), "_"));
assertEquals("ABC_123abc", RegExUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "_"));
assertEquals("ABC123abc", RegExUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), ""));
assertEquals("Lorem_ipsum dolor sit",
RegExUtils.replaceFirst("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2"));
assertEquals("Lorem_ipsum dolor sit", RegExUtils.replaceFirst("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2"));
}

@Test
Expand Down

0 comments on commit 744a8c3

Please sign in to comment.