Repository: commons-lang Updated Branches: refs/heads/master 56f0e1053 -> 47c186298
LANG-1183 Making replacePattern/removePattern methods null safe in StringUtils Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/b1762bd5 Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/b1762bd5 Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/b1762bd5 Branch: refs/heads/master Commit: b1762bd557c3d7605490e026bdf31096d83b4dde Parents: 56f0e10 Author: Loic Guibert <[email protected]> Authored: Mon Nov 2 09:14:22 2015 +0400 Committer: Loic Guibert <[email protected]> Committed: Mon Nov 2 09:14:22 2015 +0400 ---------------------------------------------------------------------- .../org/apache/commons/lang3/StringUtils.java | 49 ++++++++++++++++++-- .../apache/commons/lang3/StringUtilsTest.java | 28 +++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/b1762bd5/src/main/java/org/apache/commons/lang3/StringUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java index 94c4288..7bf62d1 100644 --- a/src/main/java/org/apache/commons/lang3/StringUtils.java +++ b/src/main/java/org/apache/commons/lang3/StringUtils.java @@ -4671,14 +4671,31 @@ public class StringUtils { } /** - * 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. This call - * is also equivalent to: + * <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> + * + * This call is a {@code null} safe equivalent to: * <ul> * <li>{@code source.replaceAll("(?s)" + regex, replacement)}</li> * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(source).replaceAll(replacement)}</li> * </ul> * + * <p>A {@code null} reference passed to this method is a no-op.</p> + * + * <pre> + * StringUtils.replacePattern(null, *, *) = null + * StringUtils.replacePattern("any", null, *) = "any" + * StringUtils.replacePattern("any", *, null) = "any" + * StringUtils.replacePattern("", "", "zzz") = "zzz" + * StringUtils.replacePattern("", ".*", "zzz") = "zzz" + * StringUtils.replacePattern("", ".+", "zzz") = "" + * StringUtils.replacePattern("<__>\n<__>", "<.*>", "z") = "z" + * StringUtils.replacePattern("ABCabc123", "[a-z]", "_") = "ABC___123" + * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_") = "ABC_123" + * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "") = "ABC123" + * StringUtils.replacePattern("Lorem ipsum dolor sit", "( +)([a-z]+)", "_$2") = "Lorem_ipsum_dolor_sit" + * </pre> + * * @param source * the source string * @param regex @@ -4686,25 +4703,48 @@ public class StringUtils { * @param replacement * the string to be substituted for each match * @return The resulting {@code String} + * @see #replaceAll(String, String, String) * @see String#replaceAll(String, String) * @see Pattern#DOTALL * @since 3.2 + * @since 3.5 Changed {@code null} reference passed to this method is a no-op. */ public static String replacePattern(final String source, final String regex, final String replacement) { + if (source == null || regex == null|| replacement == null ) { + return source; + } return Pattern.compile(regex, Pattern.DOTALL).matcher(source).replaceAll(replacement); } /** - * Removes each substring of the source String that matches the given regular expression using the DOTALL option. + * <p>Removes each substring of the source String that matches the given regular expression using the DOTALL option. + * </p> + * + * This call is a {@code null} safe equivalent to: + * <ul> + * <li>{@code source.replaceAll("(?s)" + regex, StringUtils.EMPTY)}</li> + * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(source).replaceAll(StringUtils.EMPTY)}</li> + * </ul> + * + * <p>A {@code null} reference passed to this method is a no-op.</p> + * + * <pre> + * StringUtils.removePattern(null, *) = null + * StringUtils.removePattern("any", null) = "any" + * StringUtils.removePattern("A<__>\n<__>B", "<.*>") = "AB" + * StringUtils.removePattern("ABCabc123", "[a-z]") = "ABC123" + * </pre> * * @param source * the source string * @param regex * the regular expression to which this string is to be matched * @return The resulting {@code String} + * @see #replacePattern(String, String, String) * @see String#replaceAll(String, String) * @see Pattern#DOTALL * @since 3.2 + * @since 3.5 Changed {@code null} reference passed to this method is a no-op. */ public static String removePattern(final String source, final String regex) { return replacePattern(source, regex, StringUtils.EMPTY); @@ -4751,6 +4791,7 @@ public class StringUtils { * @throws java.util.regex.PatternSyntaxException * if the regular expression's syntax is invalid * + * @see #replacePattern(String, String, String) * @see String#replaceAll(String, String) * @see java.util.regex.Pattern * @see java.util.regex.Pattern#DOTALL http://git-wip-us.apache.org/repos/asf/commons-lang/blob/b1762bd5/src/test/java/org/apache/commons/lang3/StringUtilsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java index 25a709c..186da6d 100644 --- a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java @@ -1189,12 +1189,40 @@ public class StringUtilsTest { @Test public void testReplacePattern() { + assertNull(StringUtils.replacePattern(null, "", "")); + assertEquals("any", StringUtils.replacePattern("any", null, "")); + assertEquals("any", StringUtils.replacePattern("any", "", null)); + + assertEquals("zzz", StringUtils.replacePattern("", "", "zzz")); + assertEquals("zzz", StringUtils.replacePattern("", ".*", "zzz")); + assertEquals("", StringUtils.replacePattern("", ".+", "zzz")); + + assertEquals("z", StringUtils.replacePattern("<__>\n<__>", "<.*>", "z")); + assertEquals("z", StringUtils.replacePattern("<__>\\n<__>", "<.*>", "z")); assertEquals("X", StringUtils.replacePattern("<A>\nxy\n</A>", "<A>.*</A>", "X")); + + assertEquals("ABC___123", StringUtils.replacePattern("ABCabc123", "[a-z]", "_")); + assertEquals("ABC_123", StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_")); + assertEquals("ABC123", StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "")); + assertEquals("Lorem_ipsum_dolor_sit", + StringUtils.replacePattern("Lorem ipsum dolor sit", "( +)([a-z]+)", "_$2")); } @Test public void testRemovePattern() { + assertNull(StringUtils.removePattern(null, "")); + assertEquals("any", StringUtils.removePattern("any", null)); + + assertEquals("", StringUtils.removePattern("", "")); + assertEquals("", StringUtils.removePattern("", ".*")); + assertEquals("", StringUtils.removePattern("", ".+")); + + assertEquals("AB", StringUtils.removePattern("A<__>\n<__>B", "<.*>")); + assertEquals("AB", StringUtils.removePattern("A<__>\\n<__>B", "<.*>")); assertEquals("", StringUtils.removePattern("<A>x\\ny</A>", "<A>.*</A>")); + assertEquals("", StringUtils.removePattern("<A>\nxy\n</A>", "<A>.*</A>")); + + assertEquals("ABC123", StringUtils.removePattern("ABCabc123", "[a-z]")); } @Test
