You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lg...@apache.org on 2015/10/27 05:08:40 UTC

[1/2] [lang] LANG-1139: Add null safe methods in StringUtils to replace by regular expression : - StringUtils.replaceAll(String, String, String) - StringUtils.replaceFirst(String, String, String)

Repository: commons-lang
Updated Branches:
  refs/heads/master 849578d3a -> a6addf94e


LANG-1139: Add null safe methods in StringUtils to replace by regular expression :
  - StringUtils.replaceAll(String, String, String)
  - StringUtils.replaceFirst(String, String, String)


Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/3acffccf
Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/3acffccf
Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/3acffccf

Branch: refs/heads/master
Commit: 3acffccf15027bcf87e25a432f085c45e103b0ec
Parents: 0343b4f
Author: Loic Guibert <lf...@yahoo.fr>
Authored: Thu May 28 16:20:14 2015 +0400
Committer: Loic Guibert <lf...@yahoo.fr>
Committed: Thu May 28 16:20:14 2015 +0400

----------------------------------------------------------------------
 .../org/apache/commons/lang3/StringUtils.java   | 104 +++++++++++++++++++
 .../apache/commons/lang3/StringUtilsTest.java   |  57 ++++++++++
 2 files changed, 161 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-lang/blob/3acffccf/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 29d7098..b91d3b8 100644
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@ -25,6 +25,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 /**
  * <p>Operations on {@link java.lang.String} that are
@@ -4530,6 +4531,109 @@ public class StringUtils {
     }
 
     /**
+     * <p>Replaces each substring of the text String that matches the given regular expression
+     * with the given replacement.</p>
+     *
+     * This method is a {@code null} safe equivalent to:
+     * <ul>
+     *  <li>{@code text.replaceAll(regex, replacement)}</li>
+     *  <li>{@code Pattern.compile(regex).matcher(text).replaceAll(replacement)}</li>
+     * </ul>
+     *
+     * <p>A {@code null} reference passed to this method is a no-op.</p>
+     *
+     * <p>Unlike in the {@link #replacePattern(String, String, String)} method, the {@link Pattern#DOTALL} option
+     * is NOT automatically added.
+     * To use the DOTALL option prepend <code>"(?s)"</code> to the regex.
+     * DOTALL is also know as single-line mode in Perl.</p>
+     *
+     * <pre>
+     * StringUtils.replaceAll(null, *, *)       = null
+     * StringUtils.replaceAll("any", null, *)   = "any"
+     * StringUtils.replaceAll("any", *, null)   = "any"
+     * StringUtils.replaceAll("", "", "zzz")    = "zzz"
+     * StringUtils.replaceAll("", ".*", "zzz")  = "zzz"
+     * StringUtils.replaceAll("", ".+", "zzz")  = ""
+     * StringUtils.replaceAll("<__>\n<__>", "<.*>", "z")      = "z\nz"
+     * StringUtils.replaceAll("<__>\n<__>", "(?s)<.*>", "z")  = "z"
+     * StringUtils.replaceAll("ABCabc123", "[a-z]", "_")       = "ABC___123"
+     * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "_")  = "ABC_123"
+     * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "")   = "ABC123"
+     * StringUtils.replaceAll("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum_dolor_sit"
+     * </pre>
+     *
+     * @param text  text to search and replace in, may be null
+     * @param regex  the regular expression to which this string is to be matched
+     * @param replacement  the string to be substituted for each match
+     * @return  the text with any replacements processed,
+     *              {@code null} if null String input
+     *
+     * @throws  PatternSyntaxException
+     *              if the regular expression's syntax is invalid
+     *
+     * @see String#replaceAll(String, String)
+     * @see java.util.regex.Pattern
+     * @see java.util.regex.Pattern#DOTALL
+     */
+    public static String replaceAll(final String text, final String regex, final String replacement) {
+        if (text == null || regex == null|| replacement == null ) {
+            return text;
+        }
+        return text.replaceAll(regex, replacement);
+    }
+
+    /**
+     * <p>Replaces the first substring of the text string that matches the given regular expression
+     * with the given replacement.</p>
+     *
+     * This method is a {@code null} safe equivalent to:
+     * <ul>
+     *  <li>{@code text.replaceFirst(regex, replacement)}</li>
+     *  <li>{@code Pattern.compile(regex).matcher(text).replaceFirst(replacement)}</li>
+     * </ul>
+     *
+     * <p>A {@code null} reference passed to this method is a no-op.</p>
+     *
+     * <p>The {@link Pattern#DOTALL} option is NOT automatically added.
+     * To use the DOTALL option prepend <code>"(?s)"</code> to the regex.
+     * DOTALL is also know as single-line mode in Perl.</p>
+     *
+     * <pre>
+     * StringUtils.replaceFirst(null, *, *)       = null
+     * StringUtils.replaceFirst("any", null, *)   = "any"
+     * StringUtils.replaceFirst("any", *, null)   = "any"
+     * StringUtils.replaceFirst("", "", "zzz")    = "zzz"
+     * StringUtils.replaceFirst("", ".*", "zzz")  = "zzz"
+     * StringUtils.replaceFirst("", ".+", "zzz")  = ""
+     * StringUtils.replaceFirst("<__>\n<__>", "<.*>", "z")      = "z\n<__>"
+     * StringUtils.replaceFirst("<__>\n<__>", "(?s)<.*>", "z")  = "z"
+     * StringUtils.replaceFirst("ABCabc123", "[a-z]", "_")          = "ABC_bc123"
+     * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "_")  = "ABC_123abc"
+     * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "")   = "ABC123abc"
+     * StringUtils.replaceFirst("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum  dolor   sit"
+     * </pre>
+     *
+     * @param text  text to search and replace in, may be null
+     * @param regex  the regular expression 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
+     *
+     * @throws  PatternSyntaxException
+     *              if the regular expression's syntax is invalid
+     *
+     * @see String#replaceFirst(String, String)
+     * @see java.util.regex.Pattern
+     * @see java.util.regex.Pattern#DOTALL
+     */
+    public static String replaceFirst(final String text, final String regex, final String replacement) {
+        if (text == null || regex == null|| replacement == null ) {
+            return text;
+        }
+        return text.replaceFirst(regex, replacement);
+    }
+
+    /**
      * <p>Replaces all occurrences of a String within another String.</p>
      *
      * <p>A {@code null} reference passed to this method is a no-op.</p>

http://git-wip-us.apache.org/repos/asf/commons-lang/blob/3acffccf/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 a83eed6..40e4217 100644
--- a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
@@ -35,6 +35,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Locale;
+import java.util.regex.PatternSyntaxException;
 
 import org.apache.commons.lang3.text.WordUtils;
 import org.junit.Test;
@@ -1175,6 +1176,62 @@ public class StringUtilsTest {
     }
 
     @Test
+    public void testReplaceAll_StringStringString() {
+        assertNull(StringUtils.replaceAll(null, "", ""));
+
+        assertEquals("any", StringUtils.replaceAll("any", null, ""));
+        assertEquals("any", StringUtils.replaceAll("any", "", null));
+
+        assertEquals("zzz", StringUtils.replaceAll("", "", "zzz"));
+        assertEquals("zzz", StringUtils.replaceAll("", ".*", "zzz"));
+        assertEquals("", StringUtils.replaceAll("", ".+", "zzz"));
+
+        assertEquals("z\nz", StringUtils.replaceAll("<__>\n<__>", "<.*>", "z"));
+        assertEquals("z", StringUtils.replaceAll("<__>\n<__>", "(?s)<.*>", "z"));
+
+        assertEquals("ABC___123", StringUtils.replaceAll("ABCabc123", "[a-z]", "_"));
+        assertEquals("ABC_123", StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "_"));
+        assertEquals("ABC123", StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", ""));
+        assertEquals("Lorem_ipsum_dolor_sit",
+                     StringUtils.replaceAll("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2"));
+
+        try {
+            StringUtils.replaceAll("any", "{badRegexSyntax}", "");
+            fail("StringUtils.replaceAll expecting PatternSyntaxException");
+        } catch (final PatternSyntaxException ex) {
+            // empty
+        }
+    }
+
+    @Test
+    public void testReplaceFirst_StringStringString() {
+        assertNull(StringUtils.replaceFirst(null, "", ""));
+
+        assertEquals("any", StringUtils.replaceFirst("any", null, ""));
+        assertEquals("any", StringUtils.replaceFirst("any", "", null));
+
+        assertEquals("zzz", StringUtils.replaceFirst("", "", "zzz"));
+        assertEquals("zzz", StringUtils.replaceFirst("", ".*", "zzz"));
+        assertEquals("", StringUtils.replaceFirst("", ".+", "zzz"));
+
+        assertEquals("z\n<__>", StringUtils.replaceFirst("<__>\n<__>", "<.*>", "z"));
+        assertEquals("z", StringUtils.replaceFirst("<__>\n<__>", "(?s)<.*>", "z"));
+
+        assertEquals("ABC_bc123", StringUtils.replaceFirst("ABCabc123", "[a-z]", "_"));
+        assertEquals("ABC_123abc", StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "_"));
+        assertEquals("ABC123abc", StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", ""));
+        assertEquals("Lorem_ipsum  dolor   sit",
+                     StringUtils.replaceFirst("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2"));
+
+        try {
+            StringUtils.replaceFirst("any", "{badRegexSyntax}", "");
+            fail("StringUtils.replaceFirst expecting PatternSyntaxException");
+        } catch (final PatternSyntaxException ex) {
+            // empty
+        }
+    }
+
+    @Test
     public void testReplace_StringStringStringInt() {
         assertNull(StringUtils.replace(null, null, null, 2));
         assertNull(StringUtils.replace(null, null, "any", 2));


[2/2] [lang] Merge branch 'fix-LANG-1139'

Posted by lg...@apache.org.
Merge branch 'fix-LANG-1139'

LANG-1139: Add replace by regular expression methods in StringUtils
This closes #92 from github.


Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/a6addf94
Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/a6addf94
Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/a6addf94

Branch: refs/heads/master
Commit: a6addf94e5774f4e8fd71edbec68ff339c26e19f
Parents: 849578d 3acffcc
Author: Loic Guibert <lg...@apache.org>
Authored: Tue Oct 27 08:07:09 2015 +0400
Committer: Loic Guibert <lg...@apache.org>
Committed: Tue Oct 27 08:07:09 2015 +0400

----------------------------------------------------------------------
 src/changes/changes.xml                         |   1 +
 .../org/apache/commons/lang3/StringUtils.java   | 106 +++++++++++++++++++
 .../apache/commons/lang3/StringUtilsTest.java   |  57 ++++++++++
 3 files changed, 164 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-lang/blob/a6addf94/src/changes/changes.xml
----------------------------------------------------------------------
diff --cc src/changes/changes.xml
index 165f70d,c848755..7dee0d1
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@@ -22,18 -22,6 +22,19 @@@
    <body>
  
    <release version="3.5" date="tba" description="tba">
++    <action issue="LANG-1139" type="add" dev="lguibert">Add replace by regular expression methods in StringUtils</action>
 +    <action issue="LANG-1171" type="add" dev="lguibert">Add compare methods in StringUtils</action>
 +    <action issue="LANG-1174" type="add" dev="britter" due-to="Punkratz312">Add sugar to RandomUtils</action>
 +    <action issue="LANG-1057" type="update" dev="chas" due-to="Otávio Santana">Replace StringBuilder with String concatenation for better optimization</action>
 +    <action issue="LANG-1075" type="update" dev="chas">Deprecate SystemUtils.FILE_SEPARATOR and SystemUtils.PATH_SEPARATOR</action>
 +    <action issue="LANG-1154" type="add" dev="chas" due-to="Gary Gregory">FastDateFormat APIs that use a StringBuilder</action>
 +    <action issue="LANG-1149" type="add" dev="chas" due-to="Gregory Zak">Ability to throw checked exceptions without declaring them</action>
 +    <action issue="LANG-1002" type="fix" dev="chas" due-to="Michael Osipov">Several predefined ISO FastDateFormats in DateFormatUtils are incorrect</action>
 +    <action issue="LANG-1152" type="fix" dev="chas" due-to="Pas Filip">StringIndexOutOfBoundsException or field over-write for large year fields in FastDateParser</action>
 +    <action issue="LANG-1153" type="add" dev="chas">Implement ParsePosition api for FastDateParser</action>
 +    <action issue="LANG-1141" type="fix" dev="oheger">StrLookup.systemPropertiesLookup() no longer reacts on changes on system properties</action>
 +    <action issue="LANG-1147" type="fix" dev="sebb" due-to="Loic Guibert">EnumUtils *BitVector issue with more than 32 values Enum</action>
 +    <action issue="LANG-1059" type="fix" dev="sebb" due-to="Colin Casey">Capitalize javadoc is incorrect</action>
      <action issue="LANG-1137" type="add" dev="britter" due-to="Matthew Aguirre">Add check for duplicate event listener in EventListenerSupport</action>
      <action issue="LANG-1133" type="bug" dev="chas" due-to="Pascal Schumacher">FastDateParser_TimeZoneStrategyTest#testTimeZoneStrategyPattern fails on Windows with German Locale</action>
      <action issue="LANG-1135" type="add" dev="britter" due-to="Eduardo Martins">Add method containsAllWords to WordUtils</action>

http://git-wip-us.apache.org/repos/asf/commons-lang/blob/a6addf94/src/main/java/org/apache/commons/lang3/StringUtils.java
----------------------------------------------------------------------
diff --cc src/main/java/org/apache/commons/lang3/StringUtils.java
index e109714,b91d3b8..cb8fa41
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@@ -4711,6 -4531,109 +4712,111 @@@ public class StringUtils 
      }
  
      /**
+      * <p>Replaces each substring of the text String that matches the given regular expression
+      * with the given replacement.</p>
+      *
+      * This method is a {@code null} safe equivalent to:
+      * <ul>
+      *  <li>{@code text.replaceAll(regex, replacement)}</li>
+      *  <li>{@code Pattern.compile(regex).matcher(text).replaceAll(replacement)}</li>
+      * </ul>
+      *
+      * <p>A {@code null} reference passed to this method is a no-op.</p>
+      *
+      * <p>Unlike in the {@link #replacePattern(String, String, String)} method, the {@link Pattern#DOTALL} option
+      * is NOT automatically added.
+      * To use the DOTALL option prepend <code>"(?s)"</code> to the regex.
+      * DOTALL is also know as single-line mode in Perl.</p>
+      *
+      * <pre>
+      * StringUtils.replaceAll(null, *, *)       = null
+      * StringUtils.replaceAll("any", null, *)   = "any"
+      * StringUtils.replaceAll("any", *, null)   = "any"
+      * StringUtils.replaceAll("", "", "zzz")    = "zzz"
+      * StringUtils.replaceAll("", ".*", "zzz")  = "zzz"
+      * StringUtils.replaceAll("", ".+", "zzz")  = ""
+      * StringUtils.replaceAll("<__>\n<__>", "<.*>", "z")      = "z\nz"
+      * StringUtils.replaceAll("<__>\n<__>", "(?s)<.*>", "z")  = "z"
+      * StringUtils.replaceAll("ABCabc123", "[a-z]", "_")       = "ABC___123"
+      * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "_")  = "ABC_123"
+      * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "")   = "ABC123"
+      * StringUtils.replaceAll("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum_dolor_sit"
+      * </pre>
+      *
+      * @param text  text to search and replace in, may be null
+      * @param regex  the regular expression to which this string is to be matched
+      * @param replacement  the string to be substituted for each match
+      * @return  the text with any replacements processed,
+      *              {@code null} if null String input
+      *
+      * @throws  PatternSyntaxException
+      *              if the regular expression's syntax is invalid
+      *
+      * @see String#replaceAll(String, String)
+      * @see java.util.regex.Pattern
+      * @see java.util.regex.Pattern#DOTALL
++     * @since 3.5
+      */
+     public static String replaceAll(final String text, final String regex, final String replacement) {
+         if (text == null || regex == null|| replacement == null ) {
+             return text;
+         }
+         return text.replaceAll(regex, replacement);
+     }
+ 
+     /**
+      * <p>Replaces the first substring of the text string that matches the given regular expression
+      * with the given replacement.</p>
+      *
+      * This method is a {@code null} safe equivalent to:
+      * <ul>
+      *  <li>{@code text.replaceFirst(regex, replacement)}</li>
+      *  <li>{@code Pattern.compile(regex).matcher(text).replaceFirst(replacement)}</li>
+      * </ul>
+      *
+      * <p>A {@code null} reference passed to this method is a no-op.</p>
+      *
+      * <p>The {@link Pattern#DOTALL} option is NOT automatically added.
+      * To use the DOTALL option prepend <code>"(?s)"</code> to the regex.
+      * DOTALL is also know as single-line mode in Perl.</p>
+      *
+      * <pre>
+      * StringUtils.replaceFirst(null, *, *)       = null
+      * StringUtils.replaceFirst("any", null, *)   = "any"
+      * StringUtils.replaceFirst("any", *, null)   = "any"
+      * StringUtils.replaceFirst("", "", "zzz")    = "zzz"
+      * StringUtils.replaceFirst("", ".*", "zzz")  = "zzz"
+      * StringUtils.replaceFirst("", ".+", "zzz")  = ""
+      * StringUtils.replaceFirst("<__>\n<__>", "<.*>", "z")      = "z\n<__>"
+      * StringUtils.replaceFirst("<__>\n<__>", "(?s)<.*>", "z")  = "z"
+      * StringUtils.replaceFirst("ABCabc123", "[a-z]", "_")          = "ABC_bc123"
+      * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "_")  = "ABC_123abc"
+      * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "")   = "ABC123abc"
+      * StringUtils.replaceFirst("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum  dolor   sit"
+      * </pre>
+      *
+      * @param text  text to search and replace in, may be null
+      * @param regex  the regular expression 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
+      *
+      * @throws  PatternSyntaxException
+      *              if the regular expression's syntax is invalid
+      *
+      * @see String#replaceFirst(String, String)
+      * @see java.util.regex.Pattern
+      * @see java.util.regex.Pattern#DOTALL
++     * @since 3.5
+      */
+     public static String replaceFirst(final String text, final String regex, final String replacement) {
+         if (text == null || regex == null|| replacement == null ) {
+             return text;
+         }
+         return text.replaceFirst(regex, replacement);
+     }
+ 
+     /**
       * <p>Replaces all occurrences of a String within another String.</p>
       *
       * <p>A {@code null} reference passed to this method is a no-op.</p>

http://git-wip-us.apache.org/repos/asf/commons-lang/blob/a6addf94/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
----------------------------------------------------------------------