View Javadoc
1   /* ====================================================================
2    * The Apache Software License, Version 1.1
3    *
4    * Copyright (c) 2002 The Apache Software Foundation.  All rights
5    * reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution, if
20   *    any, must include the following acknowledgement:
21   *       "This product includes software developed by the
22   *        Apache Software Foundation (http://www.codehaus.org/)."
23   *    Alternately, this acknowledgement may appear in the software itself,
24   *    if and wherever such third-party acknowledgements normally appear.
25   *
26   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
27   *    Foundation" must not be used to endorse or promote products derived
28   *    from this software without prior written permission. For written
29   *    permission, please contact codehaus@codehaus.org.
30   *
31   * 5. Products derived from this software may not be called "Apache"
32   *    nor may "Apache" appear in their names without prior written
33   *    permission of the Apache Software Foundation.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46   * SUCH DAMAGE.
47   * ====================================================================
48   *
49   * This software consists of voluntary contributions made by many
50   * individuals on behalf of the Apache Software Foundation.  For more
51   * information on the Apache Software Foundation, please see
52   * <http://www.codehaus.org/>.
53   */
54  package org.codehaus.plexus.util;
55  
56  import java.util.Arrays;
57  import java.util.Iterator;
58  import java.util.Locale;
59  import java.util.Map;
60  import java.util.Objects;
61  import java.util.StringTokenizer;
62  
63  /**
64   * <p>
65   * Common <code>String</code> manipulation routines.
66   * </p>
67   * <p>
68   * Originally from <a href="http://jakarta.apache.org/turbine/">Turbine</a> and the GenerationJavaCore library.
69   * </p>
70   *
71   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
72   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
73   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
74   * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
75   * @author <a href="mailto:ed@codehaus.org">Ed Korthof</a>
76   * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
77   * @author Stephen Colebourne
78   * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
79   * @author Holger Krauth
80   * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
81   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
82   * @since 1.0
83   *
84   */
85  public class StringUtils {
86      /**
87       * <p>
88       * <code>StringUtils</code> instances should NOT be constructed in standard programming. Instead, the class should
89       * be used as <code>StringUtils.trim(" foo ");</code>.
90       * </p>
91       * <p>
92       * This constructor is public to permit tools that require a JavaBean manager to operate.
93       * </p>
94       */
95      public StringUtils() {}
96  
97      // Empty
98      // --------------------------------------------------------------------------
99  
100     /**
101      * <p>
102      * Removes control characters, including whitespace, from both ends of this String, handling <code>null</code> by
103      * returning an empty String.
104      * </p>
105      *
106      * @see java.lang.String#trim()
107      * @param str the String to check
108      * @return the trimmed text (never <code>null</code>)
109      */
110     public static String clean(String str) {
111         return (str == null ? "" : str.trim());
112     }
113 
114     /**
115      * <p>
116      * Removes control characters, including whitespace, from both ends of this String, handling <code>null</code> by
117      * returning <code>null</code>.
118      * </p>
119      *
120      * @see java.lang.String#trim()
121      * @param str the String to check
122      * @return the trimmed text (or <code>null</code>)
123      */
124     public static String trim(String str) {
125         return (str == null ? null : str.trim());
126     }
127 
128     /**
129      * <p>
130      * Deletes all whitespaces from a String.
131      * </p>
132      * <p>
133      * Whitespace is defined by {@link Character#isWhitespace(char)}.
134      * </p>
135      *
136      * @param str String target to delete whitespace from
137      * @return the String without whitespaces
138      */
139     public static String deleteWhitespace(String str) {
140         StringBuilder buffer = new StringBuilder();
141         int sz = str.length();
142         for (int i = 0; i < sz; i++) {
143             if (!Character.isWhitespace(str.charAt(i))) {
144                 buffer.append(str.charAt(i));
145             }
146         }
147         return buffer.toString();
148     }
149 
150     /**
151      * Checks if a String is non <code>null</code> and is not empty (<code>length &gt; 0</code>).
152      *
153      * @param str the String to check
154      * @return true if the String is non-null, and not length zero
155      */
156     public static boolean isNotEmpty(String str) {
157         return ((str != null) && (!str.isEmpty()));
158     }
159 
160     /**
161      * Checks if a String is <code>null</code> or empty.
162      * <p>
163      * <strong>Note:</strong> In releases prior 3.5.0, this method trimmed the input string such that it worked
164      * the same as {@link #isBlank(String)}. Since release 3.5.0 it no longer returns {@code true} for strings
165      * containing only whitespace characters.
166      *
167      * @param str the String to check
168      * @return <code>true</code> if the String is <code>null</code>, or length zero
169      */
170     public static boolean isEmpty(String str) {
171         return ((str == null) || (str.isEmpty()));
172     }
173 
174     /**
175      * <p>
176      * Checks if a String is whitespace, empty ("") or null.
177      * </p>
178      *
179      * <pre>
180      * StringUtils.isBlank(null)      = true
181      * StringUtils.isBlank("")        = true
182      * StringUtils.isBlank(" ")       = true
183      * StringUtils.isBlank("bob")     = false
184      * StringUtils.isBlank("  bob  ") = false
185      * </pre>
186      *
187      * @param str the String to check, may be null
188      * @return <code>true</code> if the String is null, empty or whitespace
189      * @since 1.5.2
190      */
191     public static boolean isBlank(String str) {
192         int strLen;
193         if (str == null || (strLen = str.length()) == 0) {
194             return true;
195         }
196         for (int i = 0; i < strLen; i++) {
197             if (!Character.isWhitespace(str.charAt(i))) {
198                 return false;
199             }
200         }
201         return true;
202     }
203 
204     /**
205      * <p>
206      * Checks if a String is not empty (""), not null and not whitespace only.
207      * </p>
208      *
209      * <pre>
210      * StringUtils.isNotBlank(null)      = false
211      * StringUtils.isNotBlank("")        = false
212      * StringUtils.isNotBlank(" ")       = false
213      * StringUtils.isNotBlank("bob")     = true
214      * StringUtils.isNotBlank("  bob  ") = true
215      * </pre>
216      *
217      * @param str the String to check, may be null
218      * @return <code>true</code> if the String is not empty and not null and not whitespace
219      * @since 1.5.2
220      */
221     public static boolean isNotBlank(String str) {
222         return !StringUtils.isBlank(str);
223     }
224 
225     // Equals and IndexOf
226     // --------------------------------------------------------------------------
227 
228     /**
229      * <p>
230      * Compares two Strings, returning <code>true</code> if they are equal.
231      * </p>
232      * <p>
233      * <code>null</code>s are handled without exceptions. Two <code>null</code> references are considered to be equal.
234      * The comparison is case sensitive.
235      * </p>
236      *
237      * @see java.lang.String#equals(Object)
238      * @param str1 the first string
239      * @param str2 the second string
240      * @return <code>true</code> if the Strings are equal, case sensitive, or both <code>null</code>
241      * @see Objects#equals(Object, Object)
242      */
243     @Deprecated
244     public static boolean equals(String str1, String str2) {
245         return Objects.equals(str1, str2);
246     }
247 
248     /**
249      * <p>
250      * Compares two Strings, returning <code>true</code> if they are equal ignoring the case.
251      * </p>
252      * <p>
253      * <code>Nulls</code> are handled without exceptions. Two <code>null</code> references are considered equal.
254      * Comparison is case insensitive.
255      * </p>
256      *
257      * @see java.lang.String#equalsIgnoreCase(String)
258      * @param str1 the first string
259      * @param str2 the second string
260      * @return <code>true</code> if the Strings are equal, case insensitive, or both <code>null</code>
261      */
262     public static boolean equalsIgnoreCase(String str1, String str2) {
263         return (str1 == null ? str2 == null : str1.equalsIgnoreCase(str2));
264     }
265 
266     /**
267      * <p>
268      * Find the first index of any of a set of potential substrings.
269      * </p>
270      * <p>
271      * <code>null</code> String will return <code>-1</code>.
272      * </p>
273      *
274      * @param str the String to check
275      * @param searchStrs the Strings to search for
276      * @return the first index of any of the searchStrs in str
277      * @throws NullPointerException if any of searchStrs[i] is <code>null</code>
278      */
279     public static int indexOfAny(String str, String[] searchStrs) {
280         if ((str == null) || (searchStrs == null)) {
281             return -1;
282         }
283         int sz = searchStrs.length;
284 
285         // String's can't have a MAX_VALUEth index.
286         int ret = Integer.MAX_VALUE;
287 
288         int tmp;
289         for (String searchStr : searchStrs) {
290             tmp = str.indexOf(searchStr);
291             if (tmp == -1) {
292                 continue;
293             }
294 
295             if (tmp < ret) {
296                 ret = tmp;
297             }
298         }
299 
300         return (ret == Integer.MAX_VALUE) ? -1 : ret;
301     }
302 
303     /**
304      * <p>
305      * Find the latest index of any of a set of potential substrings.
306      * </p>
307      * <p>
308      * <code>null</code> string will return <code>-1</code>.
309      * </p>
310      *
311      * @param str the String to check
312      * @param searchStrs the Strings to search for
313      * @return the last index of any of the Strings
314      * @throws NullPointerException if any of searchStrs[i] is <code>null</code>
315      */
316     public static int lastIndexOfAny(String str, String[] searchStrs) {
317         if ((str == null) || (searchStrs == null)) {
318             return -1;
319         }
320         int ret = -1;
321         int tmp;
322         for (String searchStr : searchStrs) {
323             tmp = str.lastIndexOf(searchStr);
324             if (tmp > ret) {
325                 ret = tmp;
326             }
327         }
328         return ret;
329     }
330 
331     // Substring
332     // --------------------------------------------------------------------------
333 
334     /**
335      * <p>
336      * Gets a substring from the specified string avoiding exceptions.
337      * </p>
338      * <p>
339      * A negative start position can be used to start <code>n</code> characters from the end of the String.
340      * </p>
341      *
342      * @param str the String to get the substring from
343      * @param start the position to start from, negative means count back from the end of the String by this many
344      *            characters
345      * @return substring from start position
346      */
347     public static String substring(String str, int start) {
348         if (str == null) {
349             return null;
350         }
351 
352         // handle negatives, which means last n characters
353         if (start < 0) {
354             start = str.length() + start; // remember start is negative
355         }
356 
357         if (start < 0) {
358             start = 0;
359         }
360         if (start > str.length()) {
361             return "";
362         }
363 
364         return str.substring(start);
365     }
366 
367     /**
368      * <p>
369      * Gets a substring from the specified String avoiding exceptions.
370      * </p>
371      * <p>
372      * A negative start position can be used to start/end <code>n</code> characters from the end of the String.
373      * </p>
374      *
375      * @param str the String to get the substring from
376      * @param start the position to start from, negative means count back from the end of the string by this many
377      *            characters
378      * @param end the position to end at (exclusive), negative means count back from the end of the String by this many
379      *            characters
380      * @return substring from start position to end position
381      */
382     public static String substring(String str, int start, int end) {
383         if (str == null) {
384             return null;
385         }
386 
387         // handle negatives
388         if (end < 0) {
389             end = str.length() + end; // remember end is negative
390         }
391         if (start < 0) {
392             start = str.length() + start; // remember start is negative
393         }
394 
395         // check length next
396         if (end > str.length()) {
397             // check this works.
398             end = str.length();
399         }
400 
401         // if start is greater than end, return ""
402         if (start > end) {
403             return "";
404         }
405 
406         if (start < 0) {
407             start = 0;
408         }
409         if (end < 0) {
410             end = 0;
411         }
412 
413         return str.substring(start, end);
414     }
415 
416     /**
417      * <p>
418      * Gets the leftmost <code>n</code> characters of a String.
419      * </p>
420      * <p>
421      * If <code>n</code> characters are not available, or the String is <code>null</code>, the String will be returned
422      * without an exception.
423      * </p>
424      *
425      * @param str the String to get the leftmost characters from
426      * @param len the length of the required String
427      * @return the leftmost characters
428      * @throws IllegalArgumentException if len is less than zero
429      */
430     public static String left(String str, int len) {
431         if (len < 0) {
432             throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
433         }
434         if ((str == null) || (str.length() <= len)) {
435             return str;
436         } else {
437             return str.substring(0, len);
438         }
439     }
440 
441     /**
442      * <p>
443      * Gets the rightmost <code>n</code> characters of a String.
444      * </p>
445      * <p>
446      * If <code>n</code> characters are not available, or the String is <code>null</code>, the String will be returned
447      * without an exception.
448      * </p>
449      *
450      * @param str the String to get the rightmost characters from
451      * @param len the length of the required String
452      * @return the leftmost characters
453      * @throws IllegalArgumentException if len is less than zero
454      */
455     public static String right(String str, int len) {
456         if (len < 0) {
457             throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
458         }
459         if ((str == null) || (str.length() <= len)) {
460             return str;
461         } else {
462             return str.substring(str.length() - len);
463         }
464     }
465 
466     /**
467      * <p>
468      * Gets <code>n</code> characters from the middle of a String.
469      * </p>
470      * <p>
471      * If <code>n</code> characters are not available, the remainder of the String will be returned without an
472      * exception. If the String is <code>null</code>, <code>null</code> will be returned.
473      * </p>
474      *
475      * @param str the String to get the characters from
476      * @param pos the position to start from
477      * @param len the length of the required String
478      * @return the leftmost characters
479      * @throws IndexOutOfBoundsException if pos is out of bounds
480      * @throws IllegalArgumentException if len is less than zero
481      */
482     public static String mid(String str, int pos, int len) {
483         if ((pos < 0) || ((str != null) && (pos > str.length()))) {
484             throw new StringIndexOutOfBoundsException("String index " + pos + " is out of bounds");
485         }
486         if (len < 0) {
487             throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
488         }
489         if (str == null) {
490             return null;
491         }
492         if (str.length() <= (pos + len)) {
493             return str.substring(pos);
494         } else {
495             return str.substring(pos, pos + len);
496         }
497     }
498 
499     // Splitting
500     // --------------------------------------------------------------------------
501 
502     /**
503      * <p>
504      * Splits the provided text into a array, using whitespace as the separator.
505      * </p>
506      * <p>
507      * The separator is not included in the returned String array.
508      * </p>
509      *
510      * @param str the String to parse
511      * @return an array of parsed Strings
512      */
513     public static String[] split(String str) {
514         return split(str, null, -1);
515     }
516 
517     /**
518      * @param text The string to parse.
519      * @param separator Characters used as the delimiters. If <code>null</code>, splits on whitespace.
520      * @return an array of parsed Strings
521      */
522     public static String[] split(String text, String separator) {
523         return split(text, separator, -1);
524     }
525 
526     /**
527      * <p>
528      * Splits the provided text into a array, based on a given separator.
529      * </p>
530      * <p>
531      * The separator is not included in the returned String array. The maximum number of splits to perform can be
532      * controlled. A <code>null</code> separator will cause parsing to be on whitespace.
533      * </p>
534      * <p>
535      * This is useful for quickly splitting a String directly into an array of tokens, instead of an enumeration of
536      * tokens (as <code>StringTokenizer</code> does).
537      * </p>
538      *
539      * @param str The string to parse.
540      * @param separator Characters used as the delimiters. If <code>null</code>, splits on whitespace.
541      * @param max The maximum number of elements to include in the array. A zero or negative value implies no limit.
542      * @return an array of parsed Strings
543      */
544     public static String[] split(String str, String separator, int max) {
545         StringTokenizer tok;
546         if (separator == null) {
547             // Null separator means we're using StringTokenizer's default
548             // delimiter, which comprises all whitespace characters.
549             tok = new StringTokenizer(str);
550         } else {
551             tok = new StringTokenizer(str, separator);
552         }
553 
554         int listSize = tok.countTokens();
555         if ((max > 0) && (listSize > max)) {
556             listSize = max;
557         }
558 
559         String[] list = new String[listSize];
560         int i = 0;
561         int lastTokenBegin;
562         int lastTokenEnd = 0;
563         while (tok.hasMoreTokens()) {
564             if ((max > 0) && (i == listSize - 1)) {
565                 // In the situation where we hit the max yet have
566                 // tokens left over in our input, the last list
567                 // element gets all remaining text.
568                 String endToken = tok.nextToken();
569                 lastTokenBegin = str.indexOf(endToken, lastTokenEnd);
570                 list[i] = str.substring(lastTokenBegin);
571                 break;
572             } else {
573                 list[i] = tok.nextToken();
574                 lastTokenBegin = str.indexOf(list[i], lastTokenEnd);
575                 lastTokenEnd = lastTokenBegin + list[i].length();
576             }
577             i++;
578         }
579         return list;
580     }
581 
582     // Joining
583     // --------------------------------------------------------------------------
584     /**
585      * <p>
586      * Concatenates elements of an array into a single String.
587      * </p>
588      * <p>
589      * The difference from join is that concatenate has no delimiter.
590      * </p>
591      *
592      * @param array the array of values to concatenate.
593      * @return the concatenated string.
594      */
595     public static String concatenate(Object[] array) {
596         return join(array, "");
597     }
598 
599     /**
600      * <p>
601      * Joins the elements of the provided array into a single String containing the provided list of elements.
602      * </p>
603      * <p>
604      * No delimiter is added before or after the list. A <code>null</code> separator is the same as a blank String.
605      * </p>
606      *
607      * @param array the array of values to join together
608      * @param separator the separator character to use
609      * @return the joined String
610      */
611     public static String join(Object[] array, String separator) {
612         if (separator == null) {
613             separator = "";
614         }
615         int arraySize = array.length;
616         int bufSize = (arraySize == 0 ? 0 : (array[0].toString().length() + separator.length()) * arraySize);
617         StringBuilder buf = new StringBuilder(bufSize);
618 
619         for (int i = 0; i < arraySize; i++) {
620             if (i > 0) {
621                 buf.append(separator);
622             }
623             buf.append(array[i]);
624         }
625         return buf.toString();
626     }
627 
628     /**
629      * <p>
630      * Joins the elements of the provided <code>Iterator</code> into a single String containing the provided elements.
631      * </p>
632      * <p>
633      * No delimiter is added before or after the list. A <code>null</code> separator is the same as a blank String.
634      * </p>
635      *
636      * @param iterator the <code>Iterator</code> of values to join together
637      * @param separator the separator character to use
638      * @return the joined String
639      */
640     public static String join(Iterator<?> iterator, String separator) {
641         if (separator == null) {
642             separator = "";
643         }
644         StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
645         while (iterator.hasNext()) {
646             buf.append(iterator.next());
647             if (iterator.hasNext()) {
648                 buf.append(separator);
649             }
650         }
651         return buf.toString();
652     }
653 
654     // Replacing
655     // --------------------------------------------------------------------------
656 
657     /**
658      * <p>
659      * Replace a char with another char inside a larger String, once.
660      * </p>
661      * <p>
662      * A <code>null</code> reference passed to this method is a no-op.
663      * </p>
664      *
665      * @see #replace(String text, char repl, char with, int max)
666      * @param text text to search and replace in
667      * @param repl char to search for
668      * @param with char to replace with
669      * @return the text with any replacements processed
670      */
671     public static String replaceOnce(String text, char repl, char with) {
672         return replace(text, repl, with, 1);
673     }
674 
675     /**
676      * <p>
677      * Replace all occurrences of a char within another char.
678      * </p>
679      * <p>
680      * A <code>null</code> reference passed to this method is a no-op.
681      * </p>
682      *
683      * @see #replace(String text, char repl, char with, int max)
684      * @param text text to search and replace in
685      * @param repl char to search for
686      * @param with char to replace with
687      * @return the text with any replacements processed
688      */
689     public static String replace(String text, char repl, char with) {
690         return replace(text, repl, with, -1);
691     }
692 
693     /**
694      * <p>
695      * Replace a char with another char inside a larger String, for the first <code>max</code> values of the search
696      * char.
697      * </p>
698      * <p>
699      * A <code>null</code> reference passed to this method is a no-op.
700      * </p>
701      *
702      * @param text text to search and replace in
703      * @param repl char to search for
704      * @param with char to replace with
705      * @param max maximum number of values to replace, or <code>-1</code> if no maximum
706      * @return the text with any replacements processed
707      */
708     public static String replace(String text, char repl, char with, int max) {
709         return replace(text, String.valueOf(repl), String.valueOf(with), max);
710     }
711 
712     /**
713      * <p>
714      * Replace a String with another String inside a larger String, once.
715      * </p>
716      * <p>
717      * A <code>null</code> reference passed to this method is a no-op.
718      * </p>
719      *
720      * @see #replace(String text, String repl, String with, int max)
721      * @param text text to search and replace in
722      * @param repl String to search for
723      * @param with String to replace with
724      * @return the text with any replacements processed
725      */
726     public static String replaceOnce(String text, String repl, String with) {
727         return replace(text, repl, with, 1);
728     }
729 
730     /**
731      * <p>
732      * Replace all occurrences of a String within another String.
733      * </p>
734      * <p>
735      * A <code>null</code> reference passed to this method is a no-op.
736      * </p>
737      *
738      * @see #replace(String text, String repl, String with, int max)
739      * @param text text to search and replace in
740      * @param repl String to search for
741      * @param with String to replace with
742      * @return the text with any replacements processed
743      */
744     public static String replace(String text, String repl, String with) {
745         return replace(text, repl, with, -1);
746     }
747 
748     /**
749      * <p>
750      * Replace a String with another String inside a larger String, for the first <code>max</code> values of the search
751      * String.
752      * </p>
753      * <p>
754      * A <code>null</code> reference passed to this method is a no-op.
755      * </p>
756      *
757      * @param text text to search and replace in
758      * @param repl String to search for
759      * @param with String to replace with
760      * @param max maximum number of values to replace, or <code>-1</code> if no maximum
761      * @return the text with any replacements processed
762      */
763     public static String replace(String text, String repl, String with, int max) {
764         if ((text == null) || (repl == null) || (with == null) || (repl.length() == 0)) {
765             return text;
766         }
767 
768         StringBuilder buf = new StringBuilder(text.length());
769         int start = 0, end;
770         while ((end = text.indexOf(repl, start)) != -1) {
771             buf.append(text, start, end).append(with);
772             start = end + repl.length();
773 
774             if (--max == 0) {
775                 break;
776             }
777         }
778         buf.append(text, start, text.length());
779         return buf.toString();
780     }
781 
782     /**
783      * <p>
784      * Overlay a part of a String with another String.
785      * </p>
786      *
787      * @param text String to do overlaying in
788      * @param overlay String to overlay
789      * @param start int to start overlaying at
790      * @param end int to stop overlaying before
791      * @return String with overlayed text
792      * @throws NullPointerException if text or overlay is <code>null</code>
793      */
794     public static String overlayString(String text, String overlay, int start, int end) {
795         return new StringBuilder(start + overlay.length() + text.length() - end + 1)
796                 .append(text, 0, start)
797                 .append(overlay)
798                 .append(text, end, text.length())
799                 .toString();
800     }
801 
802     // Centering
803     // --------------------------------------------------------------------------
804 
805     /**
806      * <p>
807      * Center a String in a larger String of size <code>n</code>.
808      * </p>
809      * <p>
810      * Uses spaces as the value to buffer the String with. Equivalent to <code>center(str, size, " ")</code>.
811      * </p>
812      *
813      * @param str String to center
814      * @param size int size of new String
815      * @return String containing centered String
816      * @throws NullPointerException if str is <code>null</code>
817      */
818     public static String center(String str, int size) {
819         return center(str, size, " ");
820     }
821 
822     /**
823      * <p>
824      * Center a String in a larger String of size <code>n</code>.
825      * </p>
826      * <p>
827      * Uses a supplied String as the value to buffer the String with.
828      * </p>
829      *
830      * @param str String to center
831      * @param size int size of new String
832      * @param delim String to buffer the new String with
833      * @return String containing centered String
834      * @throws NullPointerException if str or delim is <code>null</code>
835      * @throws ArithmeticException if delim is the empty String
836      */
837     public static String center(String str, int size, String delim) {
838         int sz = str.length();
839         int p = size - sz;
840         if (p < 1) {
841             return str;
842         }
843         str = leftPad(str, sz + p / 2, delim);
844         str = rightPad(str, size, delim);
845         return str;
846     }
847 
848     // Chomping
849     // --------------------------------------------------------------------------
850 
851     /**
852      * <p>
853      * Remove the last newline, and everything after it from a String.
854      * </p>
855      *
856      * @param str String to chomp the newline from
857      * @return String without chomped newline
858      * @throws NullPointerException if str is <code>null</code>
859      */
860     public static String chomp(String str) {
861         return chomp(str, "\n");
862     }
863 
864     /**
865      * <p>
866      * Remove the last value of a supplied String, and everything after it from a String.
867      * </p>
868      *
869      * @param str String to chomp from
870      * @param sep String to chomp
871      * @return String without chomped ending
872      * @throws NullPointerException if str or sep is <code>null</code>
873      */
874     public static String chomp(String str, String sep) {
875         int idx = str.lastIndexOf(sep);
876         if (idx != -1) {
877             return str.substring(0, idx);
878         } else {
879             return str;
880         }
881     }
882 
883     /**
884      * <p>
885      * Remove a newline if and only if it is at the end of the supplied String.
886      * </p>
887      *
888      * @param str String to chomp from
889      * @return String without chomped ending
890      * @throws NullPointerException if str is <code>null</code>
891      */
892     public static String chompLast(String str) {
893         return chompLast(str, "\n");
894     }
895 
896     /**
897      * <p>
898      * Remove a value if and only if the String ends with that value.
899      * </p>
900      *
901      * @param str String to chomp from
902      * @param sep String to chomp
903      * @return String without chomped ending
904      * @throws NullPointerException if str or sep is <code>null</code>
905      */
906     public static String chompLast(String str, String sep) {
907         if (str.length() == 0) {
908             return str;
909         }
910         String sub = str.substring(str.length() - sep.length());
911         if (sep.equals(sub)) {
912             return str.substring(0, str.length() - sep.length());
913         } else {
914             return str;
915         }
916     }
917 
918     /**
919      * <p>
920      * Remove everything and return the last value of a supplied String, and everything after it from a String.
921      * </p>
922      *
923      * @param str String to chomp from
924      * @param sep String to chomp
925      * @return String chomped
926      * @throws NullPointerException if str or sep is <code>null</code>
927      */
928     public static String getChomp(String str, String sep) {
929         int idx = str.lastIndexOf(sep);
930         if (idx == str.length() - sep.length()) {
931             return sep;
932         } else if (idx != -1) {
933             return str.substring(idx);
934         } else {
935             return "";
936         }
937     }
938 
939     /**
940      * <p>
941      * Remove the first value of a supplied String, and everything before it from a String.
942      * </p>
943      *
944      * @param str String to chomp from
945      * @param sep String to chomp
946      * @return String without chomped beginning
947      * @throws NullPointerException if str or sep is <code>null</code>
948      */
949     public static String prechomp(String str, String sep) {
950         int idx = str.indexOf(sep);
951         if (idx != -1) {
952             return str.substring(idx + sep.length());
953         } else {
954             return str;
955         }
956     }
957 
958     /**
959      * <p>
960      * Remove and return everything before the first value of a supplied String from another String.
961      * </p>
962      *
963      * @param str String to chomp from
964      * @param sep String to chomp
965      * @return String prechomped
966      * @throws NullPointerException if str or sep is <code>null</code>
967      */
968     public static String getPrechomp(String str, String sep) {
969         int idx = str.indexOf(sep);
970         if (idx != -1) {
971             return str.substring(0, idx + sep.length());
972         } else {
973             return "";
974         }
975     }
976 
977     // Chopping
978     // --------------------------------------------------------------------------
979 
980     /**
981      * <p>
982      * Remove the last character from a String.
983      * </p>
984      * <p>
985      * If the String ends in <code>\r\n</code>, then remove both of them.
986      * </p>
987      *
988      * @param str String to chop last character from
989      * @return String without last character
990      * @throws NullPointerException if str is <code>null</code>
991      */
992     public static String chop(String str) {
993         if ("".equals(str)) {
994             return "";
995         }
996         if (str.length() == 1) {
997             return "";
998         }
999         int lastIdx = str.length() - 1;
1000         String ret = str.substring(0, lastIdx);
1001         char last = str.charAt(lastIdx);
1002         if (last == '\n') {
1003             if (ret.charAt(lastIdx - 1) == '\r') {
1004                 return ret.substring(0, lastIdx - 1);
1005             }
1006         }
1007         return ret;
1008     }
1009 
1010     /**
1011      * <p>
1012      * Remove <code>\n</code> from end of a String if it's there. If a <code>\r</code> precedes it, then remove that
1013      * too.
1014      * </p>
1015      *
1016      * @param str String to chop a newline from
1017      * @return String without newline
1018      * @throws NullPointerException if str is <code>null</code>
1019      */
1020     public static String chopNewline(String str) {
1021         int lastIdx = str.length() - 1;
1022         char last = str.charAt(lastIdx);
1023         if (last == '\n') {
1024             if (str.charAt(lastIdx - 1) == '\r') {
1025                 lastIdx--;
1026             }
1027         } else {
1028             lastIdx++;
1029         }
1030         return str.substring(0, lastIdx);
1031     }
1032 
1033     // Conversion
1034     // --------------------------------------------------------------------------
1035 
1036     // spec 3.10.6
1037     /**
1038      * <p>
1039      * Escapes any values it finds into their String form.
1040      * </p>
1041      * <p>
1042      * So a tab becomes the characters <code>'\\'</code> and <code>'t'</code>.
1043      * </p>
1044      *
1045      * @param str String to escape values in
1046      * @return String with escaped values
1047      * @throws NullPointerException if str is <code>null</code>
1048      */
1049     public static String escape(String str) {
1050         // improved with code from cybertiger@cyberiantiger.org
1051         // unicode from him, and default for < 32's.
1052         int sz = str.length();
1053         StringBuilder buffer = new StringBuilder(2 * sz);
1054         for (int i = 0; i < sz; i++) {
1055             char ch = str.charAt(i);
1056 
1057             // handle unicode
1058             if (ch > 0xfff) {
1059                 buffer.append("\\u" + Integer.toHexString(ch));
1060             } else if (ch > 0xff) {
1061                 buffer.append("\\u0" + Integer.toHexString(ch));
1062             } else if (ch > 0x7f) {
1063                 buffer.append("\\u00" + Integer.toHexString(ch));
1064             } else if (ch < 32) {
1065                 switch (ch) {
1066                     case '\b':
1067                         buffer.append('\\');
1068                         buffer.append('b');
1069                         break;
1070                     case '\n':
1071                         buffer.append('\\');
1072                         buffer.append('n');
1073                         break;
1074                     case '\t':
1075                         buffer.append('\\');
1076                         buffer.append('t');
1077                         break;
1078                     case '\f':
1079                         buffer.append('\\');
1080                         buffer.append('f');
1081                         break;
1082                     case '\r':
1083                         buffer.append('\\');
1084                         buffer.append('r');
1085                         break;
1086                     default:
1087                         if (ch > 0xf) {
1088                             buffer.append("\\u00" + Integer.toHexString(ch));
1089                         } else {
1090                             buffer.append("\\u000" + Integer.toHexString(ch));
1091                         }
1092                         break;
1093                 }
1094             } else {
1095                 switch (ch) {
1096                     case '\'':
1097                         buffer.append('\\');
1098                         buffer.append('\'');
1099                         break;
1100                     case '"':
1101                         buffer.append('\\');
1102                         buffer.append('"');
1103                         break;
1104                     case '\\':
1105                         buffer.append('\\');
1106                         buffer.append('\\');
1107                         break;
1108                     default:
1109                         buffer.append(ch);
1110                         break;
1111                 }
1112             }
1113         }
1114         return buffer.toString();
1115     }
1116 
1117     // Padding
1118     // --------------------------------------------------------------------------
1119 
1120     /**
1121      * <p>
1122      * Repeat a String <code>n</code> times to form a new string.
1123      * </p>
1124      *
1125      * @param str String to repeat
1126      * @param repeat number of times to repeat str
1127      * @return String with repeated String
1128      * @throws NegativeArraySizeException if <code>repeat &lt; 0</code>
1129      * @throws NullPointerException if str is <code>null</code>
1130      */
1131     public static String repeat(String str, int repeat) {
1132         StringBuilder buffer = new StringBuilder(repeat * str.length());
1133         for (int i = 0; i < repeat; i++) {
1134             buffer.append(str);
1135         }
1136         return buffer.toString();
1137     }
1138 
1139     /**
1140      * <p>
1141      * Right pad a String with spaces.
1142      * </p>
1143      * <p>
1144      * The String is padded to the size of <code>n</code>.
1145      * </p>
1146      *
1147      * @param str String to repeat
1148      * @param size number of times to repeat str
1149      * @return right padded String
1150      * @throws NullPointerException if str is <code>null</code>
1151      */
1152     public static String rightPad(String str, int size) {
1153         return rightPad(str, size, " ");
1154     }
1155 
1156     /**
1157      * <p>
1158      * Right pad a String with a specified string.
1159      * </p>
1160      * <p>
1161      * The String is padded to the size of <code>n</code>.
1162      * </p>
1163      *
1164      * @param str String to pad out
1165      * @param size size to pad to
1166      * @param delim String to pad with
1167      * @return right padded String
1168      * @throws NullPointerException if str or delim is <code>null</code>
1169      * @throws ArithmeticException if delim is the empty String
1170      */
1171     public static String rightPad(String str, int size, String delim) {
1172         size = (size - str.length()) / delim.length();
1173         if (size > 0) {
1174             str += repeat(delim, size);
1175         }
1176         return str;
1177     }
1178 
1179     /**
1180      * <p>
1181      * Left pad a String with spaces.
1182      * </p>
1183      * <p>
1184      * The String is padded to the size of <code>n</code>.
1185      * </p>
1186      *
1187      * @param str String to pad out
1188      * @param size size to pad to
1189      * @return left padded String
1190      * @throws NullPointerException if str or delim is <code>null</code>
1191      */
1192     public static String leftPad(String str, int size) {
1193         return leftPad(str, size, " ");
1194     }
1195 
1196     /**
1197      * Left pad a String with a specified string. Pad to a size of n.
1198      *
1199      * @param str String to pad out
1200      * @param size size to pad to
1201      * @param delim String to pad with
1202      * @return left padded String
1203      * @throws NullPointerException if str or delim is null
1204      * @throws ArithmeticException if delim is the empty string
1205      */
1206     public static String leftPad(String str, int size, String delim) {
1207         size = (size - str.length()) / delim.length();
1208         if (size > 0) {
1209             str = repeat(delim, size) + str;
1210         }
1211         return str;
1212     }
1213 
1214     // Stripping
1215     // --------------------------------------------------------------------------
1216 
1217     /**
1218      * <p>
1219      * Remove whitespace from the front and back of a String.
1220      * </p>
1221      *
1222      * @param str the String to remove whitespace from
1223      * @return the stripped String
1224      */
1225     public static String strip(String str) {
1226         return strip(str, null);
1227     }
1228 
1229     /**
1230      * <p>
1231      * Remove a specified String from the front and back of a String.
1232      * </p>
1233      * <p>
1234      * If whitespace is wanted to be removed, used the {@link #strip(java.lang.String)} method.
1235      * </p>
1236      *
1237      * @param str the String to remove a string from
1238      * @param delim the String to remove at start and end
1239      * @return the stripped String
1240      */
1241     public static String strip(String str, String delim) {
1242         str = stripStart(str, delim);
1243         return stripEnd(str, delim);
1244     }
1245 
1246     /**
1247      * <p>
1248      * Strip whitespace from the front and back of every String in the array.
1249      * </p>
1250      *
1251      * @param strs the Strings to remove whitespace from
1252      * @return the stripped Strings
1253      */
1254     public static String[] stripAll(String[] strs) {
1255         return stripAll(strs, null);
1256     }
1257 
1258     /**
1259      * <p>
1260      * Strip the specified delimiter from the front and back of every String in the array.
1261      * </p>
1262      *
1263      * @param strs the Strings to remove a String from
1264      * @param delimiter the String to remove at start and end
1265      * @return the stripped Strings
1266      */
1267     public static String[] stripAll(String[] strs, String delimiter) {
1268         if ((strs == null) || (strs.length == 0)) {
1269             return strs;
1270         }
1271         int sz = strs.length;
1272         String[] newArr = new String[sz];
1273         for (int i = 0; i < sz; i++) {
1274             newArr[i] = strip(strs[i], delimiter);
1275         }
1276         return newArr;
1277     }
1278 
1279     /**
1280      * <p>
1281      * Strip any of a supplied String from the end of a String.
1282      * </p>
1283      * <p>
1284      * If the strip String is <code>null</code>, whitespace is stripped.
1285      * </p>
1286      *
1287      * @param str the String to remove characters from
1288      * @param strip the String to remove
1289      * @return the stripped String
1290      */
1291     public static String stripEnd(String str, String strip) {
1292         if (str == null) {
1293             return null;
1294         }
1295         int end = str.length();
1296 
1297         if (strip == null) {
1298             while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
1299                 end--;
1300             }
1301         } else {
1302             while ((end != 0) && (strip.indexOf(str.charAt(end - 1)) != -1)) {
1303                 end--;
1304             }
1305         }
1306         return str.substring(0, end);
1307     }
1308 
1309     /**
1310      * <p>
1311      * Strip any of a supplied String from the start of a String.
1312      * </p>
1313      * <p>
1314      * If the strip String is <code>null</code>, whitespace is stripped.
1315      * </p>
1316      *
1317      * @param str the String to remove characters from
1318      * @param strip the String to remove
1319      * @return the stripped String
1320      */
1321     public static String stripStart(String str, String strip) {
1322         if (str == null) {
1323             return null;
1324         }
1325 
1326         int start = 0;
1327 
1328         int sz = str.length();
1329 
1330         if (strip == null) {
1331             while ((start != sz) && Character.isWhitespace(str.charAt(start))) {
1332                 start++;
1333             }
1334         } else {
1335             while ((start != sz) && (strip.indexOf(str.charAt(start)) != -1)) {
1336                 start++;
1337             }
1338         }
1339         return str.substring(start);
1340     }
1341 
1342     // Case conversion
1343     // --------------------------------------------------------------------------
1344 
1345     /**
1346      * <p>
1347      * Convert a String to upper case, <code>null</code> String returns <code>null</code>.
1348      * </p>
1349      *
1350      * @param str the String to uppercase
1351      * @return the upper cased String
1352      */
1353     public static String upperCase(String str) {
1354         if (str == null) {
1355             return null;
1356         }
1357         return str.toUpperCase();
1358     }
1359 
1360     /**
1361      * <p>
1362      * Convert a String to lower case, <code>null</code> String returns <code>null</code>.
1363      * </p>
1364      *
1365      * @param str the string to lowercase
1366      * @return the lower cased String
1367      */
1368     public static String lowerCase(String str) {
1369         if (str == null) {
1370             return null;
1371         }
1372         return str.toLowerCase();
1373     }
1374 
1375     /**
1376      * <p>
1377      * Uncapitalise a String.
1378      * </p>
1379      * <p>
1380      * That is, convert the first character into lower-case. <code>null</code> is returned as <code>null</code>.
1381      * </p>
1382      *
1383      * @param str the String to uncapitalise
1384      * @return uncapitalised String
1385      */
1386     public static String uncapitalise(String str) {
1387         if (str == null) {
1388             return null;
1389         } else if (str.length() == 0) {
1390             return "";
1391         } else {
1392             return new StringBuilder(str.length())
1393                     .append(Character.toLowerCase(str.charAt(0)))
1394                     .append(str, 1, str.length())
1395                     .toString();
1396         }
1397     }
1398 
1399     /**
1400      * <p>
1401      * Capitalise a String.
1402      * </p>
1403      * <p>
1404      * That is, convert the first character into title-case. <code>null</code> is returned as <code>null</code>.
1405      * </p>
1406      *
1407      * @param str the String to capitalise
1408      * @return capitalised String
1409      */
1410     public static String capitalise(String str) {
1411         if (str == null) {
1412             return null;
1413         } else if (str.length() == 0) {
1414             return "";
1415         } else {
1416             return new StringBuilder(str.length())
1417                     .append(Character.toTitleCase(str.charAt(0)))
1418                     .append(str, 1, str.length())
1419                     .toString();
1420         }
1421     }
1422 
1423     /**
1424      * <p>
1425      * Swaps the case of String.
1426      * </p>
1427      * <p>
1428      * Properly looks after making sure the start of words are Titlecase and not Uppercase.
1429      * </p>
1430      * <p>
1431      * <code>null</code> is returned as <code>null</code>.
1432      * </p>
1433      *
1434      * @param str the String to swap the case of
1435      * @return the modified String
1436      */
1437     public static String swapCase(String str) {
1438         if (str == null) {
1439             return null;
1440         }
1441         int sz = str.length();
1442         StringBuilder buffer = new StringBuilder(sz);
1443 
1444         boolean whitespace = false;
1445         char ch;
1446         char tmp;
1447 
1448         for (int i = 0; i < sz; i++) {
1449             ch = str.charAt(i);
1450             if (Character.isUpperCase(ch)) {
1451                 tmp = Character.toLowerCase(ch);
1452             } else if (Character.isTitleCase(ch)) {
1453                 tmp = Character.toLowerCase(ch);
1454             } else if (Character.isLowerCase(ch)) {
1455                 if (whitespace) {
1456                     tmp = Character.toTitleCase(ch);
1457                 } else {
1458                     tmp = Character.toUpperCase(ch);
1459                 }
1460             } else {
1461                 tmp = ch;
1462             }
1463             buffer.append(tmp);
1464             whitespace = Character.isWhitespace(ch);
1465         }
1466         return buffer.toString();
1467     }
1468 
1469     /**
1470      * <p>
1471      * Capitalise all the words in a String.
1472      * </p>
1473      * <p>
1474      * Uses {@link Character#isWhitespace(char)} as a separator between words.
1475      * </p>
1476      * <p>
1477      * <code>null</code> will return <code>null</code>.
1478      * </p>
1479      *
1480      * @param str the String to capitalise
1481      * @return capitalised String
1482      */
1483     public static String capitaliseAllWords(String str) {
1484         if (str == null) {
1485             return null;
1486         }
1487         int sz = str.length();
1488         StringBuilder buffer = new StringBuilder(sz);
1489         boolean space = true;
1490         for (int i = 0; i < sz; i++) {
1491             char ch = str.charAt(i);
1492             if (Character.isWhitespace(ch)) {
1493                 buffer.append(ch);
1494                 space = true;
1495             } else if (space) {
1496                 buffer.append(Character.toTitleCase(ch));
1497                 space = false;
1498             } else {
1499                 buffer.append(ch);
1500             }
1501         }
1502         return buffer.toString();
1503     }
1504 
1505     /**
1506      * <p>
1507      * Uncapitalise all the words in a string.
1508      * </p>
1509      * <p>
1510      * Uses {@link Character#isWhitespace(char)} as a separator between words.
1511      * </p>
1512      * <p>
1513      * <code>null</code> will return <code>null</code>.
1514      * </p>
1515      *
1516      * @param str the string to uncapitalise
1517      * @return uncapitalised string
1518      */
1519     public static String uncapitaliseAllWords(String str) {
1520         if (str == null) {
1521             return null;
1522         }
1523         int sz = str.length();
1524         StringBuilder buffer = new StringBuilder(sz);
1525         boolean space = true;
1526         for (int i = 0; i < sz; i++) {
1527             char ch = str.charAt(i);
1528             if (Character.isWhitespace(ch)) {
1529                 buffer.append(ch);
1530                 space = true;
1531             } else if (space) {
1532                 buffer.append(Character.toLowerCase(ch));
1533                 space = false;
1534             } else {
1535                 buffer.append(ch);
1536             }
1537         }
1538         return buffer.toString();
1539     }
1540 
1541     // Nested extraction
1542     // --------------------------------------------------------------------------
1543 
1544     /**
1545      * <p>
1546      * Get the String that is nested in between two instances of the same String.
1547      * </p>
1548      * <p>
1549      * If <code>str</code> is <code>null</code>, will return <code>null</code>.
1550      * </p>
1551      *
1552      * @param str the String containing nested-string
1553      * @param tag the String before and after nested-string
1554      * @return the String that was nested, or <code>null</code>
1555      * @throws NullPointerException if tag is <code>null</code>
1556      */
1557     public static String getNestedString(String str, String tag) {
1558         return getNestedString(str, tag, tag);
1559     }
1560 
1561     /**
1562      * <p>
1563      * Get the String that is nested in between two Strings.
1564      * </p>
1565      *
1566      * @param str the String containing nested-string
1567      * @param open the String before nested-string
1568      * @param close the String after nested-string
1569      * @return the String that was nested, or <code>null</code>
1570      * @throws NullPointerException if open or close is <code>null</code>
1571      */
1572     public static String getNestedString(String str, String open, String close) {
1573         if (str == null) {
1574             return null;
1575         }
1576         int start = str.indexOf(open);
1577         if (start != -1) {
1578             int end = str.indexOf(close, start + open.length());
1579             if (end != -1) {
1580                 return str.substring(start + open.length(), end);
1581             }
1582         }
1583         return null;
1584     }
1585 
1586     /**
1587      * <p>
1588      * How many times is the substring in the larger String.
1589      * </p>
1590      * <p>
1591      * <code>null</code> returns <code>0</code>.
1592      * </p>
1593      *
1594      * @param str the String to check
1595      * @param sub the substring to count
1596      * @return the number of occurrences, 0 if the String is <code>null</code>
1597      * @throws NullPointerException if sub is <code>null</code>
1598      */
1599     public static int countMatches(String str, String sub) {
1600         if (sub.equals("")) {
1601             return 0;
1602         }
1603         if (str == null) {
1604             return 0;
1605         }
1606         int count = 0;
1607         int idx = 0;
1608         while ((idx = str.indexOf(sub, idx)) != -1) {
1609             count++;
1610             idx += sub.length();
1611         }
1612         return count;
1613     }
1614 
1615     // Character Tests
1616     // --------------------------------------------------------------------------
1617 
1618     /**
1619      * <p>
1620      * Checks if the String contains only unicode letters.
1621      * </p>
1622      * <p>
1623      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1624      * </p>
1625      *
1626      * @param str the String to check
1627      * @return <code>true</code> if only contains letters, and is non-null
1628      */
1629     public static boolean isAlpha(String str) {
1630         if (str == null) {
1631             return false;
1632         }
1633         int sz = str.length();
1634         for (int i = 0; i < sz; i++) {
1635             if (Character.isLetter(str.charAt(i)) == false) {
1636                 return false;
1637             }
1638         }
1639         return true;
1640     }
1641 
1642     /**
1643      * <p>
1644      * Checks if the String contains only whitespace.
1645      * </p>
1646      * <p>
1647      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1648      * </p>
1649      *
1650      * @param str the String to check
1651      * @return <code>true</code> if only contains whitespace, and is non-null
1652      */
1653     public static boolean isWhitespace(String str) {
1654         if (str == null) {
1655             return false;
1656         }
1657         int sz = str.length();
1658         for (int i = 0; i < sz; i++) {
1659             if ((Character.isWhitespace(str.charAt(i)) == false)) {
1660                 return false;
1661             }
1662         }
1663         return true;
1664     }
1665 
1666     /**
1667      * <p>
1668      * Checks if the String contains only unicode letters and space (<code>' '</code>).
1669      * </p>
1670      * <p>
1671      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1672      * </p>
1673      *
1674      * @param str the String to check
1675      * @return <code>true</code> if only contains letters and space, and is non-null
1676      */
1677     public static boolean isAlphaSpace(String str) {
1678         if (str == null) {
1679             return false;
1680         }
1681         int sz = str.length();
1682         for (int i = 0; i < sz; i++) {
1683             if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
1684                 return false;
1685             }
1686         }
1687         return true;
1688     }
1689 
1690     /**
1691      * <p>
1692      * Checks if the String contains only unicode letters or digits.
1693      * </p>
1694      * <p>
1695      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1696      * </p>
1697      *
1698      * @param str the String to check
1699      * @return <code>true</code> if only contains letters or digits, and is non-null
1700      */
1701     public static boolean isAlphanumeric(String str) {
1702         if (str == null) {
1703             return false;
1704         }
1705         int sz = str.length();
1706         for (int i = 0; i < sz; i++) {
1707             if (Character.isLetterOrDigit(str.charAt(i)) == false) {
1708                 return false;
1709             }
1710         }
1711         return true;
1712     }
1713 
1714     /**
1715      * <p>
1716      * Checks if the String contains only unicode letters, digits or space (<code>' '</code>).
1717      * </p>
1718      * <p>
1719      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1720      * </p>
1721      *
1722      * @param str the String to check
1723      * @return <code>true</code> if only contains letters, digits or space, and is non-null
1724      */
1725     public static boolean isAlphanumericSpace(String str) {
1726         if (str == null) {
1727             return false;
1728         }
1729         int sz = str.length();
1730         for (int i = 0; i < sz; i++) {
1731             if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
1732                 return false;
1733             }
1734         }
1735         return true;
1736     }
1737 
1738     /**
1739      * <p>
1740      * Checks if the String contains only unicode digits.
1741      * </p>
1742      * <p>
1743      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1744      * </p>
1745      *
1746      * @param str the String to check
1747      * @return <code>true</code> if only contains digits, and is non-null
1748      */
1749     public static boolean isNumeric(String str) {
1750         if (str == null) {
1751             return false;
1752         }
1753         int sz = str.length();
1754         for (int i = 0; i < sz; i++) {
1755             if (Character.isDigit(str.charAt(i)) == false) {
1756                 return false;
1757             }
1758         }
1759         return true;
1760     }
1761 
1762     /**
1763      * <p>
1764      * Checks if the String contains only unicode digits or space (<code>' '</code>).
1765      * </p>
1766      * <p>
1767      * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>.
1768      * </p>
1769      *
1770      * @param str the String to check
1771      * @return <code>true</code> if only contains digits or space, and is non-null
1772      */
1773     public static boolean isNumericSpace(String str) {
1774         if (str == null) {
1775             return false;
1776         }
1777         int sz = str.length();
1778         for (int i = 0; i < sz; i++) {
1779             if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
1780                 return false;
1781             }
1782         }
1783         return true;
1784     }
1785 
1786     // Defaults
1787     // --------------------------------------------------------------------------
1788 
1789     /**
1790      * <p>
1791      * Returns either the passed in <code>Object</code> as a String, or, if the <code>Object</code> is
1792      * <code>null</code>, an empty String.
1793      * </p>
1794      *
1795      * @param obj the Object to check
1796      * @return the passed in Object's toString, or blank if it was <code>null</code>
1797      * @see Objects#toString(Object, String)
1798      */
1799     @Deprecated
1800     public static String defaultString(Object obj) {
1801         return defaultString(obj, "");
1802     }
1803 
1804     /**
1805      * <p>
1806      * Returns either the passed in <code>Object</code> as a String, or, if the <code>Object</code> is
1807      * <code>null</code>, a passed in default String.
1808      * </p>
1809      *
1810      * @param obj the Object to check
1811      * @param defaultString the default String to return if str is <code>null</code>
1812      * @return the passed in string, or the default if it was <code>null</code>
1813      * @see Objects#toString(Object, String)
1814      */
1815     @Deprecated
1816     public static String defaultString(Object obj, String defaultString) {
1817         return Objects.toString(obj, defaultString);
1818     }
1819 
1820     // Reversing
1821     // --------------------------------------------------------------------------
1822 
1823     /**
1824      * <p>
1825      * Reverse a String.
1826      * </p>
1827      * <p>
1828      * <code>null</code> String returns <code>null</code>.
1829      * </p>
1830      *
1831      * @param str the String to reverse
1832      * @return the reversed String
1833      */
1834     public static String reverse(String str) {
1835         if (str == null) {
1836             return null;
1837         }
1838         return new StringBuilder(str).reverse().toString();
1839     }
1840 
1841     /**
1842      * <p>
1843      * Reverses a String that is delimited by a specific character.
1844      * </p>
1845      * <p>
1846      * The Strings between the delimiters are not reversed. Thus java.lang.String becomes String.lang.java (if the
1847      * delimiter is <code>'.'</code>).
1848      * </p>
1849      *
1850      * @param str the String to reverse
1851      * @param delimiter the delimiter to use
1852      * @return the reversed String
1853      */
1854     public static String reverseDelimitedString(String str, String delimiter) {
1855         // could implement manually, but simple way is to reuse other,
1856         // probably slower, methods.
1857         String[] strs = split(str, delimiter);
1858         reverseArray(strs);
1859         return join(strs, delimiter);
1860     }
1861 
1862     /**
1863      * <p>
1864      * Reverses an array.
1865      * </p>
1866      * <p>
1867      * TAKEN FROM CollectionsUtils.
1868      * </p>
1869      *
1870      * @param array the array to reverse
1871      */
1872     private static void reverseArray(Object[] array) {
1873         int i = 0;
1874         int j = array.length - 1;
1875         Object tmp;
1876 
1877         while (j > i) {
1878             tmp = array[j];
1879             array[j] = array[i];
1880             array[i] = tmp;
1881             j--;
1882             i++;
1883         }
1884     }
1885 
1886     // Abbreviating
1887     // --------------------------------------------------------------------------
1888 
1889     /**
1890      * @return Turn "Now is the time for all good men" into "Now is the time for..."
1891      * <p>
1892      * Specifically:
1893      * <p>
1894      * If str is less than max characters long, return it. Else abbreviate it to (substring(str, 0, max-3) + "..."). If
1895      * maxWidth is less than 3, throw an IllegalArgumentException. In no case will it return a string of length greater
1896      * than maxWidth.
1897      * @param s string
1898      * @param maxWidth maximum length of result string
1899      **/
1900     public static String abbreviate(String s, int maxWidth) {
1901         return abbreviate(s, 0, maxWidth);
1902     }
1903 
1904     /**
1905      * @return Turn "Now is the time for all good men" into "...is the time for..."
1906      *
1907      * Works like abbreviate(String, int), but allows you to specify a "left edge" offset. Note that this left edge is
1908      * not necessarily going to be the leftmost character in the result, or the first character following the ellipses,
1909      * but it will appear somewhere in the result. In no case will it return a string of length greater than maxWidth.
1910      * @param s string
1911      * @param offset left edge of source string
1912      * @param maxWidth maximum length of result string
1913      **/
1914     public static String abbreviate(String s, int offset, int maxWidth) {
1915         if (maxWidth < 4) {
1916             throw new IllegalArgumentException("Minimum abbreviation width is 4");
1917         }
1918         if (s.length() <= maxWidth) {
1919             return s;
1920         }
1921         if (offset > s.length()) {
1922             offset = s.length();
1923         }
1924         if ((s.length() - offset) < (maxWidth - 3)) {
1925             offset = s.length() - (maxWidth - 3);
1926         }
1927         if (offset <= 4) {
1928             return s.substring(0, maxWidth - 3) + "...";
1929         }
1930         if (maxWidth < 7) {
1931             throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
1932         }
1933         if ((offset + (maxWidth - 3)) < s.length()) {
1934             return "..." + abbreviate(s.substring(offset), maxWidth - 3);
1935         }
1936         return "..." + s.substring(s.length() - (maxWidth - 3));
1937     }
1938 
1939     // Difference
1940     // --------------------------------------------------------------------------
1941 
1942     /**
1943      * Compare two strings, and return the portion where they differ. (More precisely, return the remainder of the
1944      * second string, starting from where it's different from the first.)
1945      * <p>
1946      * E.g. strdiff("i am a machine", "i am a robot") -&gt; "robot"
1947      * @param s1 string
1948      * @param s2 string
1949      * @return the portion of s2 where it differs from s1; returns the empty string ("") if they are equal
1950      **/
1951     public static String difference(String s1, String s2) {
1952         int at = differenceAt(s1, s2);
1953         if (at == -1) {
1954             return "";
1955         }
1956         return s2.substring(at);
1957     }
1958 
1959     /**
1960      * Compare two strings, and return the index at which the strings begin to differ.
1961      * <p>
1962      * E.g. strdiff("i am a machine", "i am a robot") -&gt; 7
1963      * </p>
1964      * @param s1 string
1965      * @param s2 string
1966      * @return the index where s2 and s1 begin to differ; -1 if they are equal
1967      **/
1968     public static int differenceAt(String s1, String s2) {
1969         int i;
1970         for (i = 0; (i < s1.length()) && (i < s2.length()); ++i) {
1971             if (s1.charAt(i) != s2.charAt(i)) {
1972                 break;
1973             }
1974         }
1975         if ((i < s2.length()) || (i < s1.length())) {
1976             return i;
1977         }
1978         return -1;
1979     }
1980 
1981     public static String interpolate(String text, Map<?, ?> namespace) {
1982         Iterator<?> keys = namespace.keySet().iterator();
1983 
1984         while (keys.hasNext()) {
1985             String key = keys.next().toString();
1986 
1987             Object obj = namespace.get(key);
1988 
1989             if (obj == null) {
1990                 throw new NullPointerException("The value of the key '" + key + "' is null.");
1991             }
1992 
1993             String value = obj.toString();
1994 
1995             text = replace(text, "${" + key + "}", value);
1996 
1997             if (!key.contains(" ")) {
1998                 text = replace(text, "$" + key, value);
1999             }
2000         }
2001         return text;
2002     }
2003 
2004     public static String removeAndHump(String data, String replaceThis) {
2005         String temp;
2006 
2007         StringBuilder out = new StringBuilder();
2008 
2009         temp = data;
2010 
2011         StringTokenizer st = new StringTokenizer(temp, replaceThis);
2012 
2013         while (st.hasMoreTokens()) {
2014             String element = (String) st.nextElement();
2015 
2016             out.append(capitalizeFirstLetter(element));
2017         }
2018 
2019         return out.toString();
2020     }
2021 
2022     public static String capitalizeFirstLetter(String data) {
2023         char firstLetter = Character.toTitleCase(data.substring(0, 1).charAt(0));
2024 
2025         String restLetters = data.substring(1);
2026 
2027         return firstLetter + restLetters;
2028     }
2029 
2030     public static String lowercaseFirstLetter(String data) {
2031         char firstLetter = Character.toLowerCase(data.substring(0, 1).charAt(0));
2032 
2033         String restLetters = data.substring(1);
2034 
2035         return firstLetter + restLetters;
2036     }
2037 
2038     public static String addAndDeHump(String view) {
2039         StringBuilder sb = new StringBuilder();
2040 
2041         for (int i = 0; i < view.length(); i++) {
2042             if ((i != 0) && Character.isUpperCase(view.charAt(i))) {
2043                 sb.append('-');
2044             }
2045 
2046             sb.append(view.charAt(i));
2047         }
2048 
2049         return sb.toString().trim().toLowerCase(Locale.ENGLISH);
2050     }
2051 
2052     /**
2053      * <p>
2054      * Quote and escape a String with the given character, handling <code>null</code>.
2055      * </p>
2056      *
2057      * <pre>
2058      * StringUtils.quoteAndEscape(null, *)    = null
2059      * StringUtils.quoteAndEscape("", *)      = ""
2060      * StringUtils.quoteAndEscape("abc", '"') = abc
2061      * StringUtils.quoteAndEscape("a\"bc", '"') = "a\"bc"
2062      * StringUtils.quoteAndEscape("a\"bc", '\'') = 'a\"bc'
2063      * </pre>
2064      *
2065      * @param source the source String
2066      * @param quoteChar the char used to quote
2067      * @return the String quoted and escaped
2068      * @since 1.5.1
2069      * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
2070      */
2071     public static String quoteAndEscape(String source, char quoteChar) {
2072         return quoteAndEscape(source, quoteChar, new char[] {quoteChar}, new char[] {' '}, '\\', false);
2073     }
2074 
2075     /**
2076      * <p>
2077      * Quote and escape a String with the given character, handling <code>null</code>.
2078      * </p>
2079      *
2080      * @param source the source String
2081      * @param quoteChar the char used to quote
2082      * @param quotingTriggers chars generating a quote
2083      * @return the String quoted and escaped
2084      * @since 1.5.1
2085      * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
2086      */
2087     public static String quoteAndEscape(String source, char quoteChar, char[] quotingTriggers) {
2088         return quoteAndEscape(source, quoteChar, new char[] {quoteChar}, quotingTriggers, '\\', false);
2089     }
2090 
2091     /**
2092      * @param source the source String
2093      * @param quoteChar the char used to quote
2094      * @param escapedChars chars to escape
2095      * @param escapeChar char used for escaping
2096      * @param force force the quoting
2097      * @return the String quoted and escaped
2098      * @since 1.5.1
2099      * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
2100      */
2101     public static String quoteAndEscape(
2102             String source, char quoteChar, final char[] escapedChars, char escapeChar, boolean force) {
2103         return quoteAndEscape(source, quoteChar, escapedChars, new char[] {' '}, escapeChar, force);
2104     }
2105 
2106     /**
2107      * @param source the source String
2108      * @param quoteChar the char used to quote
2109      * @param escapedChars chars to escape
2110      * @param quotingTriggers chars generating a quote
2111      * @param escapeChar char used for escaping
2112      * @param force force the quoting
2113      * @return the String quoted and escaped
2114      * @since 1.5.1
2115      */
2116     public static String quoteAndEscape(
2117             String source,
2118             char quoteChar,
2119             final char[] escapedChars,
2120             final char[] quotingTriggers,
2121             char escapeChar,
2122             boolean force) {
2123         return quoteAndEscape(source, quoteChar, escapedChars, quotingTriggers, escapeChar + "%s", force);
2124     }
2125 
2126     /**
2127      * @param source the source String
2128      * @param quoteChar the char used to quote
2129      * @param escapedChars chars to escape
2130      * @param quotingTriggers chars generating a quote
2131      * @param escapePattern pattern used for escaping
2132      * @param force force the quoting
2133      * @return the String quoted and escaped
2134      * @since 3.0.4
2135      */
2136     public static String quoteAndEscape(
2137             String source,
2138             char quoteChar,
2139             final char[] escapedChars,
2140             final char[] quotingTriggers,
2141             String escapePattern,
2142             boolean force) {
2143         if (source == null) {
2144             return null;
2145         }
2146 
2147         if (!force
2148                 && source.startsWith(Character.toString(quoteChar))
2149                 && source.endsWith(Character.toString(quoteChar))) {
2150             return source;
2151         }
2152 
2153         String escaped = escape(source, escapedChars, escapePattern);
2154 
2155         boolean quote = false;
2156         if (force) {
2157             quote = true;
2158         } else if (!escaped.equals(source)) {
2159             quote = true;
2160         } else {
2161             for (char quotingTrigger : quotingTriggers) {
2162                 if (escaped.indexOf(quotingTrigger) > -1) {
2163                     quote = true;
2164                     break;
2165                 }
2166             }
2167         }
2168 
2169         if (quote) {
2170             return quoteChar + escaped + quoteChar;
2171         }
2172 
2173         return escaped;
2174     }
2175 
2176     /**
2177      * @param source the source String
2178      * @param escapedChars chars to escape
2179      * @param escapeChar char used for escaping
2180      * @return the String escaped
2181      * @since 1.5.1
2182      */
2183     public static String escape(String source, final char[] escapedChars, char escapeChar) {
2184         return escape(source, escapedChars, escapeChar + "%s");
2185     }
2186 
2187     /**
2188      * @param source the source String
2189      * @param escapedChars chars to escape
2190      * @param escapePattern pattern used for escaping
2191      * @return the String escaped
2192      * @since 3.0.4
2193      */
2194     public static String escape(String source, final char[] escapedChars, String escapePattern) {
2195         if (source == null) {
2196             return null;
2197         }
2198 
2199         char[] eqc = new char[escapedChars.length];
2200         System.arraycopy(escapedChars, 0, eqc, 0, escapedChars.length);
2201         Arrays.sort(eqc);
2202 
2203         StringBuilder buffer = new StringBuilder(source.length());
2204 
2205         for (int i = 0; i < source.length(); i++) {
2206             final char c = source.charAt(i);
2207             int result = Arrays.binarySearch(eqc, c);
2208 
2209             if (result > -1) {
2210                 buffer.append(String.format(escapePattern, c));
2211             } else {
2212                 buffer.append(c);
2213             }
2214         }
2215 
2216         return buffer.toString();
2217     }
2218 
2219     /**
2220      * Remove all duplicate whitespace characters and line terminators are replaced with a single space.
2221      *
2222      * @param s a not null String
2223      * @return a string with unique whitespace.
2224      * @since 1.5.7
2225      */
2226     public static String removeDuplicateWhitespace(String s) {
2227         StringBuilder result = new StringBuilder();
2228         int length = s.length();
2229         boolean isPreviousWhiteSpace = false;
2230         for (int i = 0; i < length; i++) {
2231             char c = s.charAt(i);
2232             boolean thisCharWhiteSpace = Character.isWhitespace(c);
2233             if (!(isPreviousWhiteSpace && thisCharWhiteSpace)) {
2234                 result.append(c);
2235             }
2236             isPreviousWhiteSpace = thisCharWhiteSpace;
2237         }
2238         return result.toString();
2239     }
2240 
2241     /**
2242      * Parses the given String and replaces all occurrences of '\n', '\r' and '\r\n' with the system line separator.
2243      *
2244      * @param s a not null String
2245      * @return a String that contains only System line separators.
2246      * @see #unifyLineSeparators(String, String)
2247      * @since 1.5.7
2248      */
2249     public static String unifyLineSeparators(String s) {
2250         return unifyLineSeparators(s, System.getProperty("line.separator"));
2251     }
2252 
2253     /**
2254      * Parses the given String and replaces all occurrences of '\n', '\r' and '\r\n' with the system line separator.
2255      *
2256      * @param s a not null String
2257      * @param ls the wanted line separator ("\n" on UNIX), if null using the System line separator.
2258      * @return a String that contains only System line separators.
2259      * @throws IllegalArgumentException if ls is not '\n', '\r' and '\r\n' characters.
2260      * @since 1.5.7
2261      */
2262     public static String unifyLineSeparators(String s, String ls) {
2263         if (s == null) {
2264             return null;
2265         }
2266 
2267         if (ls == null) {
2268             ls = System.getProperty("line.separator");
2269         }
2270 
2271         if (!(ls.equals("\n") || ls.equals("\r") || ls.equals("\r\n"))) {
2272             throw new IllegalArgumentException("Requested line separator is invalid.");
2273         }
2274 
2275         int length = s.length();
2276 
2277         StringBuilder buffer = new StringBuilder(length);
2278         for (int i = 0; i < length; i++) {
2279             if (s.charAt(i) == '\r') {
2280                 if ((i + 1) < length && s.charAt(i + 1) == '\n') {
2281                     i++;
2282                 }
2283 
2284                 buffer.append(ls);
2285             } else if (s.charAt(i) == '\n') {
2286                 buffer.append(ls);
2287             } else {
2288                 buffer.append(s.charAt(i));
2289             }
2290         }
2291 
2292         return buffer.toString();
2293     }
2294 
2295     /**
2296      * <p>
2297      * Checks if String contains a search character, handling <code>null</code>. This method uses
2298      * {@link String#indexOf(int)}.
2299      * </p>
2300      * <p>
2301      * A <code>null</code> or empty ("") String will return <code>false</code>.
2302      * </p>
2303      *
2304      * <pre>
2305      * StringUtils.contains(null, *)    = false
2306      * StringUtils.contains("", *)      = false
2307      * StringUtils.contains("abc", 'a') = true
2308      * StringUtils.contains("abc", 'z') = false
2309      * </pre>
2310      *
2311      * @param str the String to check, may be null
2312      * @param searchChar the character to find
2313      * @return true if the String contains the search character, false if not or <code>null</code> string input
2314      * @since 1.5.7
2315      */
2316     public static boolean contains(String str, char searchChar) {
2317         if (isEmpty(str)) {
2318             return false;
2319         }
2320         return str.indexOf(searchChar) >= 0;
2321     }
2322 
2323     /**
2324      * <p>
2325      * Checks if String contains a search String, handling <code>null</code>. This method uses
2326      * {@link String#indexOf(int)}.
2327      * </p>
2328      * <p>
2329      * A <code>null</code> String will return <code>false</code>.
2330      * </p>
2331      *
2332      * <pre>
2333      * StringUtils.contains(null, *)     = false
2334      * StringUtils.contains(*, null)     = false
2335      * StringUtils.contains("", "")      = true
2336      * StringUtils.contains("abc", "")   = true
2337      * StringUtils.contains("abc", "a")  = true
2338      * StringUtils.contains("abc", "z")  = false
2339      * </pre>
2340      *
2341      * @param str the String to check, may be null
2342      * @param searchStr the String to find, may be null
2343      * @return true if the String contains the search String, false if not or <code>null</code> string input
2344      * @since 1.5.7
2345      */
2346     public static boolean contains(String str, String searchStr) {
2347         if (str == null || searchStr == null) {
2348             return false;
2349         }
2350         return str.contains(searchStr);
2351     }
2352 }