LANG-1183 Making replacePattern/removePattern methods null safe in StringUtils

This commit is contained in:
Loic Guibert 2015-11-02 09:14:22 +04:00
parent 56f0e1053c
commit b1762bd557
2 changed files with 73 additions and 4 deletions

View File

@ -4671,14 +4671,31 @@ public class StringUtils {
} }
/** /**
* Replaces each substring of the source String that matches the given regular expression with the given * <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. This call * replacement using the {@link Pattern#DOTALL} option. DOTALL is also know as single-line mode in Perl.</p>
* is also equivalent to: *
* This call is a {@code null} safe equivalent to:
* <ul> * <ul>
* <li>{@code source.replaceAll(&quot;(?s)&quot; + regex, replacement)}</li> * <li>{@code source.replaceAll(&quot;(?s)&quot; + regex, replacement)}</li>
* <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(source).replaceAll(replacement)}</li> * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(source).replaceAll(replacement)}</li>
* </ul> * </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 * @param source
* the source string * the source string
* @param regex * @param regex
@ -4686,25 +4703,48 @@ public class StringUtils {
* @param replacement * @param replacement
* the string to be substituted for each match * the string to be substituted for each match
* @return The resulting {@code String} * @return The resulting {@code String}
* @see #replaceAll(String, String, String)
* @see String#replaceAll(String, String) * @see String#replaceAll(String, String)
* @see Pattern#DOTALL * @see Pattern#DOTALL
* @since 3.2 * @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) { 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); 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(&quot;(?s)&quot; + 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 * @param source
* the source string * the source string
* @param regex * @param regex
* the regular expression to which this string is to be matched * the regular expression to which this string is to be matched
* @return The resulting {@code String} * @return The resulting {@code String}
* @see #replacePattern(String, String, String)
* @see String#replaceAll(String, String) * @see String#replaceAll(String, String)
* @see Pattern#DOTALL * @see Pattern#DOTALL
* @since 3.2 * @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) { public static String removePattern(final String source, final String regex) {
return replacePattern(source, regex, StringUtils.EMPTY); return replacePattern(source, regex, StringUtils.EMPTY);
@ -4751,6 +4791,7 @@ public class StringUtils {
* @throws java.util.regex.PatternSyntaxException * @throws java.util.regex.PatternSyntaxException
* if the regular expression's syntax is invalid * if the regular expression's syntax is invalid
* *
* @see #replacePattern(String, String, String)
* @see String#replaceAll(String, String) * @see String#replaceAll(String, String)
* @see java.util.regex.Pattern * @see java.util.regex.Pattern
* @see java.util.regex.Pattern#DOTALL * @see java.util.regex.Pattern#DOTALL

View File

@ -1189,12 +1189,40 @@ public class StringUtilsTest {
@Test @Test
public void testReplacePattern() { 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("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 @Test
public void testRemovePattern() { 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>x\\ny</A>", "<A>.*</A>"));
assertEquals("", StringUtils.removePattern("<A>\nxy\n</A>", "<A>.*</A>"));
assertEquals("ABC123", StringUtils.removePattern("ABCabc123", "[a-z]"));
} }
@Test @Test