StringUtils 方法

    技术2022-05-19  21

    /*  * Copyright 2002-2005 The Apache Software Foundation.  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package org.apache.commons.lang; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /**  * <p>Operations on {@link java.lang.String} that are  * <code>null</code> safe.</p>  *  * <ul>  *  <li><b>IsEmpty/IsBlank</b>  *      - checks if a String contains text</li>  *  <li><b>Trim/Strip</b>  *      - removes leading and trailing whitespace</li>  *  <li><b>Equals</b>  *      - compares two strings null-safe</li>  *  <li><b>IndexOf/LastIndexOf/Contains</b>  *      - null-safe index-of checks  *  <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>  *      - index-of any of a set of Strings</li>  *  <li><b>ContainsOnly/ContainsNone</b>  *      - does String contains only/none of these characters</li>  *  <li><b>Substring/Left/Right/Mid</b>  *      - null-safe substring extractions</li>  *  <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>  *      - substring extraction relative to other strings</li>  *  <li><b>Split/Join</b>  *      - splits a String into an array of substrings and vice versa</li>  *  <li><b>Remove/Delete</b>  *      - removes part of a String</li>  *  <li><b>Replace/Overlay</b>  *      - Searches a String and replaces one String with another</li>  *  <li><b>Chomp/Chop</b>  *      - removes the last part of a String</li>  *  <li><b>LeftPad/RightPad/Center/Repeat</b>  *      - pads a String</li>  *  <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>  *      - changes the case of a String</li>  *  <li><b>CountMatches</b>  *      - counts the number of occurrences of one String in another</li>  *  <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>  *      - checks the characters in a String</li>  *  <li><b>DefaultString</b>  *      - protects against a null input String</li>  *  <li><b>Reverse/ReverseDelimited</b>  *      - reverses a String</li>  *  <li><b>Abbreviate</b>  *      - abbreviates a string using ellipsis</li>  *  <li><b>Difference</b>  *      - compares two Strings and reports on their differences</li>  *  <li><b>LevensteinDistance</b>  *      - the number of changes needed to change one String into another</li>  * </ul>  *  * <p>The <code>StringUtils</code> class defines certain words related to  * String handling.</p>  *  * <ul>  *  <li>null - <code>null</code></li>  *  <li>empty - a zero-length string (<code>""</code>)</li>  *  <li>space - the space character (<code>' '</code>, char 32)</li>  *  <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li>  *  <li>trim - the characters <= 32 as in {@link String#trim()}</li>  * </ul>  *  * <p><code>StringUtils</code> handles <code>null</code> input Strings quietly.  * That is to say that a <code>null</code> input will return <code>null</code>.  * Where a <code>boolean</code> or <code>int</code> is being returned  * details vary by method.</p>  *  * <p>A side effect of the <code>null</code> handling is that a  * <code>NullPointerException</code> should be considered a bug in  * <code>StringUtils</code> (except for deprecated methods).</p>  *  * <p>Methods in this class give sample code to explain their operation.  * The symbol <code>*</code> is used to indicate any input including <code>null</code>.</p>  *  * @see java.lang.String  * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</a>  * @author GenerationJavaCore  * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>  * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>  * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>  * @author <a href="mailto:ed@apache.org">Ed Korthof</a>  * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>  * @author Stephen Colebourne  * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>  * @author Holger Krauth  * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>  * @author Arun Mammen Thomas  * @author Gary Gregory  * @author Phil Steitz  * @author Al Chou  * @author Michael Davey  * @since 1.0  * @version $Id: StringUtils.java 161243 2005-04-14 04:30:28Z ggregory $  */ public class StringUtils {     // Performance testing notes (JDK 1.4, Jul03, scolebourne)     // Whitespace:     // Character.isWhitespace() is faster than WHITESPACE.indexOf()     // where WHITESPACE is a string of all whitespace characters     //     // Character access:     // String.charAt(n) versus toCharArray(), then array[n]     // String.charAt(n) is about 15% worse for a 10K string     // They are about equal for a length 50 string     // String.charAt(n) is about 4 times better for a length 3 string     // String.charAt(n) is best bet overall     //     // Append:     // String.concat about twice as fast as StringBuffer.append     // (not sure who tested this)     /**      * The empty String <code>""</code>.      * @since 2.0      */     public static final String EMPTY = "";     /**      * Represents a failed index search.      * @since 2.1      */     public static final int INDEX_NOT_FOUND = -1;     /**      * <p>The maximum size to which the padding constant(s) can expand.</p>      */     private static final int PAD_LIMIT = 8192;     /**      * <p>An array of <code>String</code>s used for padding.</p>      *      * <p>Used for efficient space padding. The length of each String expands as needed.</p>      */     private static final String[] PADDING = new String[Character.MAX_VALUE];     static {         // space padding is most common, start with 64 chars         PADDING[32] = "                                                                ";     }     /**      * <p><code>StringUtils</code> instances should NOT be constructed in      * standard programming. Instead, the class should be used as      * <code>StringUtils.trim(" foo ");</code>.</p>      *      * <p>This constructor is public to permit tools that require a JavaBean      * instance to operate.</p>      */     public StringUtils() {         // no init.     }     // Empty checks     //-----------------------------------------------------------------------     /**      * <p>Checks if a String is empty ("") or null.</p>      *      * <pre>      * StringUtils.isEmpty(null)      = true      * StringUtils.isEmpty("")        = true      * StringUtils.isEmpty(" ")       = false      * StringUtils.isEmpty("bob")     = false      * StringUtils.isEmpty("  bob  ") = false      * </pre>      *      * <p>NOTE: This method changed in Lang version 2.0.      * It no longer trims the String.      * That functionality is available in isBlank().</p>      *      * @param str  the String to check, may be null      * @return <code>true</code> if the String is empty or null      */     public static boolean isEmpty(String str) {         return str == null || str.length() == 0;     }     /**      * <p>Checks if a String is not empty ("") and not null.</p>      *      * <pre>      * StringUtils.isNotEmpty(null)      = false      * StringUtils.isNotEmpty("")        = false      * StringUtils.isNotEmpty(" ")       = true      * StringUtils.isNotEmpty("bob")     = true      * StringUtils.isNotEmpty("  bob  ") = true      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if the String is not empty and not null      */     public static boolean isNotEmpty(String str) {         return str != null && str.length() > 0;     }     /**      * <p>Checks if a String is whitespace, empty ("") or null.</p>      *      * <pre>      * StringUtils.isBlank(null)      = true      * StringUtils.isBlank("")        = true      * StringUtils.isBlank(" ")       = true      * StringUtils.isBlank("bob")     = false      * StringUtils.isBlank("  bob  ") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if the String is null, empty or whitespace      * @since 2.0      */     public static boolean isBlank(String str) {         int strLen;         if (str == null || (strLen = str.length()) == 0) {             return true;         }         for (int i = 0; i < strLen; i++) {             if ((Character.isWhitespace(str.charAt(i)) == false)) {                 return false;             }         }         return true;     }     /**      * <p>Checks if a String is not empty (""), not null and not whitespace only.</p>      *      * <pre>      * StringUtils.isNotBlank(null)      = false      * StringUtils.isNotBlank("")        = false      * StringUtils.isNotBlank(" ")       = false      * StringUtils.isNotBlank("bob")     = true      * StringUtils.isNotBlank("  bob  ") = true      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if the String is      *  not empty and not null and not whitespace      * @since 2.0      */     public static boolean isNotBlank(String str) {         int strLen;         if (str == null || (strLen = str.length()) == 0) {             return false;         }         for (int i = 0; i < strLen; i++) {             if ((Character.isWhitespace(str.charAt(i)) == false)) {                 return true;             }         }         return false;     }     // Trim     //-----------------------------------------------------------------------     /**      * <p>Removes control characters (char <= 32) from both      * ends of this String, handling <code>null</code> by returning      * an empty String ("").</p>      *      * <pre>      * StringUtils.clean(null)          = ""      * StringUtils.clean("")            = ""      * StringUtils.clean("abc")         = "abc"      * StringUtils.clean("    abc    ") = "abc"      * StringUtils.clean("     ")       = ""      * </pre>      *      * @see java.lang.String#trim()      * @param str  the String to clean, may be null      * @return the trimmed text, never <code>null</code>      * @deprecated Use the clearer named {@link #trimToEmpty(String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String clean(String str) {         return str == null ? EMPTY : str.trim();     }     /**      * <p>Removes control characters (char <= 32) from both      * ends of this String, handling <code>null</code> by returning      * <code>null</code>.</p>      *      * <p>The String is trimmed using {@link String#trim()}.      * Trim removes start and end characters <= 32.      * To strip whitespace use {@link #strip(String)}.</p>      *      * <p>To trim your choice of characters, use the      * {@link #strip(String, String)} methods.</p>      *      * <pre>      * StringUtils.trim(null)          = null      * StringUtils.trim("")            = ""      * StringUtils.trim("     ")       = ""      * StringUtils.trim("abc")         = "abc"      * StringUtils.trim("    abc    ") = "abc"      * </pre>      *      * @param str  the String to be trimmed, may be null      * @return the trimmed string, <code>null</code> if null String input      */     public static String trim(String str) {         return str == null ? null : str.trim();     }     /**      * <p>Removes control characters (char <= 32) from both      * ends of this String returning <code>null</code> if the String is      * empty ("") after the trim or if it is <code>null</code>.      *      * <p>The String is trimmed using {@link String#trim()}.      * Trim removes start and end characters <= 32.      * To strip whitespace use {@link #stripToNull(String)}.</p>      *      * <pre>      * StringUtils.trimToNull(null)          = null      * StringUtils.trimToNull("")            = null      * StringUtils.trimToNull("     ")       = null      * StringUtils.trimToNull("abc")         = "abc"      * StringUtils.trimToNull("    abc    ") = "abc"      * </pre>      *      * @param str  the String to be trimmed, may be null      * @return the trimmed String,      *  <code>null</code> if only chars <= 32, empty or null String input      * @since 2.0      */     public static String trimToNull(String str) {         String ts = trim(str);         return isEmpty(ts) ? null : ts;     }     /**      * <p>Removes control characters (char <= 32) from both      * ends of this String returning an empty String ("") if the String      * is empty ("") after the trim or if it is <code>null</code>.      *      * <p>The String is trimmed using {@link String#trim()}.      * Trim removes start and end characters <= 32.      * To strip whitespace use {@link #stripToEmpty(String)}.</p>      *      * <pre>      * StringUtils.trimToEmpty(null)          = ""      * StringUtils.trimToEmpty("")            = ""      * StringUtils.trimToEmpty("     ")       = ""      * StringUtils.trimToEmpty("abc")         = "abc"      * StringUtils.trimToEmpty("    abc    ") = "abc"      * </pre>      *      * @param str  the String to be trimmed, may be null      * @return the trimmed String, or an empty String if <code>null</code> input      * @since 2.0      */     public static String trimToEmpty(String str) {         return str == null ? EMPTY : str.trim();     }     // Stripping     //-----------------------------------------------------------------------     /**      * <p>Strips whitespace from the start and end of a String.</p>      *      * <p>This is similar to {@link #trim(String)} but removes whitespace.      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.strip(null)     = null      * StringUtils.strip("")       = ""      * StringUtils.strip("   ")    = ""      * StringUtils.strip("abc")    = "abc"      * StringUtils.strip("  abc")  = "abc"      * StringUtils.strip("abc  ")  = "abc"      * StringUtils.strip(" abc ")  = "abc"      * StringUtils.strip(" ab c ") = "ab c"      * </pre>      *      * @param str  the String to remove whitespace from, may be null      * @return the stripped String, <code>null</code> if null String input      */     public static String strip(String str) {         return strip(str, null);     }     /**      * <p>Strips whitespace from the start and end of a String  returning      * <code>null</code> if the String is empty ("") after the strip.</p>      *      * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <pre>      * StringUtils.strip(null)     = null      * StringUtils.strip("")       = null      * StringUtils.strip("   ")    = null      * StringUtils.strip("abc")    = "abc"      * StringUtils.strip("  abc")  = "abc"      * StringUtils.strip("abc  ")  = "abc"      * StringUtils.strip(" abc ")  = "abc"      * StringUtils.strip(" ab c ") = "ab c"      * </pre>      *      * @param str  the String to be stripped, may be null      * @return the stripped String,      *  <code>null</code> if whitespace, empty or null String input      * @since 2.0      */     public static String stripToNull(String str) {         if (str == null) {             return null;         }         str = strip(str, null);         return str.length() == 0 ? null : str;     }     /**      * <p>Strips whitespace from the start and end of a String  returning      * an empty String if <code>null</code> input.</p>      *      * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <pre>      * StringUtils.strip(null)     = ""      * StringUtils.strip("")       = ""      * StringUtils.strip("   ")    = ""      * StringUtils.strip("abc")    = "abc"      * StringUtils.strip("  abc")  = "abc"      * StringUtils.strip("abc  ")  = "abc"      * StringUtils.strip(" abc ")  = "abc"      * StringUtils.strip(" ab c ") = "ab c"      * </pre>      *      * @param str  the String to be stripped, may be null      * @return the trimmed String, or an empty String if <code>null</code> input      * @since 2.0      */     public static String stripToEmpty(String str) {         return str == null ? EMPTY : strip(str, null);     }     /**      * <p>Strips any of a set of characters from the start and end of a String.      * This is similar to {@link String#trim()} but allows the characters      * to be stripped to be controlled.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * An empty string ("") input returns the empty string.</p>      *      * <p>If the stripChars String is <code>null</code>, whitespace is      * stripped as defined by {@link Character#isWhitespace(char)}.      * Alternatively use {@link #strip(String)}.</p>      *      * <pre>      * StringUtils.strip(null, *)          = null      * StringUtils.strip("", *)            = ""      * StringUtils.strip("abc", null)      = "abc"      * StringUtils.strip("  abc", null)    = "abc"      * StringUtils.strip("abc  ", null)    = "abc"      * StringUtils.strip(" abc ", null)    = "abc"      * StringUtils.strip("  abcyx", "xyz") = "  abc"      * </pre>      *      * @param str  the String to remove characters from, may be null      * @param stripChars  the characters to remove, null treated as whitespace      * @return the stripped String, <code>null</code> if null String input      */     public static String strip(String str, String stripChars) {         if (isEmpty(str)) {             return str;         }         str = stripStart(str, stripChars);         return stripEnd(str, stripChars);     }     /**      * <p>Strips any of a set of characters from the start of a String.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * An empty string ("") input returns the empty string.</p>      *      * <p>If the stripChars String is <code>null</code>, whitespace is      * stripped as defined by {@link Character#isWhitespace(char)}.</p>      *      * <pre>      * StringUtils.stripStart(null, *)          = null      * StringUtils.stripStart("", *)            = ""      * StringUtils.stripStart("abc", "")        = "abc"      * StringUtils.stripStart("abc", null)      = "abc"      * StringUtils.stripStart("  abc", null)    = "abc"      * StringUtils.stripStart("abc  ", null)    = "abc  "      * StringUtils.stripStart(" abc ", null)    = "abc "      * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "      * </pre>      *      * @param str  the String to remove characters from, may be null      * @param stripChars  the characters to remove, null treated as whitespace      * @return the stripped String, <code>null</code> if null String input      */     public static String stripStart(String str, String stripChars) {         int strLen;         if (str == null || (strLen = str.length()) == 0) {             return str;         }         int start = 0;         if (stripChars == null) {             while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {                 start++;             }         } else if (stripChars.length() == 0) {             return str;         } else {             while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) {                 start++;             }         }         return str.substring(start);     }     /**      * <p>Strips any of a set of characters from the end of a String.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * An empty string ("") input returns the empty string.</p>      *      * <p>If the stripChars String is <code>null</code>, whitespace is      * stripped as defined by {@link Character#isWhitespace(char)}.</p>      *      * <pre>      * StringUtils.stripEnd(null, *)          = null      * StringUtils.stripEnd("", *)            = ""      * StringUtils.stripEnd("abc", "")        = "abc"      * StringUtils.stripEnd("abc", null)      = "abc"      * StringUtils.stripEnd("  abc", null)    = "  abc"      * StringUtils.stripEnd("abc  ", null)    = "abc"      * StringUtils.stripEnd(" abc ", null)    = " abc"      * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"      * </pre>      *      * @param str  the String to remove characters from, may be null      * @param stripChars  the characters to remove, null treated as whitespace      * @return the stripped String, <code>null</code> if null String input      */     public static String stripEnd(String str, String stripChars) {         int end;         if (str == null || (end = str.length()) == 0) {             return str;         }         if (stripChars == null) {             while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {                 end--;             }         } else if (stripChars.length() == 0) {             return str;         } else {             while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {                 end--;             }         }         return str.substring(0, end);     }     // StripAll     //-----------------------------------------------------------------------     /**      * <p>Strips whitespace from the start and end of every String in an array.      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <p>A new array is returned each time, except for length zero.      * A <code>null</code> array will return <code>null</code>.      * An empty array will return itself.      * A <code>null</code> array entry will be ignored.</p>      *      * <pre>      * StringUtils.stripAll(null)             = null      * StringUtils.stripAll([])               = []      * StringUtils.stripAll(["abc", "  abc"]) = ["abc", "abc"]      * StringUtils.stripAll(["abc  ", null])  = ["abc", null]      * </pre>      *      * @param strs  the array to remove whitespace from, may be null      * @return the stripped Strings, <code>null</code> if null array input      */     public static String[] stripAll(String[] strs) {         return stripAll(strs, null);     }     /**      * <p>Strips any of a set of characters from the start and end of every      * String in an array.</p>      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <p>A new array is returned each time, except for length zero.      * A <code>null</code> array will return <code>null</code>.      * An empty array will return itself.      * A <code>null</code> array entry will be ignored.      * A <code>null</code> stripChars will strip whitespace as defined by      * {@link Character#isWhitespace(char)}.</p>      *      * <pre>      * StringUtils.stripAll(null, *)                = null      * StringUtils.stripAll([], *)                  = []      * StringUtils.stripAll(["abc", "  abc"], null) = ["abc", "abc"]      * StringUtils.stripAll(["abc  ", null], null)  = ["abc", null]      * StringUtils.stripAll(["abc  ", null], "yz")  = ["abc  ", null]      * StringUtils.stripAll(["yabcz", null], "yz")  = ["abc", null]      * </pre>      *      * @param strs  the array to remove characters from, may be null      * @param stripChars  the characters to remove, null treated as whitespace      * @return the stripped Strings, <code>null</code> if null array input      */     public static String[] stripAll(String[] strs, String stripChars) {         int strsLen;         if (strs == null || (strsLen = strs.length) == 0) {             return strs;         }         String[] newArr = new String[strsLen];         for (int i = 0; i < strsLen; i++) {             newArr[i] = strip(strs[i], stripChars);         }         return newArr;     }     // Equals     //-----------------------------------------------------------------------     /**      * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>      *      * <p><code>null</code>s are handled without exceptions. Two <code>null</code>      * references are considered to be equal. The comparison is case sensitive.</p>      *      * <pre>      * StringUtils.equals(null, null)   = true      * StringUtils.equals(null, "abc")  = false      * StringUtils.equals("abc", null)  = false      * StringUtils.equals("abc", "abc") = true      * StringUtils.equals("abc", "ABC") = false      * </pre>      *      * @see java.lang.String#equals(Object)      * @param str1  the first String, may be null      * @param str2  the second String, may be null      * @return <code>true</code> if the Strings are equal, case sensitive, or      *  both <code>null</code>      */     public static boolean equals(String str1, String str2) {         return str1 == null ? str2 == null : str1.equals(str2);     }     /**      * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring      * the case.</p>      *      * <p><code>null</code>s are handled without exceptions. Two <code>null</code>      * references are considered equal. Comparison is case insensitive.</p>      *      * <pre>      * StringUtils.equalsIgnoreCase(null, null)   = true      * StringUtils.equalsIgnoreCase(null, "abc")  = false      * StringUtils.equalsIgnoreCase("abc", null)  = false      * StringUtils.equalsIgnoreCase("abc", "abc") = true      * StringUtils.equalsIgnoreCase("abc", "ABC") = true      * </pre>      *      * @see java.lang.String#equalsIgnoreCase(String)      * @param str1  the first String, may be null      * @param str2  the second String, may be null      * @return <code>true</code> if the Strings are equal, case insensitive, or      *  both <code>null</code>      */     public static boolean equalsIgnoreCase(String str1, String str2) {         return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);     }     // IndexOf     //-----------------------------------------------------------------------     /**      * <p>Finds the first index within a String, handling <code>null</code>.      * This method uses {@link String#indexOf(int)}.</p>      *      * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOf(null, *)         = -1      * StringUtils.indexOf("", *)           = -1      * StringUtils.indexOf("aabaabaa", 'a') = 0      * StringUtils.indexOf("aabaabaa", 'b') = 2      * </pre>      *      * @param str  the String to check, may be null      * @param searchChar  the character to find      * @return the first index of the search character,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int indexOf(String str, char searchChar) {         if (isEmpty(str)) {             return -1;         }         return str.indexOf(searchChar);     }     /**      * <p>Finds the first index within a String from a start position,      * handling <code>null</code>.      * This method uses {@link String#indexOf(int, int)}.</p>      *      * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.      * A negative start position is treated as zero.      * A start position greater than the string length returns <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOf(null, *, *)          = -1      * StringUtils.indexOf("", *, *)            = -1      * StringUtils.indexOf("aabaabaa", 'b', 0)  = 2      * StringUtils.indexOf("aabaabaa", 'b', 3)  = 5      * StringUtils.indexOf("aabaabaa", 'b', 9)  = -1      * StringUtils.indexOf("aabaabaa", 'b', -1) = 2      * </pre>      *      * @param str  the String to check, may be null      * @param searchChar  the character to find      * @param startPos  the start position, negative treated as zero      * @return the first index of the search character,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int indexOf(String str, char searchChar, int startPos) {         if (isEmpty(str)) {             return -1;         }         return str.indexOf(searchChar, startPos);     }     /**      * <p>Finds the first index within a String, handling <code>null</code>.      * This method uses {@link String#indexOf(String)}.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOf(null, *)          = -1      * StringUtils.indexOf(*, null)          = -1      * StringUtils.indexOf("", "")           = 0      * StringUtils.indexOf("aabaabaa", "a")  = 0      * StringUtils.indexOf("aabaabaa", "b")  = 2      * StringUtils.indexOf("aabaabaa", "ab") = 1      * StringUtils.indexOf("aabaabaa", "")   = 0      * </pre>      *      * @param str  the String to check, may be null      * @param searchStr  the String to find, may be null      * @return the first index of the search String,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int indexOf(String str, String searchStr) {         if (str == null || searchStr == null) {             return -1;         }         return str.indexOf(searchStr);     }     /**      * <p>Finds the n-th index within a String, handling <code>null</code>.      * This method uses {@link String#indexOf(String)}.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.ordinalIndexOf(null, *, *)          = -1      * StringUtils.ordinalIndexOf(*, null, *)          = -1      * StringUtils.ordinalIndexOf("", "", *)           = 0      * StringUtils.ordinalIndexOf("aabaabaa", "a", 1)  = 0      * StringUtils.ordinalIndexOf("aabaabaa", "a", 2)  = 1      * StringUtils.ordinalIndexOf("aabaabaa", "b", 1)  = 2      * StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  = 5      * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1      * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4      * StringUtils.ordinalIndexOf("aabaabaa", "", 1)   = 0      * StringUtils.ordinalIndexOf("aabaabaa", "", 2)   = 0      * </pre>      *      * @param str  the String to check, may be null      * @param searchStr  the String to find, may be null      * @param ordinal  the n-th <code>searchStr</code> to find      * @return the n-th index of the search String,      *  <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input      * @since 2.1      */     public static int ordinalIndexOf(String str, String searchStr, int ordinal) {         if (str == null || searchStr == null || ordinal <= 0) {             return INDEX_NOT_FOUND;         }         if (searchStr.length() == 0) {             return 0;         }         int found = 0;         int index = INDEX_NOT_FOUND;         do {             index = str.indexOf(searchStr, index + 1);             if (index < 0) {                 return index;             }             found++;         } while (found < ordinal);         return index;     }     /**      * <p>Finds the first index within a String, handling <code>null</code>.      * This method uses {@link String#indexOf(String, int)}.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A negative start position is treated as zero.      * An empty ("") search String always matches.      * A start position greater than the string length only matches      * an empty search String.</p>      *      * <pre>      * StringUtils.indexOf(null, *, *)          = -1      * StringUtils.indexOf(*, null, *)          = -1      * StringUtils.indexOf("", "", 0)           = 0      * StringUtils.indexOf("aabaabaa", "a", 0)  = 0      * StringUtils.indexOf("aabaabaa", "b", 0)  = 2      * StringUtils.indexOf("aabaabaa", "ab", 0) = 1      * StringUtils.indexOf("aabaabaa", "b", 3)  = 5      * StringUtils.indexOf("aabaabaa", "b", 9)  = -1      * StringUtils.indexOf("aabaabaa", "b", -1) = 2      * StringUtils.indexOf("aabaabaa", "", 2)   = 2      * StringUtils.indexOf("abc", "", 9)        = 3      * </pre>      *      * @param str  the String to check, may be null      * @param searchStr  the String to find, may be null      * @param startPos  the start position, negative treated as zero      * @return the first index of the search String,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int indexOf(String str, String searchStr, int startPos) {         if (str == null || searchStr == null) {             return -1;         }         // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence         if (searchStr.length() == 0 && startPos >= str.length()) {             return str.length();         }         return str.indexOf(searchStr, startPos);     }     // LastIndexOf     //-----------------------------------------------------------------------     /**      * <p>Finds the last index within a String, handling <code>null</code>.      * This method uses {@link String#lastIndexOf(int)}.</p>      *      * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.lastIndexOf(null, *)         = -1      * StringUtils.lastIndexOf("", *)           = -1      * StringUtils.lastIndexOf("aabaabaa", 'a') = 7      * StringUtils.lastIndexOf("aabaabaa", 'b') = 5      * </pre>      *      * @param str  the String to check, may be null      * @param searchChar  the character to find      * @return the last index of the search character,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int lastIndexOf(String str, char searchChar) {         if (isEmpty(str)) {             return -1;         }         return str.lastIndexOf(searchChar);     }     /**      * <p>Finds the last index within a String from a start position,      * handling <code>null</code>.      * This method uses {@link String#lastIndexOf(int, int)}.</p>      *      * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.      * A negative start position returns <code>-1</code>.      * A start position greater than the string length searches the whole string.</p>      *      * <pre>      * StringUtils.lastIndexOf(null, *, *)          = -1      * StringUtils.lastIndexOf("", *,  *)           = -1      * StringUtils.lastIndexOf("aabaabaa", 'b', 8)  = 5      * StringUtils.lastIndexOf("aabaabaa", 'b', 4)  = 2      * StringUtils.lastIndexOf("aabaabaa", 'b', 0)  = -1      * StringUtils.lastIndexOf("aabaabaa", 'b', 9)  = 5      * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1      * StringUtils.lastIndexOf("aabaabaa", 'a', 0)  = 0      * </pre>      *      * @param str  the String to check, may be null      * @param searchChar  the character to find      * @param startPos  the start position      * @return the last index of the search character,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int lastIndexOf(String str, char searchChar, int startPos) {         if (isEmpty(str)) {             return -1;         }         return str.lastIndexOf(searchChar, startPos);     }     /**      * <p>Finds the last index within a String, handling <code>null</code>.      * This method uses {@link String#lastIndexOf(String)}.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.lastIndexOf(null, *)          = -1      * StringUtils.lastIndexOf(*, null)          = -1      * StringUtils.lastIndexOf("", "")           = 0      * StringUtils.lastIndexOf("aabaabaa", "a")  = 0      * StringUtils.lastIndexOf("aabaabaa", "b")  = 2      * StringUtils.lastIndexOf("aabaabaa", "ab") = 1      * StringUtils.lastIndexOf("aabaabaa", "")   = 8      * </pre>      *      * @param str  the String to check, may be null      * @param searchStr  the String to find, may be null      * @return the last index of the search String,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int lastIndexOf(String str, String searchStr) {         if (str == null || searchStr == null) {             return -1;         }         return str.lastIndexOf(searchStr);     }     /**      * <p>Finds the first index within a String, handling <code>null</code>.      * This method uses {@link String#lastIndexOf(String, int)}.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A negative start position returns <code>-1</code>.      * An empty ("") search String always matches unless the start position is negative.      * A start position greater than the string length searches the whole string.</p>      *      * <pre>      * StringUtils.lastIndexOf(null, *, *)          = -1      * StringUtils.lastIndexOf(*, null, *)          = -1      * StringUtils.lastIndexOf("aabaabaa", "a", 8)  = 7      * StringUtils.lastIndexOf("aabaabaa", "b", 8)  = 5      * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4      * StringUtils.lastIndexOf("aabaabaa", "b", 9)  = 5      * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1      * StringUtils.lastIndexOf("aabaabaa", "a", 0)  = 0      * StringUtils.lastIndexOf("aabaabaa", "b", 0)  = -1      * </pre>      *      * @param str  the String to check, may be null      * @param searchStr  the String to find, may be null      * @param startPos  the start position, negative treated as zero      * @return the first index of the search String,      *  -1 if no match or <code>null</code> string input      * @since 2.0      */     public static int lastIndexOf(String str, String searchStr, int startPos) {         if (str == null || searchStr == null) {             return -1;         }         return str.lastIndexOf(searchStr, startPos);     }     // Contains     //-----------------------------------------------------------------------     /**      * <p>Checks if String contains a search character, handling <code>null</code>.      * This method uses {@link String#indexOf(int)}.</p>      *      * <p>A <code>null</code> or empty ("") String will return <code>false</code>.</p>      *      * <pre>      * StringUtils.contains(null, *)    = false      * StringUtils.contains("", *)      = false      * StringUtils.contains("abc", 'a') = true      * StringUtils.contains("abc", 'z') = false      * </pre>      *      * @param str  the String to check, may be null      * @param searchChar  the character to find      * @return true if the String contains the search character,      *  false if not or <code>null</code> string input      * @since 2.0      */     public static boolean contains(String str, char searchChar) {         if (isEmpty(str)) {             return false;         }         return str.indexOf(searchChar) >= 0;     }     /**      * <p>Checks if String contains a search String, handling <code>null</code>.      * This method uses {@link String#indexOf(int)}.</p>      *      * <p>A <code>null</code> String will return <code>false</code>.</p>      *      * <pre>      * StringUtils.contains(null, *)     = false      * StringUtils.contains(*, null)     = false      * StringUtils.contains("", "")      = true      * StringUtils.contains("abc", "")   = true      * StringUtils.contains("abc", "a")  = true      * StringUtils.contains("abc", "z")  = false      * </pre>      *      * @param str  the String to check, may be null      * @param searchStr  the String to find, may be null      * @return true if the String contains the search String,      *  false if not or <code>null</code> string input      * @since 2.0      */     public static boolean contains(String str, String searchStr) {         if (str == null || searchStr == null) {             return false;         }         return str.indexOf(searchStr) >= 0;     }     // IndexOfAny chars     //-----------------------------------------------------------------------     /**      * <p>Search a String to find the first index of any      * character in the given set of characters.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A <code>null</code> or zero length search array will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOfAny(null, *)                = -1      * StringUtils.indexOfAny("", *)                  = -1      * StringUtils.indexOfAny(*, null)                = -1      * StringUtils.indexOfAny(*, [])                  = -1      * StringUtils.indexOfAny("zzabyycdxx",['z','a']) = 0      * StringUtils.indexOfAny("zzabyycdxx",['b','y']) = 3      * StringUtils.indexOfAny("aba", ['z'])           = -1      * </pre>      *      * @param str  the String to check, may be null      * @param searchChars  the chars to search for, may be null      * @return the index of any of the chars, -1 if no match or null input      * @since 2.0      */     public static int indexOfAny(String str, char[] searchChars) {         if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {             return -1;         }         for (int i = 0; i < str.length(); i++) {             char ch = str.charAt(i);             for (int j = 0; j < searchChars.length; j++) {                 if (searchChars[j] == ch) {                     return i;                 }             }         }         return -1;     }     /**      * <p>Search a String to find the first index of any      * character in the given set of characters.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A <code>null</code> search string will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOfAny(null, *)            = -1      * StringUtils.indexOfAny("", *)              = -1      * StringUtils.indexOfAny(*, null)            = -1      * StringUtils.indexOfAny(*, "")              = -1      * StringUtils.indexOfAny("zzabyycdxx", "za") = 0      * StringUtils.indexOfAny("zzabyycdxx", "by") = 3      * StringUtils.indexOfAny("aba","z")          = -1      * </pre>      *      * @param str  the String to check, may be null      * @param searchChars  the chars to search for, may be null      * @return the index of any of the chars, -1 if no match or null input      * @since 2.0      */     public static int indexOfAny(String str, String searchChars) {         if (isEmpty(str) || isEmpty(searchChars)) {             return -1;         }         return indexOfAny(str, searchChars.toCharArray());     }     // IndexOfAnyBut chars     //-----------------------------------------------------------------------     /**      * <p>Search a String to find the first index of any      * character not in the given set of characters.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A <code>null</code> or zero length search array will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOfAnyBut(null, *)           = -1      * StringUtils.indexOfAnyBut("", *)             = -1      * StringUtils.indexOfAnyBut(*, null)           = -1      * StringUtils.indexOfAnyBut(*, [])             = -1      * StringUtils.indexOfAnyBut("zzabyycdxx",'za') = 3      * StringUtils.indexOfAnyBut("zzabyycdxx", '')  = 0      * StringUtils.indexOfAnyBut("aba", 'ab')       = -1      * </pre>      *      * @param str  the String to check, may be null      * @param searchChars  the chars to search for, may be null      * @return the index of any of the chars, -1 if no match or null input      * @since 2.0      */     public static int indexOfAnyBut(String str, char[] searchChars) {         if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {             return -1;         }         outer : for (int i = 0; i < str.length(); i++) {             char ch = str.charAt(i);             for (int j = 0; j < searchChars.length; j++) {                 if (searchChars[j] == ch) {                     continue outer;                 }             }             return i;         }         return -1;     }     /**      * <p>Search a String to find the first index of any      * character not in the given set of characters.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A <code>null</code> search string will return <code>-1</code>.</p>      *      * <pre>      * StringUtils.indexOfAnyBut(null, *)            = -1      * StringUtils.indexOfAnyBut("", *)              = -1      * StringUtils.indexOfAnyBut(*, null)            = -1      * StringUtils.indexOfAnyBut(*, "")              = -1      * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3      * StringUtils.indexOfAnyBut("zzabyycdxx", "")   = 0      * StringUtils.indexOfAnyBut("aba","ab")         = -1      * </pre>      *      * @param str  the String to check, may be null      * @param searchChars  the chars to search for, may be null      * @return the index of any of the chars, -1 if no match or null input      * @since 2.0      */     public static int indexOfAnyBut(String str, String searchChars) {         if (isEmpty(str) || isEmpty(searchChars)) {             return -1;         }         for (int i = 0; i < str.length(); i++) {             if (searchChars.indexOf(str.charAt(i)) < 0) {                 return i;             }         }         return -1;     }     // ContainsOnly     //-----------------------------------------------------------------------     /**      * <p>Checks if the String contains only certain characters.</p>      *      * <p>A <code>null</code> String will return <code>false</code>.      * A <code>null</code> valid character array will return <code>false</code>.      * An empty String ("") always returns <code>true</code>.</p>      *      * <pre>      * StringUtils.containsOnly(null, *)       = false      * StringUtils.containsOnly(*, null)       = false      * StringUtils.containsOnly("", *)         = true      * StringUtils.containsOnly("ab", '')      = false      * StringUtils.containsOnly("abab", 'abc') = true      * StringUtils.containsOnly("ab1", 'abc')  = false      * StringUtils.containsOnly("abz", 'abc')  = false      * </pre>      *      * @param str  the String to check, may be null      * @param valid  an array of valid chars, may be null      * @return true if it only contains valid chars and is non-null      */     public static boolean containsOnly(String str, char[] valid) {         // All these pre-checks are to maintain API with an older version         if ((valid == null) || (str == null)) {             return false;         }         if (str.length() == 0) {             return true;         }         if (valid.length == 0) {             return false;         }         return indexOfAnyBut(str, valid) == -1;     }     /**      * <p>Checks if the String contains only certain characters.</p>      *      * <p>A <code>null</code> String will return <code>false</code>.      * A <code>null</code> valid character String will return <code>false</code>.      * An empty String ("") always returns <code>true</code>.</p>      *      * <pre>      * StringUtils.containsOnly(null, *)       = false      * StringUtils.containsOnly(*, null)       = false      * StringUtils.containsOnly("", *)         = true      * StringUtils.containsOnly("ab", "")      = false      * StringUtils.containsOnly("abab", "abc") = true      * StringUtils.containsOnly("ab1", "abc")  = false      * StringUtils.containsOnly("abz", "abc")  = false      * </pre>      *      * @param str  the String to check, may be null      * @param validChars  a String of valid chars, may be null      * @return true if it only contains valid chars and is non-null      * @since 2.0      */     public static boolean containsOnly(String str, String validChars) {         if (str == null || validChars == null) {             return false;         }         return containsOnly(str, validChars.toCharArray());     }     // ContainsNone     //-----------------------------------------------------------------------     /**      * <p>Checks that the String does not contain certain characters.</p>      *      * <p>A <code>null</code> String will return <code>true</code>.      * A <code>null</code> invalid character array will return <code>true</code>.      * An empty String ("") always returns true.</p>      *      * <pre>      * StringUtils.containsNone(null, *)       = true      * StringUtils.containsNone(*, null)       = true      * StringUtils.containsNone("", *)         = true      * StringUtils.containsNone("ab", '')      = true      * StringUtils.containsNone("abab", 'xyz') = true      * StringUtils.containsNone("ab1", 'xyz')  = true      * StringUtils.containsNone("abz", 'xyz')  = false      * </pre>      *      * @param str  the String to check, may be null      * @param invalidChars  an array of invalid chars, may be null      * @return true if it contains none of the invalid chars, or is null      * @since 2.0      */     public static boolean containsNone(String str, char[] invalidChars) {         if (str == null || invalidChars == null) {             return true;         }         int strSize = str.length();         int validSize = invalidChars.length;         for (int i = 0; i < strSize; i++) {             char ch = str.charAt(i);             for (int j = 0; j < validSize; j++) {                 if (invalidChars[j] == ch) {                     return false;                 }             }         }         return true;     }     /**      * <p>Checks that the String does not contain certain characters.</p>      *      * <p>A <code>null</code> String will return <code>true</code>.      * A <code>null</code> invalid character array will return <code>true</code>.      * An empty String ("") always returns true.</p>      *      * <pre>      * StringUtils.containsNone(null, *)       = true      * StringUtils.containsNone(*, null)       = true      * StringUtils.containsNone("", *)         = true      * StringUtils.containsNone("ab", "")      = true      * StringUtils.containsNone("abab", "xyz") = true      * StringUtils.containsNone("ab1", "xyz")  = true      * StringUtils.containsNone("abz", "xyz")  = false      * </pre>      *      * @param str  the String to check, may be null      * @param invalidChars  a String of invalid chars, may be null      * @return true if it contains none of the invalid chars, or is null      * @since 2.0      */     public static boolean containsNone(String str, String invalidChars) {         if (str == null || invalidChars == null) {             return true;         }         return containsNone(str, invalidChars.toCharArray());     }     // IndexOfAny strings     //-----------------------------------------------------------------------     /**      * <p>Find the first index of any of a set of potential substrings.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A <code>null</code> or zero length search array will return <code>-1</code>.      * A <code>null</code> search array entry will be ignored, but a search      * array containing "" will return <code>0</code> if <code>str</code> is not      * null. This method uses {@link String#indexOf(String)}.</p>      *      * <pre>      * StringUtils.indexOfAny(null, *)                     = -1      * StringUtils.indexOfAny(*, null)                     = -1      * StringUtils.indexOfAny(*, [])                       = -1      * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2      * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2      * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"])   = -1      * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1      * StringUtils.indexOfAny("zzabyycdxx", [""])          = 0      * StringUtils.indexOfAny("", [""])                    = 0      * StringUtils.indexOfAny("", ["a"])                   = -1      * </pre>      *      * @param str  the String to check, may be null      * @param searchStrs  the Strings to search for, may be null      * @return the first index of any of the searchStrs in str, -1 if no match      */     public static int indexOfAny(String str, String[] searchStrs) {         if ((str == null) || (searchStrs == null)) {             return -1;         }         int sz = searchStrs.length;         // String's can't have a MAX_VALUEth index.         int ret = Integer.MAX_VALUE;         int tmp = 0;         for (int i = 0; i < sz; i++) {             String search = searchStrs[i];             if (search == null) {                 continue;             }             tmp = str.indexOf(search);             if (tmp == -1) {                 continue;             }             if (tmp < ret) {                 ret = tmp;             }         }         return (ret == Integer.MAX_VALUE) ? -1 : ret;     }     /**      * <p>Find the latest index of any of a set of potential substrings.</p>      *      * <p>A <code>null</code> String will return <code>-1</code>.      * A <code>null</code> search array will return <code>-1</code>.      * A <code>null</code> or zero length search array entry will be ignored,      * but a search array containing "" will return the length of <code>str</code>      * if <code>str</code> is not null. This method uses {@link String#indexOf(String)}</p>      *      * <pre>      * StringUtils.lastIndexOfAny(null, *)                   = -1      * StringUtils.lastIndexOfAny(*, null)                   = -1      * StringUtils.lastIndexOfAny(*, [])                     = -1      * StringUtils.lastIndexOfAny(*, [null])                 = -1      * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6      * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6      * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1      * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1      * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10      * </pre>      *      * @param str  the String to check, may be null      * @param searchStrs  the Strings to search for, may be null      * @return the last index of any of the Strings, -1 if no match      */     public static int lastIndexOfAny(String str, String[] searchStrs) {         if ((str == null) || (searchStrs == null)) {             return -1;         }         int sz = searchStrs.length;         int ret = -1;         int tmp = 0;         for (int i = 0; i < sz; i++) {             String search = searchStrs[i];             if (search == null) {                 continue;             }             tmp = str.lastIndexOf(search);             if (tmp > ret) {                 ret = tmp;             }         }         return ret;     }     // Substring     //-----------------------------------------------------------------------     /**      * <p>Gets a substring from the specified String avoiding exceptions.</p>      *      * <p>A negative start position can be used to start <code>n</code>      * characters from the end of the String.</p>      *      * <p>A <code>null</code> String will return <code>null</code>.      * An empty ("") String will return "".</p>      *      * <pre>      * StringUtils.substring(null, *)   = null      * StringUtils.substring("", *)     = ""      * StringUtils.substring("abc", 0)  = "abc"      * StringUtils.substring("abc", 2)  = "c"      * StringUtils.substring("abc", 4)  = ""      * StringUtils.substring("abc", -2) = "bc"      * StringUtils.substring("abc", -4) = "abc"      * </pre>      *      * @param str  the String to get the substring from, may be null      * @param start  the position to start from, negative means      *  count back from the end of the String by this many characters      * @return substring from start position, <code>null</code> if null String input      */     public static String substring(String str, int start) {         if (str == null) {             return null;         }         // handle negatives, which means last n characters         if (start < 0) {             start = str.length() + start; // remember start is negative         }         if (start < 0) {             start = 0;         }         if (start > str.length()) {             return EMPTY;         }         return str.substring(start);     }     /**      * <p>Gets a substring from the specified String avoiding exceptions.</p>      *      * <p>A negative start position can be used to start/end <code>n</code>      * characters from the end of the String.</p>      *      * <p>The returned substring starts with the character in the <code>start</code>      * position and ends before the <code>end</code> position. All position counting is      * zero-based -- i.e., to start at the beginning of the string use      * <code>start = 0</code>. Negative start and end positions can be used to      * specify offsets relative to the end of the String.</p>      *      * <p>If <code>start</code> is not strictly to the left of <code>end</code>, ""      * is returned.</p>      *      * <pre>      * StringUtils.substring(null, *, *)    = null      * StringUtils.substring("", * ,  *)    = "";      * StringUtils.substring("abc", 0, 2)   = "ab"      * StringUtils.substring("abc", 2, 0)   = ""      * StringUtils.substring("abc", 2, 4)   = "c"      * StringUtils.substring("abc", 4, 6)   = ""      * StringUtils.substring("abc", 2, 2)   = ""      * StringUtils.substring("abc", -2, -1) = "b"      * StringUtils.substring("abc", -4, 2)  = "ab"      * </pre>      *      * @param str  the String to get the substring from, may be null      * @param start  the position to start from, negative means      *  count back from the end of the String by this many characters      * @param end  the position to end at (exclusive), negative means      *  count back from the end of the String by this many characters      * @return substring from start position to end positon,      *  <code>null</code> if null String input      */     public static String substring(String str, int start, int end) {         if (str == null) {             return null;         }         // handle negatives         if (end < 0) {             end = str.length() + end; // remember end is negative         }         if (start < 0) {             start = str.length() + start; // remember start is negative         }         // check length next         if (end > str.length()) {             end = str.length();         }         // if start is greater than end, return ""         if (start > end) {             return EMPTY;         }         if (start < 0) {             start = 0;         }         if (end < 0) {             end = 0;         }         return str.substring(start, end);     }     // Left/Right/Mid     //-----------------------------------------------------------------------     /**      * <p>Gets the leftmost <code>len</code> characters of a String.</p>      *      * <p>If <code>len</code> characters are not available, or the      * String is <code>null</code>, the String will be returned without      * an exception. An exception is thrown if len is negative.</p>      *      * <pre>      * StringUtils.left(null, *)    = null      * StringUtils.left(*, -ve)     = ""      * StringUtils.left("", *)      = ""      * StringUtils.left("abc", 0)   = ""      * StringUtils.left("abc", 2)   = "ab"      * StringUtils.left("abc", 4)   = "abc"      * </pre>      *      * @param str  the String to get the leftmost characters from, may be null      * @param len  the length of the required String, must be zero or positive      * @return the leftmost characters, <code>null</code> if null String input      */     public static String left(String str, int len) {         if (str == null) {             return null;         }         if (len < 0) {             return EMPTY;         }         if (str.length() <= len) {             return str;         } else {             return str.substring(0, len);         }     }     /**      * <p>Gets the rightmost <code>len</code> characters of a String.</p>      *      * <p>If <code>len</code> characters are not available, or the String      * is <code>null</code>, the String will be returned without an      * an exception. An exception is thrown if len is negative.</p>      *      * <pre>      * StringUtils.right(null, *)    = null      * StringUtils.right(*, -ve)     = ""      * StringUtils.right("", *)      = ""      * StringUtils.right("abc", 0)   = ""      * StringUtils.right("abc", 2)   = "bc"      * StringUtils.right("abc", 4)   = "abc"      * </pre>      *      * @param str  the String to get the rightmost characters from, may be null      * @param len  the length of the required String, must be zero or positive      * @return the rightmost characters, <code>null</code> if null String input      */     public static String right(String str, int len) {         if (str == null) {             return null;         }         if (len < 0) {             return EMPTY;         }         if (str.length() <= len) {             return str;         } else {             return str.substring(str.length() - len);         }     }     /**      * <p>Gets <code>len</code> characters from the middle of a String.</p>      *      * <p>If <code>len</code> characters are not available, the remainder      * of the String will be returned without an exception. If the      * String is <code>null</code>, <code>null</code> will be returned.      * An exception is thrown if len is negative.</p>      *      * <pre>      * StringUtils.mid(null, *, *)    = null      * StringUtils.mid(*, *, -ve)     = ""      * StringUtils.mid("", 0, *)      = ""      * StringUtils.mid("abc", 0, 2)   = "ab"      * StringUtils.mid("abc", 0, 4)   = "abc"      * StringUtils.mid("abc", 2, 4)   = "c"      * StringUtils.mid("abc", 4, 2)   = ""      * StringUtils.mid("abc", -2, 2)  = "ab"      * </pre>      *      * @param str  the String to get the characters from, may be null      * @param pos  the position to start from, negative treated as zero      * @param len  the length of the required String, must be zero or positive      * @return the middle characters, <code>null</code> if null String input      */     public static String mid(String str, int pos, int len) {         if (str == null) {             return null;         }         if (len < 0 || pos > str.length()) {             return EMPTY;         }         if (pos < 0) {             pos = 0;         }         if (str.length() <= (pos + len)) {             return str.substring(pos);         } else {             return str.substring(pos, pos + len);         }     }     // SubStringAfter/SubStringBefore     //-----------------------------------------------------------------------     /**      * <p>Gets the substring before the first occurrence of a separator.      * The separator is not returned.</p>      *      * <p>A <code>null</code> string input will return <code>null</code>.      * An empty ("") string input will return the empty string.      * A <code>null</code> separator will return the input string.</p>      *      * <pre>      * StringUtils.substringBefore(null, *)      = null      * StringUtils.substringBefore("", *)        = ""      * StringUtils.substringBefore("abc", "a")   = ""      * StringUtils.substringBefore("abcba", "b") = "a"      * StringUtils.substringBefore("abc", "c")   = "ab"      * StringUtils.substringBefore("abc", "d")   = "abc"      * StringUtils.substringBefore("abc", "")    = ""      * StringUtils.substringBefore("abc", null)  = "abc"      * </pre>      *      * @param str  the String to get a substring from, may be null      * @param separator  the String to search for, may be null      * @return the substring before the first occurrence of the separator,      *  <code>null</code> if null String input      * @since 2.0      */     public static String substringBefore(String str, String separator) {         if (isEmpty(str) || separator == null) {             return str;         }         if (separator.length() == 0) {             return EMPTY;         }         int pos = str.indexOf(separator);         if (pos == -1) {             return str;         }         return str.substring(0, pos);     }     /**      * <p>Gets the substring after the first occurrence of a separator.      * The separator is not returned.</p>      *      * <p>A <code>null</code> string input will return <code>null</code>.      * An empty ("") string input will return the empty string.      * A <code>null</code> separator will return the empty string if the      * input string is not <code>null</code>.</p>      *      * <pre>      * StringUtils.substringAfter(null, *)      = null      * StringUtils.substringAfter("", *)        = ""      * StringUtils.substringAfter(*, null)      = ""      * StringUtils.substringAfter("abc", "a")   = "bc"      * StringUtils.substringAfter("abcba", "b") = "cba"      * StringUtils.substringAfter("abc", "c")   = ""      * StringUtils.substringAfter("abc", "d")   = ""      * StringUtils.substringAfter("abc", "")    = "abc"      * </pre>      *      * @param str  the String to get a substring from, may be null      * @param separator  the String to search for, may be null      * @return the substring after the first occurrence of the separator,      *  <code>null</code> if null String input      * @since 2.0      */     public static String substringAfter(String str, String separator) {         if (isEmpty(str)) {             return str;         }         if (separator == null) {             return EMPTY;         }         int pos = str.indexOf(separator);         if (pos == -1) {             return EMPTY;         }         return str.substring(pos + separator.length());     }     /**      * <p>Gets the substring before the last occurrence of a separator.      * The separator is not returned.</p>      *      * <p>A <code>null</code> string input will return <code>null</code>.      * An empty ("") string input will return the empty string.      * An empty or <code>null</code> separator will return the input string.</p>      *      * <pre>      * StringUtils.substringBeforeLast(null, *)      = null      * StringUtils.substringBeforeLast("", *)        = ""      * StringUtils.substringBeforeLast("abcba", "b") = "abc"      * StringUtils.substringBeforeLast("abc", "c")   = "ab"      * StringUtils.substringBeforeLast("a", "a")     = ""      * StringUtils.substringBeforeLast("a", "z")     = "a"      * StringUtils.substringBeforeLast("a", null)    = "a"      * StringUtils.substringBeforeLast("a", "")      = "a"      * </pre>      *      * @param str  the String to get a substring from, may be null      * @param separator  the String to search for, may be null      * @return the substring before the last occurrence of the separator,      *  <code>null</code> if null String input      * @since 2.0      */     public static String substringBeforeLast(String str, String separator) {         if (isEmpty(str) || isEmpty(separator)) {             return str;         }         int pos = str.lastIndexOf(separator);         if (pos == -1) {             return str;         }         return str.substring(0, pos);     }     /**      * <p>Gets the substring after the last occurrence of a separator.      * The separator is not returned.</p>      *      * <p>A <code>null</code> string input will return <code>null</code>.      * An empty ("") string input will return the empty string.      * An empty or <code>null</code> separator will return the empty string if      * the input string is not <code>null</code>.</p>      *      * <pre>      * StringUtils.substringAfterLast(null, *)      = null      * StringUtils.substringAfterLast("", *)        = ""      * StringUtils.substringAfterLast(*, "")        = ""      * StringUtils.substringAfterLast(*, null)      = ""      * StringUtils.substringAfterLast("abc", "a")   = "bc"      * StringUtils.substringAfterLast("abcba", "b") = "a"      * StringUtils.substringAfterLast("abc", "c")   = ""      * StringUtils.substringAfterLast("a", "a")     = ""      * StringUtils.substringAfterLast("a", "z")     = ""      * </pre>      *      * @param str  the String to get a substring from, may be null      * @param separator  the String to search for, may be null      * @return the substring after the last occurrence of the separator,      *  <code>null</code> if null String input      * @since 2.0      */     public static String substringAfterLast(String str, String separator) {         if (isEmpty(str)) {             return str;         }         if (isEmpty(separator)) {             return EMPTY;         }         int pos = str.lastIndexOf(separator);         if (pos == -1 || pos == (str.length() - separator.length())) {             return EMPTY;         }         return str.substring(pos + separator.length());     }     // Substring between     //-----------------------------------------------------------------------     /**      * <p>Gets the String that is nested in between two instances of the      * same String.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> tag returns <code>null</code>.</p>      *      * <pre>      * StringUtils.substringBetween(null, *)            = null      * StringUtils.substringBetween("", "")             = ""      * StringUtils.substringBetween("", "tag")          = null      * StringUtils.substringBetween("tagabctag", null)  = null      * StringUtils.substringBetween("tagabctag", "")    = ""      * StringUtils.substringBetween("tagabctag", "tag") = "abc"      * </pre>      *      * @param str  the String containing the substring, may be null      * @param tag  the String before and after the substring, may be null      * @return the substring, <code>null</code> if no match      * @since 2.0      */     public static String substringBetween(String str, String tag) {         return substringBetween(str, tag, tag);     }     /**      * <p>Gets the String that is nested in between two Strings.      * Only the first match is returned.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> open/close returns <code>null</code> (no match).      * An empty ("") open/close returns an empty string.</p>      *      * <pre>      * StringUtils.substringBetween(null, *, *)          = null      * StringUtils.substringBetween("", "", "")          = ""      * StringUtils.substringBetween("", "", "tag")       = null      * StringUtils.substringBetween("", "tag", "tag")    = null      * StringUtils.substringBetween("yabcz", null, null) = null      * StringUtils.substringBetween("yabcz", "", "")     = ""      * StringUtils.substringBetween("yabcz", "y", "z")   = "abc"      * StringUtils.substringBetween("yabczyabcz", "y", "z")   = "abc"      * </pre>      *      * @param str  the String containing the substring, may be null      * @param open  the String before the substring, may be null      * @param close  the String after the substring, may be null      * @return the substring, <code>null</code> if no match      * @since 2.0      */     public static String substringBetween(String str, String open, String close) {         if (str == null || open == null || close == null) {             return null;         }         int start = str.indexOf(open);         if (start != -1) {             int end = str.indexOf(close, start + open.length());             if (end != -1) {                 return str.substring(start + open.length(), end);             }         }         return null;     }     // Nested extraction     //-----------------------------------------------------------------------     /**      * <p>Gets the String that is nested in between two instances of the      * same String.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> tag returns <code>null</code>.</p>      *      * <pre>      * StringUtils.getNestedString(null, *)            = null      * StringUtils.getNestedString("", "")             = ""      * StringUtils.getNestedString("", "tag")          = null      * StringUtils.getNestedString("tagabctag", null)  = null      * StringUtils.getNestedString("tagabctag", "")    = ""      * StringUtils.getNestedString("tagabctag", "tag") = "abc"      * </pre>      *      * @param str  the String containing nested-string, may be null      * @param tag  the String before and after nested-string, may be null      * @return the nested String, <code>null</code> if no match      * @deprecated Use the better named {@link #substringBetween(String, String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String getNestedString(String str, String tag) {         return substringBetween(str, tag, tag);     }     /**      * <p>Gets the String that is nested in between two Strings.      * Only the first match is returned.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> open/close returns <code>null</code> (no match).      * An empty ("") open/close returns an empty string.</p>      *      * <pre>      * StringUtils.getNestedString(null, *, *)          = null      * StringUtils.getNestedString("", "", "")          = ""      * StringUtils.getNestedString("", "", "tag")       = null      * StringUtils.getNestedString("", "tag", "tag")    = null      * StringUtils.getNestedString("yabcz", null, null) = null      * StringUtils.getNestedString("yabcz", "", "")     = ""      * StringUtils.getNestedString("yabcz", "y", "z")   = "abc"      * StringUtils.getNestedString("yabczyabcz", "y", "z")   = "abc"      * </pre>      *      * @param str  the String containing nested-string, may be null      * @param open  the String before nested-string, may be null      * @param close  the String after nested-string, may be null      * @return the nested String, <code>null</code> if no match      * @deprecated Use the better named {@link #substringBetween(String, String, String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String getNestedString(String str, String open, String close) {         return substringBetween(str, open, close);     }     // Splitting     //-----------------------------------------------------------------------     /**      * <p>Splits the provided text into an array, using whitespace as the      * separator.      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as one separator.      * For more control over the split use the StrTokenizer class.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.split(null)       = null      * StringUtils.split("")         = []      * StringUtils.split("abc def")  = ["abc", "def"]      * StringUtils.split("abc  def") = ["abc", "def"]      * StringUtils.split(" abc ")    = ["abc"]      * </pre>      *      * @param str  the String to parse, may be null      * @return an array of parsed Strings, <code>null</code> if null String input      */     public static String[] split(String str) {         return split(str, null, -1);     }     /**      * <p>Splits the provided text into an array, separator specified.      * This is an alternative to using StringTokenizer.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as one separator.      * For more control over the split use the StrTokenizer class.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.split(null, *)         = null      * StringUtils.split("", *)           = []      * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]      * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]      * StringUtils.split("a:b:c", '.')    = ["a:b:c"]      * StringUtils.split("a/tb/nc", null) = ["a", "b", "c"]      * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]      * </pre>      *      * @param str  the String to parse, may be null      * @param separatorChar  the character used as the delimiter,      *  <code>null</code> splits on whitespace      * @return an array of parsed Strings, <code>null</code> if null String input      * @since 2.0      */     public static String[] split(String str, char separatorChar) {         return splitWorker(str, separatorChar, false);     }     /**      * <p>Splits the provided text into an array, separators specified.      * This is an alternative to using StringTokenizer.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as one separator.      * For more control over the split use the StrTokenizer class.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> separatorChars splits on whitespace.</p>      *      * <pre>      * StringUtils.split(null, *)         = null      * StringUtils.split("", *)           = []      * StringUtils.split("abc def", null) = ["abc", "def"]      * StringUtils.split("abc def", " ")  = ["abc", "def"]      * StringUtils.split("abc  def", " ") = ["abc", "def"]      * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]      * </pre>      *      * @param str  the String to parse, may be null      * @param separatorChars  the characters used as the delimiters,      *  <code>null</code> splits on whitespace      * @return an array of parsed Strings, <code>null</code> if null String input      */     public static String[] split(String str, String separatorChars) {         return splitWorker(str, separatorChars, -1, false);     }     /**      * <p>Splits the provided text into an array with a maximum length,      * separators specified.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as one separator.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> separatorChars splits on whitespace.</p>      *      * <p>If more than <code>max</code> delimited substrings are found, the last      * returned string includes all characters after the first <code>max - 1</code>      * returned strings (including separator characters).</p>      *      * <pre>      * StringUtils.split(null, *, *)            = null      * StringUtils.split("", *, *)              = []      * StringUtils.split("ab de fg", null, 0)   = ["ab", "cd", "ef"]      * StringUtils.split("ab   de fg", null, 0) = ["ab", "cd", "ef"]      * StringUtils.split("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]      * StringUtils.split("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]      * </pre>      *      * @param str  the String to parse, may be null      * @param separatorChars  the characters used as the delimiters,      *  <code>null</code> splits on whitespace      * @param max  the maximum number of elements to include in the      *  array. A zero or negative value implies no limit      * @return an array of parsed Strings, <code>null</code> if null String input      */     public static String[] split(String str, String separatorChars, int max) {         return splitWorker(str, separatorChars, max, false);     }     /**      * <p>Splits the provided text into an array, separator string specified.</p>      *      * <p>The separator(s) will not be included in the returned String array.      * Adjacent separators are treated as one separator.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> separator splits on whitespace.</p>      *      * <pre>      * StringUtils.split(null, *)            = null      * StringUtils.split("", *)              = []      * StringUtils.split("ab de fg", null)   = ["ab", "de", "fg"]      * StringUtils.split("ab   de fg", null) = ["ab", "de", "fg"]      * StringUtils.split("ab:cd:ef", ":")    = ["ab", "cd", "ef"]      * StringUtils.split("abstemiouslyaeiouyabstemiously", "aeiouy")  = ["bst", "m", "sl", "bst", "m", "sl"]      * StringUtils.split("abstemiouslyaeiouyabstemiously", "aeiouy")  = ["abstemiously", "abstemiously"]      * </pre>      *      * @param str  the String to parse, may be null      * @param separator  String containing the String to be used as a delimiter,      *  <code>null</code> splits on whitespace      * @return an array of parsed Strings, <code>null</code> if null String was input      */     public static String[] splitByWholeSeparator(String str, String separator) {         return splitByWholeSeparator( str, separator, -1 ) ;     }     /**      * <p>Splits the provided text into an array, separator string specified.      * Returns a maximum of <code>max</code> substrings.</p>      *      * <p>The separator(s) will not be included in the returned String array.      * Adjacent separators are treated as one separator.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> separator splits on whitespace.</p>      *      * <pre>      * StringUtils.splitByWholeSeparator(null, *, *)               = null      * StringUtils.splitByWholeSeparator("", *, *)                 = []      * StringUtils.splitByWholeSeparator("ab de fg", null, 0)      = ["ab", "de", "fg"]      * StringUtils.splitByWholeSeparator("ab   de fg", null, 0)    = ["ab", "de", "fg"]      * StringUtils.splitByWholeSeparator("ab:cd:ef", ":", 2)       = ["ab", "cd"]      * StringUtils.splitByWholeSeparator("abstemiouslyaeiouyabstemiously", "aeiouy", 2) = ["bst", "m"]      * StringUtils.splitByWholeSeparator("abstemiouslyaeiouyabstemiously", "aeiouy", 2)  = ["abstemiously", "abstemiously"]      * </pre>      *      * @param str  the String to parse, may be null      * @param separator  String containing the String to be used as a delimiter,      *  <code>null</code> splits on whitespace      * @param max  the maximum number of elements to include in the returned      *  array. A zero or negative value implies no limit.      * @return an array of parsed Strings, <code>null</code> if null String was input      */     public static String[] splitByWholeSeparator( String str, String separator, int max ) {         if (str == null) {             return null;         }         int len = str.length() ;         if (len == 0) {             return ArrayUtils.EMPTY_STRING_ARRAY;         }         if ( ( separator == null ) || ( "".equals( separator ) ) ) {             // Split on whitespace.             return split( str, null, max ) ;         }         int separatorLength = separator.length() ;         ArrayList substrings = new ArrayList() ;         int numberOfSubstrings = 0 ;         int beg = 0 ;         int end = 0 ;         while ( end < len ) {             end = str.indexOf( separator, beg ) ;             if ( end > -1 ) {                 if ( end > beg ) {                     numberOfSubstrings += 1 ;                     if ( numberOfSubstrings == max ) {                         end = len ;                         substrings.add( str.substring( beg ) ) ;                     } else {                         // The following is OK, because String.substring( beg, end ) excludes                         // the character at the position 'end'.                         substrings.add( str.substring( beg, end ) ) ;                         // Set the starting point for the next search.                         // The following is equivalent to beg = end + (separatorLength - 1) + 1,                         // which is the right calculation:                         beg = end + separatorLength ;                     }                 } else {                     // We found a consecutive occurrence of the separator, so skip it.                     beg = end + separatorLength ;                 }             } else {                 // String.substring( beg ) goes from 'beg' to the end of the String.                 substrings.add( str.substring( beg ) ) ;                 end = len ;             }         }         return (String[]) substrings.toArray( new String[substrings.size()] ) ;     }     //-----------------------------------------------------------------------     /**      * <p>Splits the provided text into an array, using whitespace as the      * separator, preserving all tokens, including empty tokens created by      * adjacent separators. This is an alternative to using StringTokenizer.      * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as separators for empty tokens.      * For more control over the split use the StrTokenizer class.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.splitPreserveAllTokens(null)       = null      * StringUtils.splitPreserveAllTokens("")         = []      * StringUtils.splitPreserveAllTokens("abc def")  = ["abc", "def"]      * StringUtils.splitPreserveAllTokens("abc  def") = ["abc", "", "def"]      * StringUtils.splitPreserveAllTokens(" abc ")    = ["", "abc", ""]      * </pre>      *      * @param str  the String to parse, may be <code>null</code>      * @return an array of parsed Strings, <code>null</code> if null String input      * @since 2.1      */     public static String[] splitPreserveAllTokens(String str) {         return splitWorker(str, null, -1, true);     }     /**      * <p>Splits the provided text into an array, separator specified,      * preserving all tokens, including empty tokens created by adjacent      * separators. This is an alternative to using StringTokenizer.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as separators for empty tokens.      * For more control over the split use the StrTokenizer class.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.splitPreserveAllTokens(null, *)         = null      * StringUtils.splitPreserveAllTokens("", *)           = []      * StringUtils.splitPreserveAllTokens("a.b.c", '.')    = ["a", "b", "c"]      * StringUtils.splitPreserveAllTokens("a..b.c", '.')   = ["a", "b", "c"]      * StringUtils.splitPreserveAllTokens("a:b:c", '.')    = ["a:b:c"]      * StringUtils.splitPreserveAllTokens("a/tb/nc", null) = ["a", "b", "c"]      * StringUtils.splitPreserveAllTokens("a b c", ' ')    = ["a", "b", "c"]      * StringUtils.splitPreserveAllTokens("a b c ", ' ')   = ["a", "b", "c", ""]      * StringUtils.splitPreserveAllTokens("a b c ", ' ')   = ["a", "b", "c", "", ""]      * StringUtils.splitPreserveAllTokens(" a b c", ' ')   = ["", a", "b", "c"]      * StringUtils.splitPreserveAllTokens("  a b c", ' ')  = ["", "", a", "b", "c"]      * StringUtils.splitPreserveAllTokens(" a b c ", ' ')  = ["", a", "b", "c", ""]      * </pre>      *      * @param str  the String to parse, may be <code>null</code>      * @param separatorChar  the character used as the delimiter,      *  <code>null</code> splits on whitespace      * @return an array of parsed Strings, <code>null</code> if null String input      * @since 2.1      */     public static String[] splitPreserveAllTokens(String str, char separatorChar) {         return splitWorker(str, separatorChar, true);     }     /**      * Performs the logic for the <code>split</code> and      * <code>splitPreserveAllTokens</code> methods that do not return a      * maximum array length.      *      * @param str  the String to parse, may be <code>null</code>      * @param separatorChar the separate character      * @param preserveAllTokens if <code>true</code>, adjacent separators are      * treated as empty token separators; if <code>false</code>, adjacent      * separators are treated as one separator.      * @return an array of parsed Strings, <code>null</code> if null String input      */     private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {         // Performance tuned for 2.0 (JDK1.4)         if (str == null) {             return null;         }         int len = str.length();         if (len == 0) {             return ArrayUtils.EMPTY_STRING_ARRAY;         }         List list = new ArrayList();         int i = 0, start = 0;         boolean match = false;         boolean lastMatch = false;         while (i < len) {             if (str.charAt(i) == separatorChar) {                 if (match || preserveAllTokens) {                     list.add(str.substring(start, i));                     match = false;                     lastMatch = true;                 }                 start = ++i;                 continue;             } else {                 lastMatch = false;             }             match = true;             i++;         }         if (match || (preserveAllTokens && lastMatch)) {             list.add(str.substring(start, i));         }         return (String[]) list.toArray(new String[list.size()]);     }     /**      * <p>Splits the provided text into an array, separators specified,      * preserving all tokens, including empty tokens created by adjacent      * separators. This is an alternative to using StringTokenizer.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as separators for empty tokens.      * For more control over the split use the StrTokenizer class.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> separatorChars splits on whitespace.</p>      *      * <pre>      * StringUtils.splitPreserveAllTokens(null, *)           = null      * StringUtils.splitPreserveAllTokens("", *)             = []      * StringUtils.splitPreserveAllTokens("abc def", null)   = ["abc", "def"]      * StringUtils.splitPreserveAllTokens("abc def", " ")    = ["abc", "def"]      * StringUtils.splitPreserveAllTokens("abc  def", " ")   = ["abc", "", def"]      * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":")   = ["ab", "cd", "ef"]      * StringUtils.splitPreserveAllTokens("ab:cd:ef:", ":")  = ["ab", "cd", "ef", ""]      * StringUtils.splitPreserveAllTokens("ab:cd:ef::", ":") = ["ab", "cd", "ef", "", ""]      * StringUtils.splitPreserveAllTokens("ab::cd:ef", ":")  = ["ab", "", cd", "ef"]      * StringUtils.splitPreserveAllTokens(":cd:ef", ":")     = ["", cd", "ef"]      * StringUtils.splitPreserveAllTokens("::cd:ef", ":")    = ["", "", cd", "ef"]      * StringUtils.splitPreserveAllTokens(":cd:ef:", ":")    = ["", cd", "ef", ""]      * </pre>      *      * @param str  the String to parse, may be <code>null</code>      * @param separatorChars  the characters used as the delimiters,      *  <code>null</code> splits on whitespace      * @return an array of parsed Strings, <code>null</code> if null String input      * @since 2.1      */     public static String[] splitPreserveAllTokens(String str, String separatorChars) {         return splitWorker(str, separatorChars, -1, true);     }     /**      * <p>Splits the provided text into an array with a maximum length,      * separators specified, preserving all tokens, including empty tokens      * created by adjacent separators.</p>      *      * <p>The separator is not included in the returned String array.      * Adjacent separators are treated as separators for empty tokens.      * Adjacent separators are treated as one separator.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.      * A <code>null</code> separatorChars splits on whitespace.</p>      *      * <p>If more than <code>max</code> delimited substrings are found, the last      * returned string includes all characters after the first <code>max - 1</code>      * returned strings (including separator characters).</p>      *      * <pre>      * StringUtils.splitPreserveAllTokens(null, *, *)            = null      * StringUtils.splitPreserveAllTokens("", *, *)              = []      * StringUtils.splitPreserveAllTokens("ab de fg", null, 0)   = ["ab", "cd", "ef"]      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 0) = ["ab", "cd", "ef"]      * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]      * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 2) = ["ab", "  de fg"]      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 3) = ["ab", "", " de fg"]      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 4) = ["ab", "", "", "de fg"]      * </pre>      *      * @param str  the String to parse, may be <code>null</code>      * @param separatorChars  the characters used as the delimiters,      *  <code>null</code> splits on whitespace      * @param max  the maximum number of elements to include in the      *  array. A zero or negative value implies no limit      * @return an array of parsed Strings, <code>null</code> if null String input      * @since 2.1      */     public static String[] splitPreserveAllTokens(String str, String separatorChars, int max) {         return splitWorker(str, separatorChars, max, true);     }     /**      * Performs the logic for the <code>split</code> and      * <code>splitPreserveAllTokens</code> methods that return a maximum array      * length.      *      * @param str  the String to parse, may be <code>null</code>      * @param separatorChars the separate character      * @param max  the maximum number of elements to include in the      *  array. A zero or negative value implies no limit.      * @param preserveAllTokens if <code>true</code>, adjacent separators are      * treated as empty token separators; if <code>false</code>, adjacent      * separators are treated as one separator.      * @return an array of parsed Strings, <code>null</code> if null String input      */     private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {         // Performance tuned for 2.0 (JDK1.4)         // Direct code is quicker than StringTokenizer.         // Also, StringTokenizer uses isSpace() not isWhitespace()         if (str == null) {             return null;         }         int len = str.length();         if (len == 0) {             return ArrayUtils.EMPTY_STRING_ARRAY;         }         List list = new ArrayList();         int sizePlus1 = 1;         int i = 0, start = 0;         boolean match = false;         boolean lastMatch = false;         if (separatorChars == null) {             // Null separator means use whitespace             while (i < len) {                 if (Character.isWhitespace(str.charAt(i))) {                     if (match || preserveAllTokens) {                         lastMatch = true;                         if (sizePlus1++ == max) {                             i = len;                             lastMatch = false;                         }                         list.add(str.substring(start, i));                         match = false;                     }                     start = ++i;                     continue;                 } else {                     lastMatch = false;                 }                 match = true;                 i++;             }         } else if (separatorChars.length() == 1) {             // Optimise 1 character case             char sep = separatorChars.charAt(0);             while (i < len) {                 if (str.charAt(i) == sep) {                     if (match || preserveAllTokens) {                         lastMatch = true;                         if (sizePlus1++ == max) {                             i = len;                             lastMatch = false;                         }                         list.add(str.substring(start, i));                         match = false;                     }                     start = ++i;                     continue;                 } else {                     lastMatch = false;                 }                 match = true;                 i++;             }         } else {             // standard case             while (i < len) {                 if (separatorChars.indexOf(str.charAt(i)) >= 0) {                     if (match || preserveAllTokens) {                         lastMatch = true;                         if (sizePlus1++ == max) {                             i = len;                             lastMatch = false;                         }                         list.add(str.substring(start, i));                         match = false;                     }                     start = ++i;                     continue;                 } else {                     lastMatch = false;                 }                 match = true;                 i++;             }         }         if (match || (preserveAllTokens && lastMatch)) {             list.add(str.substring(start, i));         }         return (String[]) list.toArray(new String[list.size()]);     }     // Joining     //-----------------------------------------------------------------------     /**      * <p>Concatenates elements of an array into a single String.      * Null objects or empty strings within the array are represented by      * empty strings.</p>      *      * <pre>      * StringUtils.concatenate(null)            = null      * StringUtils.concatenate([])              = ""      * StringUtils.concatenate([null])          = ""      * StringUtils.concatenate(["a", "b", "c"]) = "abc"      * StringUtils.concatenate([null, "", "a"]) = "a"      * </pre>      *      * @param array  the array of values to concatenate, may be null      * @return the concatenated String, <code>null</code> if null array input      * @deprecated Use the better named {@link #join(Object[])} instead.      *             Method will be removed in Commons Lang 3.0.      */     public static String concatenate(Object[] array) {         return join(array, null);     }     /**      * <p>Joins the elements of the provided array into a single String      * containing the provided list of elements.</p>      *      * <p>No separator is added to the joined String.      * Null objects or empty strings within the array are represented by      * empty strings.</p>      *      * <pre>      * StringUtils.join(null)            = null      * StringUtils.join([])              = ""      * StringUtils.join([null])          = ""      * StringUtils.join(["a", "b", "c"]) = "abc"      * StringUtils.join([null, "", "a"]) = "a"      * </pre>      *      * @param array  the array of values to join together, may be null      * @return the joined String, <code>null</code> if null array input      * @since 2.0      */     public static String join(Object[] array) {         return join(array, null);     }     /**      * <p>Joins the elements of the provided array into a single String      * containing the provided list of elements.</p>      *      * <p>No delimiter is added before or after the list.      * Null objects or empty strings within the array are represented by      * empty strings.</p>      *      * <pre>      * StringUtils.join(null, *)               = null      * StringUtils.join([], *)                 = ""      * StringUtils.join([null], *)             = ""      * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"      * StringUtils.join(["a", "b", "c"], null) = "abc"      * StringUtils.join([null, "", "a"], ';')  = ";;a"      * </pre>      *      * @param array  the array of values to join together, may be null      * @param separator  the separator character to use      * @return the joined String, <code>null</code> if null array input      * @since 2.0      */     public static String join(Object[] array, char separator) {         if (array == null) {             return null;         }         int arraySize = array.length;         int bufSize = (arraySize == 0 ? 0 : ((array[0] == null ? 16 : array[0].toString().length()) + 1) * arraySize);         StringBuffer buf = new StringBuffer(bufSize);         for (int i = 0; i < arraySize; i++) {             if (i > 0) {                 buf.append(separator);             }             if (array[i] != null) {                 buf.append(array[i]);             }         }         return buf.toString();     }     /**      * <p>Joins the elements of the provided array into a single String      * containing the provided list of elements.</p>      *      * <p>No delimiter is added before or after the list.      * A <code>null</code> separator is the same as an empty String ("").      * Null objects or empty strings within the array are represented by      * empty strings.</p>      *      * <pre>      * StringUtils.join(null, *)                = null      * StringUtils.join([], *)                  = ""      * StringUtils.join([null], *)              = ""      * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"      * StringUtils.join(["a", "b", "c"], null)  = "abc"      * StringUtils.join(["a", "b", "c"], "")    = "abc"      * StringUtils.join([null, "", "a"], ',')   = ",,a"      * </pre>      *      * @param array  the array of values to join together, may be null      * @param separator  the separator character to use, null treated as ""      * @return the joined String, <code>null</code> if null array input      */     public static String join(Object[] array, String separator) {         if (array == null) {             return null;         }         if (separator == null) {             separator = EMPTY;         }         int arraySize = array.length;         // ArraySize ==  0: Len = 0         // ArraySize > 0:   Len = NofStrings *(len(firstString) + len(separator))         //           (Assuming that all Strings are roughly equally long)         int bufSize =             ((arraySize == 0)                 ? 0                 : arraySize                     * ((array[0] == null ? 16 : array[0].toString().length())                         + separator.length()));         StringBuffer buf = new StringBuffer(bufSize);         for (int i = 0; i < arraySize; i++) {             if (i > 0) {                 buf.append(separator);             }             if (array[i] != null) {                 buf.append(array[i]);             }         }         return buf.toString();     }     /**      * <p>Joins the elements of the provided <code>Iterator</code> into      * a single String containing the provided elements.</p>      *      * <p>No delimiter is added before or after the list. Null objects or empty      * strings within the iteration are represented by empty strings.</p>      *      * <p>See the examples here: {@link #join(Object[],char)}. </p>      *      * @param iterator  the <code>Iterator</code> of values to join together, may be null      * @param separator  the separator character to use      * @return the joined String, <code>null</code> if null iterator input      * @since 2.0      */     public static String join(Iterator iterator, char separator) {         if (iterator == null) {             return null;         }         StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small         while (iterator.hasNext()) {             Object obj = iterator.next();             if (obj != null) {                 buf.append(obj);             }             if (iterator.hasNext()) {                 buf.append(separator);             }         }         return buf.toString();     }     /**      * <p>Joins the elements of the provided <code>Iterator</code> into      * a single String containing the provided elements.</p>      *      * <p>No delimiter is added before or after the list.      * A <code>null</code> separator is the same as an empty String ("").</p>      *      * <p>See the examples here: {@link #join(Object[],String)}. </p>      *      * @param iterator  the <code>Iterator</code> of values to join together, may be null      * @param separator  the separator character to use, null treated as ""      * @return the joined String, <code>null</code> if null iterator input      */     public static String join(Iterator iterator, String separator) {         if (iterator == null) {             return null;         }         StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small         while (iterator.hasNext()) {             Object obj = iterator.next();             if (obj != null) {                 buf.append(obj);             }             if ((separator != null) && iterator.hasNext()) {                 buf.append(separator);             }         }         return buf.toString();     }     // Delete     //-----------------------------------------------------------------------     /**      * <p>Deletes all 'space' characters from a String as defined by      * {@link Character#isSpace(char)}.</p>      *      * <p>This is the only StringUtils method that uses the      * <code>isSpace</code> definition. You are advised to use      * {@link #deleteWhitespace(String)} instead as whitespace is much      * better localized.</p>      *      * <pre>      * StringUtils.deleteSpaces(null)           = null      * StringUtils.deleteSpaces("")             = ""      * StringUtils.deleteSpaces("abc")          = "abc"      * StringUtils.deleteSpaces(" /t  abc /n ") = "abc"      * StringUtils.deleteSpaces("ab  c")        = "abc"      * StringUtils.deleteSpaces("a/nb/tc     ") = "abc"      * </pre>      *      * <p>Spaces are defined as <code>{' ', '/t', '/r', '/n', '/b'}</code>      * in line with the deprecated <code>isSpace</code> method.</p>      *      * @param str  the String to delete spaces from, may be null      * @return the String without 'spaces', <code>null</code> if null String input      * @deprecated Use the better localized {@link #deleteWhitespace(String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String deleteSpaces(String str) {         if (str == null) {             return null;         }         return CharSetUtils.delete(str, " /t/r/n/b");     }     /**      * <p>Deletes all whitespaces from a String as defined by      * {@link Character#isWhitespace(char)}.</p>      *      * <pre>      * StringUtils.deleteWhitespace(null)         = null      * StringUtils.deleteWhitespace("")           = ""      * StringUtils.deleteWhitespace("abc")        = "abc"      * StringUtils.deleteWhitespace("   ab  c  ") = "abc"      * </pre>      *      * @param str  the String to delete whitespace from, may be null      * @return the String without whitespaces, <code>null</code> if null String input      */     public static String deleteWhitespace(String str) {         if (isEmpty(str)) {             return str;         }         int sz = str.length();         char[] chs = new char[sz];         int count = 0;         for (int i = 0; i < sz; i++) {             if (!Character.isWhitespace(str.charAt(i))) {                 chs[count++] = str.charAt(i);             }         }         if (count == sz) {             return str;         }         return new String(chs, 0, count);     }     // Remove     //-----------------------------------------------------------------------     /**      * <p>Removes a substring only if it is at the begining of a source string,      * otherwise returns the source string.</p>      *      * <p>A <code>null</code> source string will return <code>null</code>.      * An empty ("") source string will return the empty string.      * A <code>null</code> search string will return the source string.</p>      *      * <pre>      * StringUtils.removeStart(null, *)      = null      * StringUtils.removeStart("", *)        = ""      * StringUtils.removeStart(*, null)      = *      * StringUtils.removeStart("www.domain.com", "www.")   = "domain.com"      * StringUtils.removeStart("domain.com", "www.")       = "domain.com"      * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"      * StringUtils.removeStart("abc", "")    = "abc"      * </pre>      *      * @param str  the source String to search, may be null      * @param remove  the String to search for and remove, may be null      * @return the substring with the string removed if found,      *  <code>null</code> if null String input      * @since 2.1      */     public static String removeStart(String str, String remove) {         if (isEmpty(str) || isEmpty(remove)) {             return str;         }         if (str.startsWith(remove)){             return str.substring(remove.length());         }         return str;     }     /**      * <p>Removes a substring only if it is at the end of a source string,      * otherwise returns the source string.</p>      *      * <p>A <code>null</code> source string will return <code>null</code>.      * An empty ("") source string will return the empty string.      * A <code>null</code> search string will return the source string.</p>      *      * <pre>      * StringUtils.removeEnd(null, *)      = null      * StringUtils.removeEnd("", *)        = ""      * StringUtils.removeEnd(*, null)      = *      * StringUtils.removeEnd("www.domain.com", ".com.")  = "www,domain"      * StringUtils.removeEnd("www.domain.com", ".com")   = "www.domain"      * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"      * StringUtils.removeEnd("abc", "")    = "abc"      * </pre>      *      * @param str  the source String to search, may be null      * @param remove  the String to search for and remove, may be null      * @return the substring with the string removed if found,      *  <code>null</code> if null String input      * @since 2.1      */     public static String removeEnd(String str, String remove) {         if (isEmpty(str) || isEmpty(remove)) {             return str;         }         if (str.endsWith(remove)) {             return str.substring(0, str.length() - remove.length());         }         return str;     }     /**      * <p>Removes all occurances of a substring from within the source string.</p>      *      * <p>A <code>null</code> source string will return <code>null</code>.      * An empty ("") source string will return the empty string.      * A <code>null</code> remove string will return the source string.      * An empty ("") remove string will return the source string.</p>      *      * <pre>      * StringUtils.remove(null, *)        = null      * StringUtils.remove("", *)          = ""      * StringUtils.remove(*, null)        = *      * StringUtils.remove(*, "")          = *      * StringUtils.remove("queued", "ue") = "qd"      * StringUtils.remove("queued", "zz") = "queued"      * </pre>      *      * @param str  the source String to search, may be null      * @param remove  the String to search for and remove, may be null      * @return the substring with the string removed if found,      *  <code>null</code> if null String input      * @since 2.1      */     public static String remove(String str, String remove) {         if (isEmpty(str) || isEmpty(remove)) {             return str;         }         return replace(str, remove, "", -1);     }     /**      * <p>Removes all occurances of a character from within the source string.</p>      *      * <p>A <code>null</code> source string will return <code>null</code>.      * An empty ("") source string will return the empty string.</p>      *      * <pre>      * StringUtils.remove(null, *)       = null      * StringUtils.remove("", *)         = ""      * StringUtils.remove("queued", 'u') = "qeed"      * StringUtils.remove("queued", 'z') = "queued"      * </pre>      *      * @param str  the source String to search, may be null      * @param remove  the char to search for and remove, may be null      * @return the substring with the char removed if found,      *  <code>null</code> if null String input      * @since 2.1      */     public static String remove(String str, char remove) {         if (isEmpty(str) || str.indexOf(remove) == -1) {             return str;         }         char[] chars = str.toCharArray();         int pos = 0;         for (int i = 0; i < chars.length; i++) {             if (chars[i] != remove) {                 chars[pos++] = chars[i];             }         }         return new String(chars, 0, pos);     }     // Replacing     //-----------------------------------------------------------------------     /**      * <p>Replaces a String with another String inside a larger String, once.</p>      *      * <p>A <code>null</code> reference passed to this method is a no-op.</p>      *      * <pre>      * StringUtils.replaceOnce(null, *, *)        = null      * StringUtils.replaceOnce("", *, *)          = ""      * StringUtils.replaceOnce("any", null, *)    = "any"      * StringUtils.replaceOnce("any", *, null)    = "any"      * StringUtils.replaceOnce("any", "", *)      = "any"      * StringUtils.replaceOnce("aba", "a", null)  = "aba"      * StringUtils.replaceOnce("aba", "a", "")    = "ba"      * StringUtils.replaceOnce("aba", "a", "z")   = "zba"      * </pre>      *      * @see #replace(String text, String repl, String with, int max)      * @param text  text to search and replace in, may be null      * @param repl  the String to search for, may be null      * @param with  the String to replace with, may be null      * @return the text with any replacements processed,      *  <code>null</code> if null String input      */     public static String replaceOnce(String text, String repl, String with) {         return replace(text, repl, with, 1);     }     /**      * <p>Replaces all occurrences of a String within another String.</p>      *      * <p>A <code>null</code> reference passed to this method is a no-op.</p>      *      * <pre>      * StringUtils.replace(null, *, *)        = null      * StringUtils.replace("", *, *)          = ""      * StringUtils.replace("any", null, *)    = "any"      * StringUtils.replace("any", *, null)    = "any"      * StringUtils.replace("any", "", *)      = "any"      * StringUtils.replace("aba", "a", null)  = "aba"      * StringUtils.replace("aba", "a", "")    = "b"      * StringUtils.replace("aba", "a", "z")   = "zbz"      * </pre>      *      * @see #replace(String text, String repl, String with, int max)      * @param text  text to search and replace in, may be null      * @param repl  the String to search for, may be null      * @param with  the String to replace with, may be null      * @return the text with any replacements processed,      *  <code>null</code> if null String input      */     public static String replace(String text, String repl, String with) {         return replace(text, repl, with, -1);     }     /**      * <p>Replaces a String with another String inside a larger String,      * for the first <code>max</code> values of the search String.</p>      *      * <p>A <code>null</code> reference passed to this method is a no-op.</p>      *      * <pre>      * StringUtils.replace(null, *, *, *)         = null      * StringUtils.replace("", *, *, *)           = ""      * StringUtils.replace("any", null, *, *)     = "any"      * StringUtils.replace("any", *, null, *)     = "any"      * StringUtils.replace("any", "", *, *)       = "any"      * StringUtils.replace("any", *, *, 0)        = "any"      * StringUtils.replace("abaa", "a", null, -1) = "abaa"      * StringUtils.replace("abaa", "a", "", -1)   = "b"      * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"      * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"      * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"      * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"      * </pre>      *      * @param text  text to search and replace in, may be null      * @param repl  the String to search for, may be null      * @param with  the String to replace with, may be null      * @param max  maximum number of values to replace, or <code>-1</code> if no maximum      * @return the text with any replacements processed,      *  <code>null</code> if null String input      */     public static String replace(String text, String repl, String with, int max) {         if (text == null || isEmpty(repl) || with == null || max == 0) {             return text;         }         StringBuffer buf = new StringBuffer(text.length());         int start = 0, end = 0;         while ((end = text.indexOf(repl, start)) != -1) {             buf.append(text.substring(start, end)).append(with);             start = end + repl.length();             if (--max == 0) {                 break;             }         }         buf.append(text.substring(start));         return buf.toString();     }     // Replace, character based     //-----------------------------------------------------------------------     /**      * <p>Replaces all occurrences of a character in a String with another.      * This is a null-safe version of {@link String#replace(char, char)}.</p>      *      * <p>A <code>null</code> string input returns <code>null</code>.      * An empty ("") string input returns an empty string.</p>      *      * <pre>      * StringUtils.replaceChars(null, *, *)        = null      * StringUtils.replaceChars("", *, *)          = ""      * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"      * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"      * </pre>      *      * @param str  String to replace characters in, may be null      * @param searchChar  the character to search for, may be null      * @param replaceChar  the character to replace, may be null      * @return modified String, <code>null</code> if null string input      * @since 2.0      */     public static String replaceChars(String str, char searchChar, char replaceChar) {         if (str == null) {             return null;         }         return str.replace(searchChar, replaceChar);     }     /**      * <p>Replaces multiple characters in a String in one go.      * This method can also be used to delete characters.</p>      *      * <p>For example:<br />      * <code>replaceChars("hello", "ho", "jy") = jelly</code>.</p>      *      * <p>A <code>null</code> string input returns <code>null</code>.      * An empty ("") string input returns an empty string.      * A null or empty set of search characters returns the input string.</p>      *      * <p>The length of the search characters should normally equal the length      * of the replace characters.      * If the search characters is longer, then the extra search characters      * are deleted.      * If the search characters is shorter, then the extra replace characters      * are ignored.</p>      *      * <pre>      * StringUtils.replaceChars(null, *, *)           = null      * StringUtils.replaceChars("", *, *)             = ""      * StringUtils.replaceChars("abc", null, *)       = "abc"      * StringUtils.replaceChars("abc", "", *)         = "abc"      * StringUtils.replaceChars("abc", "b", null)     = "ac"      * StringUtils.replaceChars("abc", "b", "")       = "ac"      * StringUtils.replaceChars("abcba", "bc", "yz")  = "ayzya"      * StringUtils.replaceChars("abcba", "bc", "y")   = "ayya"      * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"      * </pre>      *      * @param str  String to replace characters in, may be null      * @param searchChars  a set of characters to search for, may be null      * @param replaceChars  a set of characters to replace, may be null      * @return modified String, <code>null</code> if null string input      * @since 2.0      */     public static String replaceChars(String str, String searchChars, String replaceChars) {         if (isEmpty(str) || isEmpty(searchChars)) {             return str;         }         if (replaceChars == null) {             replaceChars = "";         }         boolean modified = false;         StringBuffer buf = new StringBuffer(str.length());         for (int i = 0; i < str.length(); i++) {             char ch = str.charAt(i);             int index = searchChars.indexOf(ch);             if (index >= 0) {                 modified = true;                 if (index < replaceChars.length()) {                     buf.append(replaceChars.charAt(index));                 }             } else {                 buf.append(ch);             }         }         if (modified) {             return buf.toString();         } else {             return str;         }     }     // Overlay     //-----------------------------------------------------------------------     /**      * <p>Overlays part of a String with another String.</p>      *      * <pre>      * StringUtils.overlayString(null, *, *, *)           = NullPointerException      * StringUtils.overlayString(*, null, *, *)           = NullPointerException      * StringUtils.overlayString("", "abc", 0, 0)         = "abc"      * StringUtils.overlayString("abcdef", null, 2, 4)    = "abef"      * StringUtils.overlayString("abcdef", "", 2, 4)      = "abef"      * StringUtils.overlayString("abcdef", "zzzz", 2, 4)  = "abzzzzef"      * StringUtils.overlayString("abcdef", "zzzz", 4, 2)  = "abcdzzzzcdef"      * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsException      * StringUtils.overlayString("abcdef", "zzzz", 2, 8)  = IndexOutOfBoundsException      * </pre>      *      * @param text  the String to do overlaying in, may be null      * @param overlay  the String to overlay, may be null      * @param start  the position to start overlaying at, must be valid      * @param end  the position to stop overlaying before, must be valid      * @return overlayed String, <code>null</code> if null String input      * @throws NullPointerException if text or overlay is null      * @throws IndexOutOfBoundsException if either position is invalid      * @deprecated Use better named {@link #overlay(String, String, int, int)} instead.      *             Method will be removed in Commons Lang 3.0.      */     public static String overlayString(String text, String overlay, int start, int end) {         return new StringBuffer(start + overlay.length() + text.length() - end + 1)             .append(text.substring(0, start))             .append(overlay)             .append(text.substring(end))             .toString();     }     /**      * <p>Overlays part of a String with another String.</p>      *      * <p>A <code>null</code> string input returns <code>null</code>.      * A negative index is treated as zero.      * An index greater than the string length is treated as the string length.      * The start index is always the smaller of the two indices.</p>      *      * <pre>      * StringUtils.overlay(null, *, *, *)            = null      * StringUtils.overlay("", "abc", 0, 0)          = "abc"      * StringUtils.overlay("abcdef", null, 2, 4)     = "abef"      * StringUtils.overlay("abcdef", "", 2, 4)       = "abef"      * StringUtils.overlay("abcdef", "", 4, 2)       = "abef"      * StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"      * StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"      * StringUtils.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"      * StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"      * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"      * StringUtils.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"      * </pre>      *      * @param str  the String to do overlaying in, may be null      * @param overlay  the String to overlay, may be null      * @param start  the position to start overlaying at      * @param end  the position to stop overlaying before      * @return overlayed String, <code>null</code> if null String input      * @since 2.0      */     public static String overlay(String str, String overlay, int start, int end) {         if (str == null) {             return null;         }         if (overlay == null) {             overlay = EMPTY;         }         int len = str.length();         if (start < 0) {             start = 0;         }         if (start > len) {             start = len;         }         if (end < 0) {             end = 0;         }         if (end > len) {             end = len;         }         if (start > end) {             int temp = start;             start = end;             end = temp;         }         return new StringBuffer(len + start - end + overlay.length() + 1)             .append(str.substring(0, start))             .append(overlay)             .append(str.substring(end))             .toString();     }     // Chomping     //-----------------------------------------------------------------------     /**      * <p>Removes one newline from end of a String if it's there,      * otherwise leave it alone.  A newline is "<code>/n</code>",      * "<code>/r</code>", or "<code>/r/n</code>".</p>      *      * <p>NOTE: This method changed in 2.0.      * It now more closely matches Perl chomp.</p>      *      * <pre>      * StringUtils.chomp(null)          = null      * StringUtils.chomp("")            = ""      * StringUtils.chomp("abc /r")      = "abc "      * StringUtils.chomp("abc/n")       = "abc"      * StringUtils.chomp("abc/r/n")     = "abc"      * StringUtils.chomp("abc/r/n/r/n") = "abc/r/n"      * StringUtils.chomp("abc/n/r")     = "abc/n"      * StringUtils.chomp("abc/n/rabc")  = "abc/n/rabc"      * StringUtils.chomp("/r")          = ""      * StringUtils.chomp("/n")          = ""      * StringUtils.chomp("/r/n")        = ""      * </pre>      *      * @param str  the String to chomp a newline from, may be null      * @return String without newline, <code>null</code> if null String input      */     public static String chomp(String str) {         if (isEmpty(str)) {             return str;         }         if (str.length() == 1) {             char ch = str.charAt(0);             if (ch == '/r' || ch == '/n') {                 return EMPTY;             } else {                 return str;             }         }         int lastIdx = str.length() - 1;         char last = str.charAt(lastIdx);         if (last == '/n') {             if (str.charAt(lastIdx - 1) == '/r') {                 lastIdx--;             }         } else if (last == '/r') {             // why is this block empty?             // just to skip incrementing the index?         } else {             lastIdx++;         }         return str.substring(0, lastIdx);     }     /**      * <p>Removes <code>separator</code> from the end of      * <code>str</code> if it's there, otherwise leave it alone.</p>      *      * <p>NOTE: This method changed in version 2.0.      * It now more closely matches Perl chomp.      * For the previous behavior, use {@link #substringBeforeLast(String, String)}.      * This method uses {@link String#endsWith(String)}.</p>      *      * <pre>      * StringUtils.chomp(null, *)         = null      * StringUtils.chomp("", *)           = ""      * StringUtils.chomp("foobar", "bar") = "foo"      * StringUtils.chomp("foobar", "baz") = "foobar"      * StringUtils.chomp("foo", "foo")    = ""      * StringUtils.chomp("foo ", "foo")   = "foo "      * StringUtils.chomp(" foo", "foo")   = " "      * StringUtils.chomp("foo", "foooo")  = "foo"      * StringUtils.chomp("foo", "")       = "foo"      * StringUtils.chomp("foo", null)     = "foo"      * </pre>      *      * @param str  the String to chomp from, may be null      * @param separator  separator String, may be null      * @return String without trailing separator, <code>null</code> if null String input      */     public static String chomp(String str, String separator) {         if (isEmpty(str) || separator == null) {             return str;         }         if (str.endsWith(separator)) {             return str.substring(0, str.length() - separator.length());         }         return str;     }     /**      * <p>Remove any "/n" if and only if it is at the end      * of the supplied String.</p>      *      * @param str  the String to chomp from, must not be null      * @return String without chomped ending      * @throws NullPointerException if str is <code>null</code>      * @deprecated Use {@link #chomp(String)} instead.      *             Method will be removed in Commons Lang 3.0.      */     public static String chompLast(String str) {         return chompLast(str, "/n");     }     /**      * <p>Remove a value if and only if the String ends with that value.</p>      *      * @param str  the String to chomp from, must not be null      * @param sep  the String to chomp, must not be null      * @return String without chomped ending      * @throws NullPointerException if str or sep is <code>null</code>      * @deprecated Use {@link #chomp(String,String)} instead.      *             Method will be removed in Commons Lang 3.0.      */     public static String chompLast(String str, String sep) {         if (str.length() == 0) {             return str;         }         String sub = str.substring(str.length() - sep.length());         if (sep.equals(sub)) {             return str.substring(0, str.length() - sep.length());         } else {             return str;         }     }     /**      * <p>Remove everything and return the last value of a supplied String, and      * everything after it from a String.</p>      *      * @param str  the String to chomp from, must not be null      * @param sep  the String to chomp, must not be null      * @return String chomped      * @throws NullPointerException if str or sep is <code>null</code>      * @deprecated Use {@link #substringAfterLast(String, String)} instead      *             (although this doesn't include the separator)      *             Method will be removed in Commons Lang 3.0.      */     public static String getChomp(String str, String sep) {         int idx = str.lastIndexOf(sep);         if (idx == str.length() - sep.length()) {             return sep;         } else if (idx != -1) {             return str.substring(idx);         } else {             return EMPTY;         }     }     /**      * <p>Remove the first value of a supplied String, and everything before it      * from a String.</p>      *      * @param str  the String to chomp from, must not be null      * @param sep  the String to chomp, must not be null      * @return String without chomped beginning      * @throws NullPointerException if str or sep is <code>null</code>      * @deprecated Use {@link #substringAfter(String,String)} instead.      *             Method will be removed in Commons Lang 3.0.      */     public static String prechomp(String str, String sep) {         int idx = str.indexOf(sep);         if (idx != -1) {             return str.substring(idx + sep.length());         } else {             return str;         }     }     /**      * <p>Remove and return everything before the first value of a      * supplied String from another String.</p>      *      * @param str  the String to chomp from, must not be null      * @param sep  the String to chomp, must not be null      * @return String prechomped      * @throws NullPointerException if str or sep is <code>null</code>      * @deprecated Use {@link #substringBefore(String,String)} instead      *             (although this doesn't include the separator).      *             Method will be removed in Commons Lang 3.0.      */     public static String getPrechomp(String str, String sep) {         int idx = str.indexOf(sep);         if (idx != -1) {             return str.substring(0, idx + sep.length());         } else {             return EMPTY;         }     }     // Chopping     //-----------------------------------------------------------------------     /**      * <p>Remove the last character from a String.</p>      *      * <p>If the String ends in <code>/r/n</code>, then remove both      * of them.</p>      *      * <pre>      * StringUtils.chop(null)          = null      * StringUtils.chop("")            = ""      * StringUtils.chop("abc /r")      = "abc "      * StringUtils.chop("abc/n")       = "abc"      * StringUtils.chop("abc/r/n")     = "abc"      * StringUtils.chop("abc")         = "ab"      * StringUtils.chop("abc/nabc")    = "abc/nab"      * StringUtils.chop("a")           = ""      * StringUtils.chop("/r")          = ""      * StringUtils.chop("/n")          = ""      * StringUtils.chop("/r/n")        = ""      * </pre>      *      * @param str  the String to chop last character from, may be null      * @return String without last character, <code>null</code> if null String input      */     public static String chop(String str) {         if (str == null) {             return null;         }         int strLen = str.length();         if (strLen < 2) {             return EMPTY;         }         int lastIdx = strLen - 1;         String ret = str.substring(0, lastIdx);         char last = str.charAt(lastIdx);         if (last == '/n') {             if (ret.charAt(lastIdx - 1) == '/r') {                 return ret.substring(0, lastIdx - 1);             }         }         return ret;     }     /**      * <p>Removes <code>/n</code> from end of a String if it's there.      * If a <code>/r</code> precedes it, then remove that too.</p>      *      * @param str  the String to chop a newline from, must not be null      * @return String without newline      * @throws NullPointerException if str is <code>null</code>      * @deprecated Use {@link #chomp(String)} instead.      *             Method will be removed in Commons Lang 3.0.      */     public static String chopNewline(String str) {         int lastIdx = str.length() - 1;         if (lastIdx <= 0) {             return EMPTY;         }         char last = str.charAt(lastIdx);         if (last == '/n') {             if (str.charAt(lastIdx - 1) == '/r') {                 lastIdx--;             }         } else {             lastIdx++;         }         return str.substring(0, lastIdx);     }     // Conversion     //-----------------------------------------------------------------------     /**      * <p>Escapes any values it finds into their String form.</p>      *      * <p>So a tab becomes the characters <code>'//'</code> and      * <code>'t'</code>.</p>      *      * <p>As of Lang 2.0, this calls {@link StringEscapeUtils#escapeJava(String)}      * behind the scenes.      * </p>      * @see StringEscapeUtils#escapeJava(java.lang.String)      * @param str String to escape values in      * @return String with escaped values      * @throws NullPointerException if str is <code>null</code>      * @deprecated Use {@link StringEscapeUtils#escapeJava(String)}      *             This method will be removed in Commons Lang 3.0      */     public static String escape(String str) {         return StringEscapeUtils.escapeJava(str);     }     // Padding     //-----------------------------------------------------------------------     /**      * <p>Repeat a String <code>repeat</code> times to form a      * new String.</p>      *      * <pre>      * StringUtils.repeat(null, 2) = null      * StringUtils.repeat("", 0)   = ""      * StringUtils.repeat("", 2)   = ""      * StringUtils.repeat("a", 3)  = "aaa"      * StringUtils.repeat("ab", 2) = "abab"      * StringUtils.repeat("a", -2) = ""      * </pre>      *      * @param str  the String to repeat, may be null      * @param repeat  number of times to repeat str, negative treated as zero      * @return a new String consisting of the original String repeated,      *  <code>null</code> if null String input      */     public static String repeat(String str, int repeat) {         // Performance tuned for 2.0 (JDK1.4)         if (str == null) {             return null;         }         if (repeat <= 0) {             return EMPTY;         }         int inputLength = str.length();         if (repeat == 1 || inputLength == 0) {             return str;         }         if (inputLength == 1 && repeat <= PAD_LIMIT) {             return padding(repeat, str.charAt(0));         }         int outputLength = inputLength * repeat;         switch (inputLength) {             case 1 :                 char ch = str.charAt(0);                 char[] output1 = new char[outputLength];                 for (int i = repeat - 1; i >= 0; i--) {                     output1[i] = ch;                 }                 return new String(output1);             case 2 :                 char ch0 = str.charAt(0);                 char ch1 = str.charAt(1);                 char[] output2 = new char[outputLength];                 for (int i = repeat * 2 - 2; i >= 0; i--, i--) {                     output2[i] = ch0;                     output2[i + 1] = ch1;                 }                 return new String(output2);             default :                 StringBuffer buf = new StringBuffer(outputLength);                 for (int i = 0; i < repeat; i++) {                     buf.append(str);                 }                 return buf.toString();         }     }     /**      * <p>Returns padding using the specified delimiter repeated      * to a given length.</p>      *      * <pre>      * StringUtils.padding(0, 'e')  = ""      * StringUtils.padding(3, 'e')  = "eee"      * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException      * </pre>      *      * @param repeat  number of times to repeat delim      * @param padChar  character to repeat      * @return String with repeated character      * @throws IndexOutOfBoundsException if <code>repeat < 0</code>      */     private static String padding(int repeat, char padChar) {         // be careful of synchronization in this method         // we are assuming that get and set from an array index is atomic         String pad = PADDING[padChar];         if (pad == null) {             pad = String.valueOf(padChar);         }         while (pad.length() < repeat) {             pad = pad.concat(pad);         }         PADDING[padChar] = pad;         return pad.substring(0, repeat);     }     /**      * <p>Right pad a String with spaces (' ').</p>      *      * <p>The String is padded to the size of <code>size</code>.</p>      *      * <pre>      * StringUtils.rightPad(null, *)   = null      * StringUtils.rightPad("", 3)     = "   "      * StringUtils.rightPad("bat", 3)  = "bat"      * StringUtils.rightPad("bat", 5)  = "bat  "      * StringUtils.rightPad("bat", 1)  = "bat"      * StringUtils.rightPad("bat", -1) = "bat"      * </pre>      *      * @param str  the String to pad out, may be null      * @param size  the size to pad to      * @return right padded String or original String if no padding is necessary,      *  <code>null</code> if null String input      */     public static String rightPad(String str, int size) {         return rightPad(str, size, ' ');     }     /**      * <p>Right pad a String with a specified character.</p>      *      * <p>The String is padded to the size of <code>size</code>.</p>      *      * <pre>      * StringUtils.rightPad(null, *, *)     = null      * StringUtils.rightPad("", 3, 'z')     = "zzz"      * StringUtils.rightPad("bat", 3, 'z')  = "bat"      * StringUtils.rightPad("bat", 5, 'z')  = "batzz"      * StringUtils.rightPad("bat", 1, 'z')  = "bat"      * StringUtils.rightPad("bat", -1, 'z') = "bat"      * </pre>      *      * @param str  the String to pad out, may be null      * @param size  the size to pad to      * @param padChar  the character to pad with      * @return right padded String or original String if no padding is necessary,      *  <code>null</code> if null String input      * @since 2.0      */     public static String rightPad(String str, int size, char padChar) {         if (str == null) {             return null;         }         int pads = size - str.length();         if (pads <= 0) {             return str; // returns original String when possible         }         if (pads > PAD_LIMIT) {             return rightPad(str, size, String.valueOf(padChar));         }         return str.concat(padding(pads, padChar));     }     /**      * <p>Right pad a String with a specified String.</p>      *      * <p>The String is padded to the size of <code>size</code>.</p>      *      * <pre>      * StringUtils.rightPad(null, *, *)      = null      * StringUtils.rightPad("", 3, "z")      = "zzz"      * StringUtils.rightPad("bat", 3, "yz")  = "bat"      * StringUtils.rightPad("bat", 5, "yz")  = "batyz"      * StringUtils.rightPad("bat", 8, "yz")  = "batyzyzy"      * StringUtils.rightPad("bat", 1, "yz")  = "bat"      * StringUtils.rightPad("bat", -1, "yz") = "bat"      * StringUtils.rightPad("bat", 5, null)  = "bat  "      * StringUtils.rightPad("bat", 5, "")    = "bat  "      * </pre>      *      * @param str  the String to pad out, may be null      * @param size  the size to pad to      * @param padStr  the String to pad with, null or empty treated as single space      * @return right padded String or original String if no padding is necessary,      *  <code>null</code> if null String input      */     public static String rightPad(String str, int size, String padStr) {         if (str == null) {             return null;         }         if (isEmpty(padStr)) {             padStr = " ";         }         int padLen = padStr.length();         int strLen = str.length();         int pads = size - strLen;         if (pads <= 0) {             return str; // returns original String when possible         }         if (padLen == 1 && pads <= PAD_LIMIT) {             return rightPad(str, size, padStr.charAt(0));         }         if (pads == padLen) {             return str.concat(padStr);         } else if (pads < padLen) {             return str.concat(padStr.substring(0, pads));         } else {             char[] padding = new char[pads];             char[] padChars = padStr.toCharArray();             for (int i = 0; i < pads; i++) {                 padding[i] = padChars[i % padLen];             }             return str.concat(new String(padding));         }     }     /**      * <p>Left pad a String with spaces (' ').</p>      *      * <p>The String is padded to the size of <code>size<code>.</p>      *      * <pre>      * StringUtils.leftPad(null, *)   = null      * StringUtils.leftPad("", 3)     = "   "      * StringUtils.leftPad("bat", 3)  = "bat"      * StringUtils.leftPad("bat", 5)  = "  bat"      * StringUtils.leftPad("bat", 1)  = "bat"      * StringUtils.leftPad("bat", -1) = "bat"      * </pre>      *      * @param str  the String to pad out, may be null      * @param size  the size to pad to      * @return left padded String or original String if no padding is necessary,      *  <code>null</code> if null String input      */     public static String leftPad(String str, int size) {         return leftPad(str, size, ' ');     }     /**      * <p>Left pad a String with a specified character.</p>      *      * <p>Pad to a size of <code>size</code>.</p>      *      * <pre>      * StringUtils.leftPad(null, *, *)     = null      * StringUtils.leftPad("", 3, 'z')     = "zzz"      * StringUtils.leftPad("bat", 3, 'z')  = "bat"      * StringUtils.leftPad("bat", 5, 'z')  = "zzbat"      * StringUtils.leftPad("bat", 1, 'z')  = "bat"      * StringUtils.leftPad("bat", -1, 'z') = "bat"      * </pre>      *      * @param str  the String to pad out, may be null      * @param size  the size to pad to      * @param padChar  the character to pad with      * @return left padded String or original String if no padding is necessary,      *  <code>null</code> if null String input      * @since 2.0      */     public static String leftPad(String str, int size, char padChar) {         if (str == null) {             return null;         }         int pads = size - str.length();         if (pads <= 0) {             return str; // returns original String when possible         }         if (pads > PAD_LIMIT) {             return leftPad(str, size, String.valueOf(padChar));         }         return padding(pads, padChar).concat(str);     }     /**      * <p>Left pad a String with a specified String.</p>      *      * <p>Pad to a size of <code>size</code>.</p>      *      * <pre>      * StringUtils.leftPad(null, *, *)      = null      * StringUtils.leftPad("", 3, "z")      = "zzz"      * StringUtils.leftPad("bat", 3, "yz")  = "bat"      * StringUtils.leftPad("bat", 5, "yz")  = "yzbat"      * StringUtils.leftPad("bat", 8, "yz")  = "yzyzybat"      * StringUtils.leftPad("bat", 1, "yz")  = "bat"      * StringUtils.leftPad("bat", -1, "yz") = "bat"      * StringUtils.leftPad("bat", 5, null)  = "  bat"      * StringUtils.leftPad("bat", 5, "")    = "  bat"      * </pre>      *      * @param str  the String to pad out, may be null      * @param size  the size to pad to      * @param padStr  the String to pad with, null or empty treated as single space      * @return left padded String or original String if no padding is necessary,      *  <code>null</code> if null String input      */     public static String leftPad(String str, int size, String padStr) {         if (str == null) {             return null;         }         if (isEmpty(padStr)) {             padStr = " ";         }         int padLen = padStr.length();         int strLen = str.length();         int pads = size - strLen;         if (pads <= 0) {             return str; // returns original String when possible         }         if (padLen == 1 && pads <= PAD_LIMIT) {             return leftPad(str, size, padStr.charAt(0));         }         if (pads == padLen) {             return padStr.concat(str);         } else if (pads < padLen) {             return padStr.substring(0, pads).concat(str);         } else {             char[] padding = new char[pads];             char[] padChars = padStr.toCharArray();             for (int i = 0; i < pads; i++) {                 padding[i] = padChars[i % padLen];             }             return new String(padding).concat(str);         }     }     // Centering     //-----------------------------------------------------------------------     /**      * <p>Centers a String in a larger String of size <code>size</code>      * using the space character (' ').<p>      *      * <p>If the size is less than the String length, the String is returned.      * A <code>null</code> String returns <code>null</code>.      * A negative size is treated as zero.</p>      *      * <p>Equivalent to <code>center(str, size, " ")</code>.</p>      *      * <pre>      * StringUtils.center(null, *)   = null      * StringUtils.center("", 4)     = "    "      * StringUtils.center("ab", -1)  = "ab"      * StringUtils.center("ab", 4)   = " ab "      * StringUtils.center("abcd", 2) = "abcd"      * StringUtils.center("a", 4)    = " a  "      * </pre>      *      * @param str  the String to center, may be null      * @param size  the int size of new String, negative treated as zero      * @return centered String, <code>null</code> if null String input      */     public static String center(String str, int size) {         return center(str, size, ' ');     }     /**      * <p>Centers a String in a larger String of size <code>size</code>.      * Uses a supplied character as the value to pad the String with.</p>      *      * <p>If the size is less than the String length, the String is returned.      * A <code>null</code> String returns <code>null</code>.      * A negative size is treated as zero.</p>      *      * <pre>      * StringUtils.center(null, *, *)     = null      * StringUtils.center("", 4, ' ')     = "    "      * StringUtils.center("ab", -1, ' ')  = "ab"      * StringUtils.center("ab", 4, ' ')   = " ab"      * StringUtils.center("abcd", 2, ' ') = "abcd"      * StringUtils.center("a", 4, ' ')    = " a  "      * StringUtils.center("a", 4, 'y')    = "yayy"      * </pre>      *      * @param str  the String to center, may be null      * @param size  the int size of new String, negative treated as zero      * @param padChar  the character to pad the new String with      * @return centered String, <code>null</code> if null String input      * @since 2.0      */     public static String center(String str, int size, char padChar) {         if (str == null || size <= 0) {             return str;         }         int strLen = str.length();         int pads = size - strLen;         if (pads <= 0) {             return str;         }         str = leftPad(str, strLen + pads / 2, padChar);         str = rightPad(str, size, padChar);         return str;     }     /**      * <p>Centers a String in a larger String of size <code>size</code>.      * Uses a supplied String as the value to pad the String with.</p>      *      * <p>If the size is less than the String length, the String is returned.      * A <code>null</code> String returns <code>null</code>.      * A negative size is treated as zero.</p>      *      * <pre>      * StringUtils.center(null, *, *)     = null      * StringUtils.center("", 4, " ")     = "    "      * StringUtils.center("ab", -1, " ")  = "ab"      * StringUtils.center("ab", 4, " ")   = " ab"      * StringUtils.center("abcd", 2, " ") = "abcd"      * StringUtils.center("a", 4, " ")    = " a  "      * StringUtils.center("a", 4, "yz")   = "yayz"      * StringUtils.center("abc", 7, null) = "  abc  "      * StringUtils.center("abc", 7, "")   = "  abc  "      * </pre>      *      * @param str  the String to center, may be null      * @param size  the int size of new String, negative treated as zero      * @param padStr  the String to pad the new String with, must not be null or empty      * @return centered String, <code>null</code> if null String input      * @throws IllegalArgumentException if padStr is <code>null</code> or empty      */     public static String center(String str, int size, String padStr) {         if (str == null || size <= 0) {             return str;         }         if (isEmpty(padStr)) {             padStr = " ";         }         int strLen = str.length();         int pads = size - strLen;         if (pads <= 0) {             return str;         }         str = leftPad(str, strLen + pads / 2, padStr);         str = rightPad(str, size, padStr);         return str;     }     // Case conversion     //-----------------------------------------------------------------------     /**      * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.upperCase(null)  = null      * StringUtils.upperCase("")    = ""      * StringUtils.upperCase("aBc") = "ABC"      * </pre>      *      * @param str  the String to upper case, may be null      * @return the upper cased String, <code>null</code> if null String input      */     public static String upperCase(String str) {         if (str == null) {             return null;         }         return str.toUpperCase();     }     /**      * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>      *      * <p>A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.lowerCase(null)  = null      * StringUtils.lowerCase("")    = ""      * StringUtils.lowerCase("aBc") = "abc"      * </pre>      *      * @param str  the String to lower case, may be null      * @return the lower cased String, <code>null</code> if null String input      */     public static String lowerCase(String str) {         if (str == null) {             return null;         }         return str.toLowerCase();     }     /**      * <p>Capitalizes a String changing the first letter to title case as      * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>      *      * <p>For a word based algorithm, see {@link WordUtils#capitalize(String)}.      * A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.capitalize(null)  = null      * StringUtils.capitalize("")    = ""      * StringUtils.capitalize("cat") = "Cat"      * StringUtils.capitalize("cAt") = "CAt"      * </pre>      *      * @param str  the String to capitalize, may be null      * @return the capitalized String, <code>null</code> if null String input      * @see WordUtils#capitalize(String)      * @see #uncapitalize(String)      * @since 2.0      */     public static String capitalize(String str) {         int strLen;         if (str == null || (strLen = str.length()) == 0) {             return str;         }         return new StringBuffer(strLen)             .append(Character.toTitleCase(str.charAt(0)))             .append(str.substring(1))             .toString();     }     /**      * <p>Capitalizes a String changing the first letter to title case as      * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>      *      * @param str  the String to capitalize, may be null      * @return the capitalized String, <code>null</code> if null String input      * @deprecated Use the standardly named {@link #capitalize(String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String capitalise(String str) {         return capitalize(str);     }     /**      * <p>Uncapitalizes a String changing the first letter to title case as      * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>      *      * <p>For a word based algorithm, see {@link WordUtils#uncapitalize(String)}.      * A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.uncapitalize(null)  = null      * StringUtils.uncapitalize("")    = ""      * StringUtils.uncapitalize("Cat") = "cat"      * StringUtils.uncapitalize("CAT") = "cAT"      * </pre>      *      * @param str  the String to uncapitalize, may be null      * @return the uncapitalized String, <code>null</code> if null String input      * @see WordUtils#uncapitalize(String)      * @see #capitalize(String)      * @since 2.0      */     public static String uncapitalize(String str) {         int strLen;         if (str == null || (strLen = str.length()) == 0) {             return str;         }         return new StringBuffer(strLen)             .append(Character.toLowerCase(str.charAt(0)))             .append(str.substring(1))             .toString();     }     /**      * <p>Uncapitalizes a String changing the first letter to title case as      * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>      *      * @param str  the String to uncapitalize, may be null      * @return the uncapitalized String, <code>null</code> if null String input      * @deprecated Use the standardly named {@link #uncapitalize(String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String uncapitalise(String str) {         return uncapitalize(str);     }     /**      * <p>Swaps the case of a String changing upper and title case to      * lower case, and lower case to upper case.</p>      *      * <ul>      *  <li>Upper case character converts to Lower case</li>      *  <li>Title case character converts to Lower case</li>      *  <li>Lower case character converts to Upper case</li>      * </ul>      *      * <p>For a word based algorithm, see {@link WordUtils#swapCase(String)}.      * A <code>null</code> input String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.swapCase(null)                 = null      * StringUtils.swapCase("")                   = ""      * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"      * </pre>      *      * <p>NOTE: This method changed in Lang version 2.0.      * It no longer performs a word based algorithm.      * If you only use ASCII, you will notice no change.      * That functionality is available in WordUtils.</p>      *      * @param str  the String to swap case, may be null      * @return the changed String, <code>null</code> if null String input      */     public static String swapCase(String str) {         int strLen;         if (str == null || (strLen = str.length()) == 0) {             return str;         }         StringBuffer buffer = new StringBuffer(strLen);         char ch = 0;         for (int i = 0; i < strLen; i++) {             ch = str.charAt(i);             if (Character.isUpperCase(ch)) {                 ch = Character.toLowerCase(ch);             } else if (Character.isTitleCase(ch)) {                 ch = Character.toLowerCase(ch);             } else if (Character.isLowerCase(ch)) {                 ch = Character.toUpperCase(ch);             }             buffer.append(ch);         }         return buffer.toString();     }     /**      * <p>Capitalizes all the whitespace separated words in a String.      * Only the first letter of each word is changed.</p>      *      * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.      * A <code>null</code> input String returns <code>null</code>.</p>      *      * @param str  the String to capitalize, may be null      * @return capitalized String, <code>null</code> if null String input      * @deprecated Use the relocated {@link WordUtils#capitalize(String)}.      *             Method will be removed in Commons Lang 3.0.      */     public static String capitaliseAllWords(String str) {         return WordUtils.capitalize(str);     }     // Count matches     //-----------------------------------------------------------------------     /**      * <p>Counts how many times the substring appears in the larger String.</p>      *      * <p>A <code>null</code> or empty ("") String input returns <code>0</code>.</p>      *      * <pre>      * StringUtils.countMatches(null, *)       = 0      * StringUtils.countMatches("", *)         = 0      * StringUtils.countMatches("abba", null)  = 0      * StringUtils.countMatches("abba", "")    = 0      * StringUtils.countMatches("abba", "a")   = 2      * StringUtils.countMatches("abba", "ab")  = 1      * StringUtils.countMatches("abba", "xxx") = 0      * </pre>      *      * @param str  the String to check, may be null      * @param sub  the substring to count, may be null      * @return the number of occurrences, 0 if either String is <code>null</code>      */     public static int countMatches(String str, String sub) {         if (isEmpty(str) || isEmpty(sub)) {             return 0;         }         int count = 0;         int idx = 0;         while ((idx = str.indexOf(sub, idx)) != -1) {             count++;             idx += sub.length();         }         return count;     }     // Character Tests     //-----------------------------------------------------------------------     /**      * <p>Checks if the String contains only unicode letters.</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isAlpha(null)   = false      * StringUtils.isAlpha("")     = true      * StringUtils.isAlpha("  ")   = false      * StringUtils.isAlpha("abc")  = true      * StringUtils.isAlpha("ab2c") = false      * StringUtils.isAlpha("ab-c") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains letters, and is non-null      */     public static boolean isAlpha(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if (Character.isLetter(str.charAt(i)) == false) {                 return false;             }         }         return true;     }     /**      * <p>Checks if the String contains only unicode letters and      * space (' ').</p>      *      * <p><code>null</code> will return <code>false</code>      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isAlphaSpace(null)   = false      * StringUtils.isAlphaSpace("")     = true      * StringUtils.isAlphaSpace("  ")   = true      * StringUtils.isAlphaSpace("abc")  = true      * StringUtils.isAlphaSpace("ab c") = true      * StringUtils.isAlphaSpace("ab2c") = false      * StringUtils.isAlphaSpace("ab-c") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains letters and space,      *  and is non-null      */     public static boolean isAlphaSpace(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {                 return false;             }         }         return true;     }     /**      * <p>Checks if the String contains only unicode letters or digits.</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isAlphanumeric(null)   = false      * StringUtils.isAlphanumeric("")     = true      * StringUtils.isAlphanumeric("  ")   = false      * StringUtils.isAlphanumeric("abc")  = true      * StringUtils.isAlphanumeric("ab c") = false      * StringUtils.isAlphanumeric("ab2c") = true      * StringUtils.isAlphanumeric("ab-c") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains letters or digits,      *  and is non-null      */     public static boolean isAlphanumeric(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if (Character.isLetterOrDigit(str.charAt(i)) == false) {                 return false;             }         }         return true;     }     /**      * <p>Checks if the String contains only unicode letters, digits      * or space (<code>' '</code>).</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isAlphanumeric(null)   = false      * StringUtils.isAlphanumeric("")     = true      * StringUtils.isAlphanumeric("  ")   = true      * StringUtils.isAlphanumeric("abc")  = true      * StringUtils.isAlphanumeric("ab c") = true      * StringUtils.isAlphanumeric("ab2c") = true      * StringUtils.isAlphanumeric("ab-c") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains letters, digits or space,      *  and is non-null      */     public static boolean isAlphanumericSpace(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {                 return false;             }         }         return true;     }     /**      * <p>Checks if the string contains only ASCII printable characters.</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isAsciiPrintable(null)     = false      * StringUtils.isAsciiPrintable("")       = true      * StringUtils.isAsciiPrintable(" ")      = true      * StringUtils.isAsciiPrintable("Ceki")   = true      * StringUtils.isAsciiPrintable("ab2c")   = true      * StringUtils.isAsciiPrintable("!ab-c~") = true      * StringUtils.isAsciiPrintable("/u0020") = true      * StringUtils.isAsciiPrintable("/u0021") = true      * StringUtils.isAsciiPrintable("/u007e") = true      * StringUtils.isAsciiPrintable("/u007f") = false      * StringUtils.isAsciiPrintable("Ceki G/u00fclc/u00fc") = false      * </pre>      *      * @param str the string to check, may be null      * @return <code>true</code> if every character is in the range      *  32 thru 126      * @since 2.1      */     public static boolean isAsciiPrintable(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if (CharUtils.isAsciiPrintable(str.charAt(i)) == false) {                 return false;             }         }         return true;     }       /**      * <p>Checks if the String contains only unicode digits.      * A decimal point is not a unicode digit and returns false.</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isNumeric(null)   = false      * StringUtils.isNumeric("")     = true      * StringUtils.isNumeric("  ")   = false      * StringUtils.isNumeric("123")  = true      * StringUtils.isNumeric("12 3") = false      * StringUtils.isNumeric("ab2c") = false      * StringUtils.isNumeric("12-3") = false      * StringUtils.isNumeric("12.3") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains digits, and is non-null      */     public static boolean isNumeric(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if (Character.isDigit(str.charAt(i)) == false) {                 return false;             }         }         return true;     }     /**      * <p>Checks if the String contains only unicode digits or space      * (<code>' '</code>).      * A decimal point is not a unicode digit and returns false.</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isNumeric(null)   = false      * StringUtils.isNumeric("")     = true      * StringUtils.isNumeric("  ")   = true      * StringUtils.isNumeric("123")  = true      * StringUtils.isNumeric("12 3") = true      * StringUtils.isNumeric("ab2c") = false      * StringUtils.isNumeric("12-3") = false      * StringUtils.isNumeric("12.3") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains digits or space,      *  and is non-null      */     public static boolean isNumericSpace(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {                 return false;             }         }         return true;     }     /**      * <p>Checks if the String contains only whitespace.</p>      *      * <p><code>null</code> will return <code>false</code>.      * An empty String ("") will return <code>true</code>.</p>      *      * <pre>      * StringUtils.isWhitespace(null)   = false      * StringUtils.isWhitespace("")     = true      * StringUtils.isWhitespace("  ")   = true      * StringUtils.isWhitespace("abc")  = false      * StringUtils.isWhitespace("ab2c") = false      * StringUtils.isWhitespace("ab-c") = false      * </pre>      *      * @param str  the String to check, may be null      * @return <code>true</code> if only contains whitespace, and is non-null      * @since 2.0      */     public static boolean isWhitespace(String str) {         if (str == null) {             return false;         }         int sz = str.length();         for (int i = 0; i < sz; i++) {             if ((Character.isWhitespace(str.charAt(i)) == false)) {                 return false;             }         }         return true;     }     // Defaults     //-----------------------------------------------------------------------     /**      * <p>Returns either the passed in String,      * or if the String is <code>null</code>, an empty String ("").</p>      *      * <pre>      * StringUtils.defaultString(null)  = ""      * StringUtils.defaultString("")    = ""      * StringUtils.defaultString("bat") = "bat"      * </pre>      *      * @see ObjectUtils#toString(Object)      * @see String#valueOf(Object)      * @param str  the String to check, may be null      * @return the passed in String, or the empty String if it      *  was <code>null</code>      */     public static String defaultString(String str) {         return str == null ? EMPTY : str;     }     /**      * <p>Returns either the passed in String, or if the String is      * <code>null</code>, the value of <code>defaultStr</code>.</p>      *      * <pre>      * StringUtils.defaultString(null, "NULL")  = "NULL"      * StringUtils.defaultString("", "NULL")    = ""      * StringUtils.defaultString("bat", "NULL") = "bat"      * </pre>      *      * @see ObjectUtils#toString(Object,String)      * @see String#valueOf(Object)      * @param str  the String to check, may be null      * @param defaultStr  the default String to return      *  if the input is <code>null</code>, may be null      * @return the passed in String, or the default if it was <code>null</code>      */     public static String defaultString(String str, String defaultStr) {         return str == null ? defaultStr : str;     }     /**      * <p>Returns either the passed in String, or if the String is      * empty or <code>null</code>, the value of <code>defaultStr</code>.</p>      *      * <pre>      * StringUtils.defaultIfEmpty(null, "NULL")  = "NULL"      * StringUtils.defaultIfEmpty("", "NULL")    = "NULL"      * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"      * </pre>      *      * @see StringUtils#defaultString(String, String)      * @param str  the String to check, may be null      * @param defaultStr  the default String to return      *  if the input is empty ("") or <code>null</code>, may be null      * @return the passed in String, or the default      */     public static String defaultIfEmpty(String str, String defaultStr) {         return StringUtils.isEmpty(str) ? defaultStr : str;     }     // Reversing     //-----------------------------------------------------------------------     /**      * <p>Reverses a String as per {@link StringBuffer#reverse()}.</p>      *      * <p>A <code>null</code> String returns <code>null</code>.</p>      *      * <pre>      * StringUtils.reverse(null)  = null      * StringUtils.reverse("")    = ""      * StringUtils.reverse("bat") = "tab"      * </pre>      *      * @param str  the String to reverse, may be null      * @return the reversed String, <code>null</code> if null String input      */     public static String reverse(String str) {         if (str == null) {             return null;         }         return new StringBuffer(str).reverse().toString();     }     /**      * <p>Reverses a String that is delimited by a specific character.</p>      *      * <p>The Strings between the delimiters are not reversed.      * Thus java.lang.String becomes String.lang.java (if the delimiter      * is <code>'.'</code>).</p>      *      * <pre>      * StringUtils.reverseDelimited(null, *)      = null      * StringUtils.reverseDelimited("", *)        = ""      * StringUtils.reverseDelimited("a.b.c", 'x') = "a.b.c"      * StringUtils.reverseDelimited("a.b.c", ".") = "c.b.a"      * </pre>      *      * @param str  the String to reverse, may be null      * @param separatorChar  the separator character to use      * @return the reversed String, <code>null</code> if null String input      * @since 2.0      */     public static String reverseDelimited(String str, char separatorChar) {         if (str == null) {             return null;         }         // could implement manually, but simple way is to reuse other,         // probably slower, methods.         String[] strs = split(str, separatorChar);         ArrayUtils.reverse(strs);         return join(strs, separatorChar);     }     /**      * <p>Reverses a String that is delimited by a specific character.</p>      *      * <p>The Strings between the delimiters are not reversed.      * Thus java.lang.String becomes String.lang.java (if the delimiter      * is <code>"."</code>).</p>      *      * <pre>      * StringUtils.reverseDelimitedString(null, *)       = null      * StringUtils.reverseDelimitedString("",*)          = ""      * StringUtils.reverseDelimitedString("a.b.c", null) = "a.b.c"      * StringUtils.reverseDelimitedString("a.b.c", ".")  = "c.b.a"      * </pre>      *      * @param str  the String to reverse, may be null      * @param separatorChars  the separator characters to use, null treated as whitespace      * @return the reversed String, <code>null</code> if null String input      * @deprecated Use {@link #reverseDelimited(String, char)} instead.      *      This method is broken as the join doesn't know which char to use.      *      Method will be removed in Commons Lang 3.0.      *      */     public static String reverseDelimitedString(String str, String separatorChars) {         if (str == null) {             return null;         }         // could implement manually, but simple way is to reuse other,         // probably slower, methods.         String[] strs = split(str, separatorChars);         ArrayUtils.reverse(strs);         if (separatorChars == null) {             return join(strs, ' ');         }         return join(strs, separatorChars);     }     // Abbreviating     //-----------------------------------------------------------------------     /**      * <p>Abbreviates a String using ellipses. This will turn      * "Now is the time for all good men" into "Now is the time for..."</p>      *      * <p>Specifically:      * <ul>      *   <li>If <code>str</code> is less than <code>maxWidth</code> characters      *       long, return it.</li>      *   <li>Else abbreviate it to <code>(substring(str, 0, max-3) + "...")</code>.</li>      *   <li>If <code>maxWidth</code> is less than <code>4</code>, throw an      *       <code>IllegalArgumentException</code>.</li>      *   <li>In no case will it return a String of length greater than      *       <code>maxWidth</code>.</li>      * </ul>      * </p>      *      * <pre>      * StringUtils.abbreviate(null, *)      = null      * StringUtils.abbreviate("", 4)        = ""      * StringUtils.abbreviate("abcdefg", 6) = "abc..."      * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"      * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"      * StringUtils.abbreviate("abcdefg", 4) = "a..."      * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException      * </pre>      *      * @param str  the String to check, may be null      * @param maxWidth  maximum length of result String, must be at least 4      * @return abbreviated String, <code>null</code> if null String input      * @throws IllegalArgumentException if the width is too small      * @since 2.0      */     public static String abbreviate(String str, int maxWidth) {         return abbreviate(str, 0, maxWidth);     }     /**      * <p>Abbreviates a String using ellipses. This will turn      * "Now is the time for all good men" into "...is the time for..."</p>      *      * <p>Works like <code>abbreviate(String, int)</code>, but allows you to specify      * a "left edge" offset.  Note that this left edge is not necessarily going to      * be the leftmost character in the result, or the first character following the      * ellipses, but it will appear somewhere in the result.      *      * <p>In no case will it return a String of length greater than      * <code>maxWidth</code>.</p>      *      * <pre>      * StringUtils.abbreviate(null, *, *)                = null      * StringUtils.abbreviate("", 0, 4)                  = ""      * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."      * StringUtils.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."      * StringUtils.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."      * StringUtils.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."      * StringUtils.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."      * StringUtils.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."      * StringUtils.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"      * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"      * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"      * StringUtils.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException      * StringUtils.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException      * </pre>      *      * @param str  the String to check, may be null      * @param offset  left edge of source String      * @param maxWidth  maximum length of result String, must be at least 4      * @return abbreviated String, <code>null</code> if null String input      * @throws IllegalArgumentException if the width is too small      * @since 2.0      */     public static String abbreviate(String str, int offset, int maxWidth) {         if (str == null) {             return null;         }         if (maxWidth < 4) {             throw new IllegalArgumentException("Minimum abbreviation width is 4");         }         if (str.length() <= maxWidth) {             return str;         }         if (offset > str.length()) {             offset = str.length();         }         if ((str.length() - offset) < (maxWidth - 3)) {             offset = str.length() - (maxWidth - 3);         }         if (offset <= 4) {             return str.substring(0, maxWidth - 3) + "...";         }         if (maxWidth < 7) {             throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");         }         if ((offset + (maxWidth - 3)) < str.length()) {             return "..." + abbreviate(str.substring(offset), maxWidth - 3);         }         return "..." + str.substring(str.length() - (maxWidth - 3));     }     // Difference     //-----------------------------------------------------------------------     /**      * <p>Compares two Strings, and returns the portion where they differ.      * (More precisely, return the remainder of the second String,      * starting from where it's different from the first.)</p>      *      * <p>For example,      * <code>difference("i am a machine", "i am a robot") -> "robot"</code>.</p>      *      * <pre>      * StringUtils.difference(null, null) = null      * StringUtils.difference("", "") = ""      * StringUtils.difference("", "abc") = "abc"      * StringUtils.difference("abc", "") = ""      * StringUtils.difference("abc", "abc") = ""      * StringUtils.difference("ab", "abxyz") = "xyz"      * StringUtils.difference("abcde", "abxyz") = "xyz"      * StringUtils.difference("abcde", "xyz") = "xyz"      * </pre>      *      * @param str1  the first String, may be null      * @param str2  the second String, may be null      * @return the portion of str2 where it differs from str1; returns the      * empty String if they are equal      * @since 2.0      */     public static String difference(String str1, String str2) {         if (str1 == null) {             return str2;         }         if (str2 == null) {             return str1;         }         int at = indexOfDifference(str1, str2);         if (at == -1) {             return EMPTY;         }         return str2.substring(at);     }     /**      * <p>Compares two Strings, and returns the index at which the      * Strings begin to differ.</p>      *      * <p>For example,      * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code></p>      *      * <pre>      * StringUtils.indexOfDifference(null, null) = -1      * StringUtils.indexOfDifference("", "") = -1      * StringUtils.indexOfDifference("", "abc") = 0      * StringUtils.indexOfDifference("abc", "") = 0      * StringUtils.indexOfDifference("abc", "abc") = -1      * StringUtils.indexOfDifference("ab", "abxyz") = 2      * StringUtils.indexOfDifference("abcde", "abxyz") = 2      * StringUtils.indexOfDifference("abcde", "xyz") = 0      * </pre>      *      * @param str1  the first String, may be null      * @param str2  the second String, may be null      * @return the index where str2 and str1 begin to differ; -1 if they are equal      * @since 2.0      */     public static int indexOfDifference(String str1, String str2) {         if (str1 == str2) {             return -1;         }         if (str1 == null || str2 == null) {             return 0;         }         int i;         for (i = 0; i < str1.length() && i < str2.length(); ++i) {             if (str1.charAt(i) != str2.charAt(i)) {                 break;             }         }         if (i < str2.length() || i < str1.length()) {             return i;         }         return -1;     }     // Misc     //-----------------------------------------------------------------------     /**      * <p>Find the Levenshtein distance between two Strings.</p>      *      * <p>This is the number of changes needed to change one String into      * another, where each change is a single character modification (deletion,      * insertion or substitution).</p>      *      * <p>This implementation of the Levenshtein distance algorithm      * is from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>      *      * <pre>      * StringUtils.getLevenshteinDistance(null, *)             = IllegalArgumentException      * StringUtils.getLevenshteinDistance(*, null)             = IllegalArgumentException      * StringUtils.getLevenshteinDistance("","")               = 0      * StringUtils.getLevenshteinDistance("","a")              = 1      * StringUtils.getLevenshteinDistance("aaapppp", "")       = 7      * StringUtils.getLevenshteinDistance("frog", "fog")       = 1      * StringUtils.getLevenshteinDistance("fly", "ant")        = 3      * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7      * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7      * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8      * StringUtils.getLevenshteinDistance("hello", "hallo")    = 1      * </pre>      *      * @param s  the first String, must not be null      * @param t  the second String, must not be null      * @return result distance      * @throws IllegalArgumentException if either String input <code>null</code>      */     public static int getLevenshteinDistance(String s, String t) {         if (s == null || t == null) {             throw new IllegalArgumentException("Strings must not be null");         }         int d[][]; // matrix         int n; // length of s         int m; // length of t         int i; // iterates through s         int j; // iterates through t         char s_i; // ith character of s         char t_j; // jth character of t         int cost; // cost         // Step 1         n = s.length();         m = t.length();         if (n == 0) {             return m;         }         if (m == 0) {             return n;         }         d = new int[n + 1][m + 1];         // Step 2         for (i = 0; i <= n; i++) {             d[i][0] = i;         }         for (j = 0; j <= m; j++) {             d[0][j] = j;         }         // Step 3         for (i = 1; i <= n; i++) {             s_i = s.charAt(i - 1);             // Step 4             for (j = 1; j <= m; j++) {                 t_j = t.charAt(j - 1);                 // Step 5                 if (s_i == t_j) {                     cost = 0;                 } else {                     cost = 1;                 }                 // Step 6                 d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);             }         }         // Step 7         return d[n][m];     }     /**      * <p>Gets the minimum of three <code>int</code> values.</p>      *      * @param a  value 1      * @param b  value 2      * @param c  value 3      * @return  the smallest of the values      */     private static int min(int a, int b, int c) {         // Method copied from NumberUtils to avoid dependency on subpackage         if (b < a) {             a = b;         }         if (c < a) {             a = c;         }         return a;     } }


    最新回复(0)