    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.lang3;
    018
    019import java.util.regex.Pattern;
    020
    021/**
    022 * <p>Helpers to process Strings using regular expressions.</p>
    023 * @see java.util.regex.Pattern
    024 * @since 3.8
    025 */
    026public class RegExUtils {
    027
    028    /**
    029     * <p>Removes each substring of the text String that matches the given regular expression pattern.</p>
    030     *
    031     * This method is a {@code null} safe equivalent to:
    032     * <ul>
    033     *  <li>{@code pattern.matcher(text).replaceAll(StringUtils.EMPTY)}</li>
    034     * </ul>
    035     *
    036     * <p>A {@code null} reference passed to this method is a no-op.</p>
    037     *
    038     * <pre>
    039     * StringUtils.removeAll(null, *)      = null
    040     * StringUtils.removeAll("any", (Pattern) null)  = "any"
    041     * StringUtils.removeAll("any", Pattern.compile(""))    = "any"
    042     * StringUtils.removeAll("any", Pattern.compile(".*"))  = ""
    043     * StringUtils.removeAll("any", Pattern.compile(".+"))  = ""
    044     * StringUtils.removeAll("abc", Pattern.compile(".?"))  = ""
    045     * StringUtils.removeAll("A&lt;__&gt;\n&lt;__&gt;B", Pattern.compile("&lt;.*&gt;"))      = "A\nB"
    046     * StringUtils.removeAll("A&lt;__&gt;\n&lt;__&gt;B", Pattern.compile("(?s)&lt;.*&gt;"))  = "AB"
    047     * StringUtils.removeAll("A&lt;__&gt;\n&lt;__&gt;B", Pattern.compile("&lt;.*&gt;", Pattern.DOTALL))  = "AB"
    048     * StringUtils.removeAll("ABCabc123abc", Pattern.compile("[a-z]"))     = "ABC123"
    049     * </pre>
    050     *
    051     * @param text  text to remove from, may be null
    052     * @param regex  the regular expression to which this string is to be matched
    053     * @return  the text with any removes processed,
    054     *              {@code null} if null String input
    055     *
    056     * @see #replaceAll(String, Pattern, String)
    057     * @see java.util.regex.Matcher#replaceAll(String)
    058     * @see java.util.regex.Pattern
    059     */
    060    public static String removeAll(final String text, final Pattern regex) {
    061        return replaceAll(text, regex, StringUtils.EMPTY);
    062    }
    063
    064    /**
    065     * <p>Removes each substring of the text String that matches the given regular expression.</p>
    066     *
    067     * This method is a {@code null} safe equivalent to:
    068     * <ul>
    069     *  <li>{@code text.replaceAll(regex, StringUtils.EMPTY)}</li>
    070     *  <li>{@code Pattern.compile(regex).matcher(text).replaceAll(StringUtils.EMPTY)}</li>
    071     * </ul>
    072     *
    073     * <p>A {@code null} reference passed to this method is a no-op.</p>
    074     *
    075     * <p>Unlike in the {@link #removePattern(String, String)} method, the {@link Pattern#DOTALL} option
    076     * is NOT automatically added.
    077     * To use the DOTALL option prepend {@code "(?s)"} to the regex.
    078     * DOTALL is also known as single-line mode in Perl.</p>
    079     *
    080     * <pre>
    081     * StringUtils.removeAll(null, *)      = null
    082     * StringUtils.removeAll("any", (String) null)  = "any"
    083     * StringUtils.removeAll("any", "")    = "any"
    084     * StringUtils.removeAll("any", ".*")  = ""
    085     * StringUtils.removeAll("any", ".+")  = ""
    086     * StringUtils.removeAll("abc", ".?")  = ""
    087     * StringUtils.removeAll("A&lt;__&gt;\n&lt;__&gt;B", "&lt;.*&gt;")      = "A\nB"
    088     * StringUtils.removeAll("A&lt;__&gt;\n&lt;__&gt;B", "(?s)&lt;.*&gt;")  = "AB"
    089     * StringUtils.removeAll("ABCabc123abc", "[a-z]")     = "ABC123"
    090     * </pre>
    091     *
    092     * @param text  text to remove from, may be null
    093     * @param regex  the regular expression to which this string is to be matched
    094     * @return  the text with any removes processed,
    095     *              {@code null} if null String input
    096     *
    097     * @throws  java.util.regex.PatternSyntaxException
    098     *              if the regular expression's syntax is invalid
    099     *
    100     * @see #replaceAll(String, String, String)
    101     * @see #removePattern(String, String)
    102     * @see String#replaceAll(String, String)
    103     * @see java.util.regex.Pattern
    104     * @see java.util.regex.Pattern#DOTALL
    105     */
    106    public static String removeAll(final String text, final String regex) {
    107        return replaceAll(text, regex, StringUtils.EMPTY);
    108    }
    109
    110    /**
    111     * <p>Removes the first substring of the text string that matches the given regular expression pattern.</p>
    112     *
    113     * This method is a {@code null} safe equivalent to:
    114     * <ul>
    115     *  <li>{@code pattern.matcher(text).replaceFirst(StringUtils.EMPTY)}</li>
    116     * </ul>
    117     *
    118     * <p>A {@code null} reference passed to this method is a no-op.</p>
    119     *
    120     * <pre>
    121     * StringUtils.removeFirst(null, *)      = null
    122     * StringUtils.removeFirst("any", (Pattern) null)  = "any"
    123     * StringUtils.removeFirst("any", Pattern.compile(""))    = "any"
    124     * StringUtils.removeFirst("any", Pattern.compile(".*"))  = ""
    125     * StringUtils.removeFirst("any", Pattern.compile(".+"))  = ""
    126     * StringUtils.removeFirst("abc", Pattern.compile(".?"))  = "bc"
    127     * StringUtils.removeFirst("A&lt;__&gt;\n&lt;__&gt;B", Pattern.compile("&lt;.*&gt;"))      = "A\n&lt;__&gt;B"
    128     * StringUtils.removeFirst("A&lt;__&gt;\n&lt;__&gt;B", Pattern.compile("(?s)&lt;.*&gt;"))  = "AB"
    129     * StringUtils.removeFirst("ABCabc123", Pattern.compile("[a-z]"))          = "ABCbc123"
    130     * StringUtils.removeFirst("ABCabc123abc", Pattern.compile("[a-z]+"))      = "ABC123abc"
    131     * </pre>
    132     *
    133     * @param text  text to remove from, may be null
    134     * @param regex  the regular expression pattern to which this string is to be matched
    135     * @return  the text with the first replacement processed,
    136     *              {@code null} if null String input
    137     *
    138     * @see #replaceFirst(String, Pattern, String)
    139     * @see java.util.regex.Matcher#replaceFirst(String)
    140     * @see java.util.regex.Pattern
    141     */
    142    public static String removeFirst(final String text, final Pattern regex) {
    143        return replaceFirst(text, regex, StringUtils.EMPTY);
    144    }
    145
    146    /**
    147     * <p>Removes the first substring of the text string that matches the given regular expression.</p>
    148     *
    149     * This method is a {@code null} safe equivalent to:
    150     * <ul>
    151     *  <li>{@code text.replaceFirst(regex, StringUtils.EMPTY)}</li>
    152     *  <li>{@code Pattern.compile(regex).matcher(text).replaceFirst(StringUtils.EMPTY)}</li>
    153     * </ul>
    154     *
    155     * <p>A {@code null} reference passed to this method is a no-op.</p>
    156     *
    157     * <p>The {@link Pattern#DOTALL} option is NOT automatically added.
    158     * To use the DOTALL option prepend {@code "(?s)"} to the regex.
    159     * DOTALL is also known as single-line mode in Perl.</p>
    160     *
    161     * <pre>
    162     * StringUtils.removeFirst(null, *)      = null
    163     * StringUtils.removeFirst("any", (String) null)  = "any"
    164     * StringUtils.removeFirst("any", "")    = "any"
    165     * StringUtils.removeFirst("any", ".*")  = ""
    166     * StringUtils.removeFirst("any", ".+")  = ""
    167     * StringUtils.removeFirst("abc", ".?")  = "bc"
    168     * StringUtils.removeFirst("A&lt;__&gt;\n&lt;__&gt;B", "&lt;.*&gt;")      = "A\n&lt;__&gt;B"
    169     * StringUtils.removeFirst("A&lt;__&gt;\n&lt;__&gt;B", "(?s)&lt;.*&gt;")  = "AB"
    170     * StringUtils.removeFirst("ABCabc123", "[a-z]")          = "ABCbc123"
    171     * StringUtils.removeFirst("ABCabc123abc", "[a-z]+")      = "ABC123abc"
    172     * </pre>
    173     *
    174     * @param text  text to remove from, may be null
    175     * @param regex  the regular expression to which this string is to be matched
    176     * @return  the text with the first replacement processed,
    177     *              {@code null} if null String input
    178     *
    179     * @throws  java.util.regex.PatternSyntaxException
    180     *              if the regular expression's syntax is invalid
    181     *
    182     * @see #replaceFirst(String, String, String)
    183     * @see String#replaceFirst(String, String)
    184     * @see java.util.regex.Pattern
    185     * @see java.util.regex.Pattern#DOTALL
    186     */
    187    public static String removeFirst(final String text, final String regex) {
    188        return replaceFirst(text, regex, StringUtils.EMPTY);
    189    }
    190
    191    /**
    192     * <p>Removes each substring of the source String that matches the given regular expression using the DOTALL option.</p>
    193     *
    194     * This call is a {@code null} safe equivalent to:
    195     * <ul>
    196     * <li>{@code text.replaceAll(&quot;(?s)&quot; + regex, StringUtils.EMPTY)}</li>
    197     * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(StringUtils.EMPTY)}</li>
    198     * </ul>
    199     *
    200     * <p>A {@code null} reference passed to this method is a no-op.</p>
    201     *
    202     * <pre>
    203     * StringUtils.removePattern(null, *)       = null
    204     * StringUtils.removePattern("any", (String) null)   = "any"
    205     * StringUtils.removePattern("A&lt;__&gt;\n&lt;__&gt;B", "&lt;.*&gt;")  = "AB"
    206     * StringUtils.removePattern("ABCabc123", "[a-z]")    = "ABC123"
    207     * </pre>
    208     *
    209     * @param text
    210     *            the source string
    211     * @param regex
    212     *            the regular expression to which this string is to be matched
    213     * @return The resulting {@code String}
    214     * @see #replacePattern(String, String, String)
    215     * @see String#replaceAll(String, String)
    216     * @see Pattern#DOTALL
    217     */
    218    public static String removePattern(final String text, final String regex) {
    219        return replacePattern(text, regex, StringUtils.EMPTY);
    220    }
    221
    222    /**
    223     * <p>Replaces each substring of the text String that matches the given regular expression pattern with the given replacement.</p>
    224     *
    225     * This method is a {@code null} safe equivalent to:
    226     * <ul>
    227     *  <li>{@code pattern.matcher(text).replaceAll(replacement)}</li>
    228     * </ul>
    229     *
    230     * <p>A {@code null} reference passed to this method is a no-op.</p>
    231     *
    232     * <pre>
    233     * StringUtils.replaceAll(null, *, *)       = null
    234     * StringUtils.replaceAll("any", (Pattern) null, *)   = "any"
    235     * StringUtils.replaceAll("any", *, null)   = "any"
    236     * StringUtils.replaceAll("", Pattern.compile(""), "zzz")    = "zzz"
    237     * StringUtils.replaceAll("", Pattern.compile(".*"), "zzz")  = "zzz"
    238     * StringUtils.replaceAll("", Pattern.compile(".+"), "zzz")  = ""
    239     * StringUtils.replaceAll("abc", Pattern.compile(""), "ZZ")  = "ZZaZZbZZcZZ"
    240     * StringUtils.replaceAll("&lt;__&gt;\n&lt;__&gt;", Pattern.compile("&lt;.*&gt;"), "z")                 = "z\nz"
    241     * StringUtils.replaceAll("&lt;__&gt;\n&lt;__&gt;", Pattern.compile("&lt;.*&gt;", Pattern.DOTALL), "z") = "z"
    242     * StringUtils.replaceAll("&lt;__&gt;\n&lt;__&gt;", Pattern.compile("(?s)&lt;.*&gt;"), "z")             = "z"
    243     * StringUtils.replaceAll("ABCabc123", Pattern.compile("[a-z]"), "_")       = "ABC___123"
    244     * StringUtils.replaceAll("ABCabc123", Pattern.compile("[^A-Z0-9]+"), "_")  = "ABC_123"
    245     * StringUtils.replaceAll("ABCabc123", Pattern.compile("[^A-Z0-9]+"), "")   = "ABC123"
    246     * StringUtils.replaceAll("Lorem ipsum  dolor   sit", Pattern.compile("( +)([a-z]+)"), "_$2")  = "Lorem_ipsum_dolor_sit"
    247     * </pre>
    248     *
    249     * @param text  text to search and replace in, may be null
    250     * @param regex  the regular expression pattern to which this string is to be matched
    251     * @param replacement  the string to be substituted for each match
    252     * @return  the text with any replacements processed,
    253     *              {@code null} if null String input
    254     *
    255     * @see java.util.regex.Matcher#replaceAll(String)
    256     * @see java.util.regex.Pattern
    257     */
    258    public static String replaceAll(final String text, final Pattern regex, final String replacement) {
    259        if (text == null || regex == null || replacement == null) {
    260            return text;
    261        }
    262        return regex.matcher(text).replaceAll(replacement);
    263    }
    264
    265    /**
    266     * <p>Replaces each substring of the text String that matches the given regular expression
    267     * with the given replacement.</p>
    268     *
    269     * This method is a {@code null} safe equivalent to:
    270     * <ul>
    271     *  <li>{@code text.replaceAll(regex, replacement)}</li>
    272     *  <li>{@code Pattern.compile(regex).matcher(text).replaceAll(replacement)}</li>
    273     * </ul>
    274     *
    275     * <p>A {@code null} reference passed to this method is a no-op.</p>
    276     *
    277     * <p>Unlike in the {@link #replacePattern(String, String, String)} method, the {@link Pattern#DOTALL} option
    278     * is NOT automatically added.
    279     * To use the DOTALL option prepend {@code "(?s)"} to the regex.
    280     * DOTALL is also known as single-line mode in Perl.</p>
    281     *
    282     * <pre>
    283     * StringUtils.replaceAll(null, *, *)       = null
    284     * StringUtils.replaceAll("any", (String) null, *)   = "any"
    285     * StringUtils.replaceAll("any", *, null)   = "any"
    286     * StringUtils.replaceAll("", "", "zzz")    = "zzz"
    287     * StringUtils.replaceAll("", ".*", "zzz")  = "zzz"
    288     * StringUtils.replaceAll("", ".+", "zzz")  = ""
    289     * StringUtils.replaceAll("abc", "", "ZZ")  = "ZZaZZbZZcZZ"
    290     * StringUtils.replaceAll("&lt;__&gt;\n&lt;__&gt;", "&lt;.*&gt;", "z")      = "z\nz"
    291     * StringUtils.replaceAll("&lt;__&gt;\n&lt;__&gt;", "(?s)&lt;.*&gt;", "z")  = "z"
    292     * StringUtils.replaceAll("ABCabc123", "[a-z]", "_")       = "ABC___123"
    293     * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "_")  = "ABC_123"
    294     * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "")   = "ABC123"
    295     * StringUtils.replaceAll("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum_dolor_sit"
    296     * </pre>
    297     *
    298     * @param text  text to search and replace in, may be null
    299     * @param regex  the regular expression to which this string is to be matched
    300     * @param replacement  the string to be substituted for each match
    301     * @return  the text with any replacements processed,
    302     *              {@code null} if null String input
    303     *
    304     * @throws  java.util.regex.PatternSyntaxException
    305     *              if the regular expression's syntax is invalid
    306     *
    307     * @see #replacePattern(String, String, String)
    308     * @see String#replaceAll(String, String)
    309     * @see java.util.regex.Pattern
    310     * @see java.util.regex.Pattern#DOTALL
    311     */
    312    public static String replaceAll(final String text, final String regex, final String replacement) {
    313        if (text == null || regex == null || replacement == null) {
    314            return text;
    315        }
    316        return text.replaceAll(regex, replacement);
    317    }
    318
    319    /**
    320     * <p>Replaces the first substring of the text string that matches the given regular expression pattern
    321     * with the given replacement.</p>
    322     *
    323     * This method is a {@code null} safe equivalent to:
    324     * <ul>
    325     *  <li>{@code pattern.matcher(text).replaceFirst(replacement)}</li>
    326     * </ul>
    327     *
    328     * <p>A {@code null} reference passed to this method is a no-op.</p>
    329     *
    330     * <pre>
    331     * StringUtils.replaceFirst(null, *, *)       = null
    332     * StringUtils.replaceFirst("any", (Pattern) null, *)   = "any"
    333     * StringUtils.replaceFirst("any", *, null)   = "any"
    334     * StringUtils.replaceFirst("", Pattern.compile(""), "zzz")    = "zzz"
    335     * StringUtils.replaceFirst("", Pattern.compile(".*"), "zzz")  = "zzz"
    336     * StringUtils.replaceFirst("", Pattern.compile(".+"), "zzz")  = ""
    337     * StringUtils.replaceFirst("abc", Pattern.compile(""), "ZZ")  = "ZZabc"
    338     * StringUtils.replaceFirst("&lt;__&gt;\n&lt;__&gt;", Pattern.compile("&lt;.*&gt;"), "z")      = "z\n&lt;__&gt;"
    339     * StringUtils.replaceFirst("&lt;__&gt;\n&lt;__&gt;", Pattern.compile("(?s)&lt;.*&gt;"), "z")  = "z"
    340     * StringUtils.replaceFirst("ABCabc123", Pattern.compile("[a-z]"), "_")          = "ABC_bc123"
    341     * StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "_")  = "ABC_123abc"
    342     * StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "")   = "ABC123abc"
    343     * StringUtils.replaceFirst("Lorem ipsum  dolor   sit", Pattern.compile("( +)([a-z]+)"), "_$2")  = "Lorem_ipsum  dolor   sit"
    344     * </pre>
    345     *
    346     * @param text  text to search and replace in, may be null
    347     * @param regex  the regular expression pattern to which this string is to be matched
    348     * @param replacement  the string to be substituted for the first match
    349     * @return  the text with the first replacement processed,
    350     *              {@code null} if null String input
    351     *
    352     * @see java.util.regex.Matcher#replaceFirst(String)
    353     * @see java.util.regex.Pattern
    354     */
    355    public static String replaceFirst(final String text, final Pattern regex, final String replacement) {
    356        if (text == null || regex == null|| replacement == null ) {
    357            return text;
    358        }
    359        return regex.matcher(text).replaceFirst(replacement);
    360    }
    361
    362    /**
    363     * <p>Replaces the first substring of the text string that matches the given regular expression
    364     * with the given replacement.</p>
    365     *
    366     * This method is a {@code null} safe equivalent to:
    367     * <ul>
    368     *  <li>{@code text.replaceFirst(regex, replacement)}</li>
    369     *  <li>{@code Pattern.compile(regex).matcher(text).replaceFirst(replacement)}</li>
    370     * </ul>
    371     *
    372     * <p>A {@code null} reference passed to this method is a no-op.</p>
    373     *
    374     * <p>The {@link Pattern#DOTALL} option is NOT automatically added.
    375     * To use the DOTALL option prepend {@code "(?s)"} to the regex.
    376     * DOTALL is also known as single-line mode in Perl.</p>
    377     *
    378     * <pre>
    379     * StringUtils.replaceFirst(null, *, *)       = null
    380     * StringUtils.replaceFirst("any", (String) null, *)   = "any"
    381     * StringUtils.replaceFirst("any", *, null)   = "any"
    382     * StringUtils.replaceFirst("", "", "zzz")    = "zzz"
    383     * StringUtils.replaceFirst("", ".*", "zzz")  = "zzz"
    384     * StringUtils.replaceFirst("", ".+", "zzz")  = ""
    385     * StringUtils.replaceFirst("abc", "", "ZZ")  = "ZZabc"
    386     * StringUtils.replaceFirst("&lt;__&gt;\n&lt;__&gt;", "&lt;.*&gt;", "z")      = "z\n&lt;__&gt;"
    387     * StringUtils.replaceFirst("&lt;__&gt;\n&lt;__&gt;", "(?s)&lt;.*&gt;", "z")  = "z"
    388     * StringUtils.replaceFirst("ABCabc123", "[a-z]", "_")          = "ABC_bc123"
    389     * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "_")  = "ABC_123abc"
    390     * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "")   = "ABC123abc"
    391     * StringUtils.replaceFirst("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum  dolor   sit"
    392     * </pre>
    393     *
    394     * @param text  text to search and replace in, may be null
    395     * @param regex  the regular expression to which this string is to be matched
    396     * @param replacement  the string to be substituted for the first match
    397     * @return  the text with the first replacement processed,
    398     *              {@code null} if null String input
    399     *
    400     * @throws  java.util.regex.PatternSyntaxException
    401     *              if the regular expression's syntax is invalid
    402     *
    403     * @see String#replaceFirst(String, String)
    404     * @see java.util.regex.Pattern
    405     * @see java.util.regex.Pattern#DOTALL
    406     */
    407    public static String replaceFirst(final String text, final String regex, final String replacement) {
    408        if (text == null || regex == null|| replacement == null ) {
    409            return text;
    410        }
    411        return text.replaceFirst(regex, replacement);
    412    }
    413
    414    /**
    415     * <p>Replaces each substring of the source String that matches the given regular expression with the given
    416     * replacement using the {@link Pattern#DOTALL} option. DOTALL is also known as single-line mode in Perl.</p>
    417     *
    418     * This call is a {@code null} safe equivalent to:
    419     * <ul>
    420     * <li>{@code text.replaceAll(&quot;(?s)&quot; + regex, replacement)}</li>
    421     * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(replacement)}</li>
    422     * </ul>
    423     *
    424     * <p>A {@code null} reference passed to this method is a no-op.</p>
    425     *
    426     * <pre>
    427     * StringUtils.replacePattern(null, *, *)       = null
    428     * StringUtils.replacePattern("any", (String) null, *)   = "any"
    429     * StringUtils.replacePattern("any", *, null)   = "any"
    430     * StringUtils.replacePattern("", "", "zzz")    = "zzz"
    431     * StringUtils.replacePattern("", ".*", "zzz")  = "zzz"
    432     * StringUtils.replacePattern("", ".+", "zzz")  = ""
    433     * StringUtils.replacePattern("&lt;__&gt;\n&lt;__&gt;", "&lt;.*&gt;", "z")       = "z"
    434     * StringUtils.replacePattern("ABCabc123", "[a-z]", "_")       = "ABC___123"
    435     * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_")  = "ABC_123"
    436     * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "")   = "ABC123"
    437     * StringUtils.replacePattern("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum_dolor_sit"
    438     * </pre>
    439     *
    440     * @param text
    441     *            the source string
    442     * @param regex
    443     *            the regular expression to which this string is to be matched
    444     * @param replacement
    445     *            the string to be substituted for each match
    446     * @return The resulting {@code String}
    447     * @see #replaceAll(String, String, String)
    448     * @see String#replaceAll(String, String)
    449     * @see Pattern#DOTALL
    450     */
    451    public static String replacePattern(final String text, final String regex, final String replacement) {
    452        if (text == null || regex == null || replacement == null) {
    453            return text;
    454        }
    455        return Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(replacement);
    456    }
    457
    458}