h101com 发表于 2015-8-2 11:58:48

java开发_org.apache.commons.lang.StringUtils工具类源码

  在之前写了一篇关于""和null区别的文章。
  下面是文章的地址:
  http://www.iyunv.com/hongten/archive/2012/11/08/java_null.html
  下面看看org.apache.commons.lang.StringUtils工具类源码



   1 /*
   2* Licensed to the Apache Software Foundation (ASF) under one or more
   3* contributor license agreements.See the NOTICE file distributed with
   4* this work for additional information regarding copyright ownership.
   5* The ASF licenses this file to You under the Apache License, Version 2.0
   6* (the "License"); you may not use this file except in compliance with
   7* the License.You may obtain a copy of the License at
   8*
   9*      http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*/
17 package org.apache.commons.lang;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Locale;
24
25 import org.apache.commons.lang.text.StrBuilder;
26
27 /**
28* Operations on {@link java.lang.String} that are
29* null safe.
30*
31*
32*IsEmpty/IsBlank
33*      - checks if a String contains text
34*Trim/Strip
35*      - removes leading and trailing whitespace
36*Equals
37*      - compares two strings null-safe
38*startsWith
39*      - check if a String starts with a prefix null-safe
40*endsWith
41*      - check if a String ends with a suffix null-safe
42*IndexOf/LastIndexOf/Contains
43*      - null-safe index-of checks
44*IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut
45*      - index-of any of a set of Strings
46*ContainsOnly/ContainsNone/ContainsAny
47*      - does String contains only/none/any of these characters
48*Substring/Left/Right/Mid
49*      - null-safe substring extractions
50*SubstringBefore/SubstringAfter/SubstringBetween
51*      - substring extraction relative to other strings
52*Split/Join
53*      - splits a String into an array of substrings and vice versa
54*Remove/Delete
55*      - removes part of a String
56*Replace/Overlay
57*      - Searches a String and replaces one String with another
58*Chomp/Chop
59*      - removes the last part of a String
60*LeftPad/RightPad/Center/Repeat
61*      - pads a String
62*UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize
63*      - changes the case of a String
64*CountMatches
65*      - counts the number of occurrences of one String in another
66*IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable
67*      - checks the characters in a String
68*DefaultString
69*      - protects against a null input String
70*Reverse/ReverseDelimited
71*      - reverses a String
72*Abbreviate
73*      - abbreviates a string using ellipsis
74*Difference
75*      - compares Strings and reports on their differences
76*LevensteinDistance
77*      - the number of changes needed to change one String into another
78*
79*
80* The StringUtils class defines certain words related to
81* String handling.
82*
83*
84*null - null
85*empty - a zero-length string ("")
86*space - the space character (' ', char 32)
87*whitespace - the characters defined by {@link Character#isWhitespace(char)}
88*trim - the characters <= 32 as in {@link String#trim()}
89*
90*
91* StringUtils handles null input Strings quietly.
92* That is to say that a null input will return null.
93* Where a boolean or int is being returned
94* details vary by method.
95*
96* A side effect of the null handling is that a
97* NullPointerException should be considered a bug in
98* StringUtils (except for deprecated methods).
99*
100* Methods in this class give sample code to explain their operation.
101* The symbol * is used to indicate any input including null.
102*
103* #ThreadSafe#
104* @see java.lang.String
105* @author Apache Software Foundation
106* @author Apache Jakarta Turbine
107* @author Jon S. Stevens
108* @author Daniel L. Rall
109* @author Greg Coladonato
110* @author Ed Korthof
111* @author Rand McNeely
112* @author Fredrik Westermarck
113* @author Holger Krauth
114* @author Alexander Day Chaffee
115* @author Henning P. Schmiedehausen
116* @author Arun Mammen Thomas
117* @author Gary Gregory
118* @author Phil Steitz
119* @author Al Chou
120* @author Michael Davey
121* @author Reuben Sivan
122* @author Chris Hyzer
123* @author Scott Johnson
124* @since 1.0
125* @version $Id: StringUtils.java 1058365 2011-01-13 00:04:49Z niallp $
126*/
127 //@Immutable
128 public class StringUtils {
129   // Performance testing notes (JDK 1.4, Jul03, scolebourne)
130   // Whitespace:
131   // Character.isWhitespace() is faster than WHITESPACE.indexOf()
132   // where WHITESPACE is a string of all whitespace characters
133   //
134   // Character access:
135   // String.charAt(n) versus toCharArray(), then array
136   // String.charAt(n) is about 15% worse for a 10K string
137   // They are about equal for a length 50 string
138   // String.charAt(n) is about 4 times better for a length 3 string
139   // String.charAt(n) is best bet overall
140   //
141   // Append:
142   // String.concat about twice as fast as StringBuffer.append
143   // (not sure who tested this)
144
145   /**
146      * The empty String "".
147      * @since 2.0
148      */
149   public static final String EMPTY = "";
150
151   /**
152      * Represents a failed index search.
153      * @since 2.1
154      */
155   public static final int INDEX_NOT_FOUND = -1;
156
157   /**
158      * The maximum size to which the padding constant(s) can expand.
159      */
160   private static final int PAD_LIMIT = 8192;
161
162   /**
163      * StringUtils instances should NOT be constructed in
164      * standard programming. Instead, the class should be used as
165      * StringUtils.trim(" foo ");.
166      *
167      * This constructor is public to permit tools that require a JavaBean
168      * instance to operate.
169      */
170   public StringUtils() {
171         super();
172   }
173
174   // Empty checks
175   //-----------------------------------------------------------------------
176   /**
177      * Checks if a String is empty ("") or null.
178      *
179      *
180      * StringUtils.isEmpty(null)      = true
181      * StringUtils.isEmpty("")      = true
182      * StringUtils.isEmpty(" ")       = false
183      * StringUtils.isEmpty("bob")   = false
184      * StringUtils.isEmpty("bob") = false
185      *
186      *
187      * NOTE: This method changed in Lang version 2.0.
188      * It no longer trims the String.
189      * That functionality is available in isBlank().
190      *
191      * @param strthe String to check, may be null
192      * @return true if the String is empty or null
193      */
194   public static boolean isEmpty(String str) {
195         return str == null || str.length() == 0;
196   }
197
198   /**
199      * Checks if a String is not empty ("") and not null.
200      *
201      *
202      * StringUtils.isNotEmpty(null)      = false
203      * StringUtils.isNotEmpty("")      = false
204      * StringUtils.isNotEmpty(" ")       = true
205      * StringUtils.isNotEmpty("bob")   = true
206      * StringUtils.isNotEmpty("bob") = true
207      *
208      *
209      * @param strthe String to check, may be null
210      * @return true if the String is not empty and not null
211      */
212   public static boolean isNotEmpty(String str) {
213         return !StringUtils.isEmpty(str);
214   }
215
216   /**
217      * Checks if a String is whitespace, empty ("") or null.
218      *
219      *
220      * StringUtils.isBlank(null)      = true
221      * StringUtils.isBlank("")      = true
222      * StringUtils.isBlank(" ")       = true
223      * StringUtils.isBlank("bob")   = false
224      * StringUtils.isBlank("bob") = false
225      *
226      *
227      * @param strthe String to check, may be null
228      * @return true if the String is null, empty or whitespace
229      * @since 2.0
230      */
231   public static boolean isBlank(String str) {
232         int strLen;
233         if (str == null || (strLen = str.length()) == 0) {
234             return true;
235         }
236         for (int i = 0; i < strLen; i++) {
237             if ((Character.isWhitespace(str.charAt(i)) == false)) {
238               return false;
239             }
240         }
241         return true;
242   }
243
244   /**
245      * Checks if a String is not empty (""), not null and not whitespace only.
246      *
247      *
248      * StringUtils.isNotBlank(null)      = false
249      * StringUtils.isNotBlank("")      = false
250      * StringUtils.isNotBlank(" ")       = false
251      * StringUtils.isNotBlank("bob")   = true
252      * StringUtils.isNotBlank("bob") = true
253      *
254      *
255      * @param strthe String to check, may be null
256      * @return true if the String is
257      *not empty and not null and not whitespace
258      * @since 2.0
259      */
260   public static boolean isNotBlank(String str) {
261         return !StringUtils.isBlank(str);
262   }
263
264   // Trim
265   //-----------------------------------------------------------------------
266   /**
267      * Removes control characters (char &lt;= 32) from both
268      * ends of this String, handling null by returning
269      * an empty String ("").
270      *
271      *
272      * StringUtils.clean(null)          = ""
273      * StringUtils.clean("")            = ""
274      * StringUtils.clean("abc")         = "abc"
275      * StringUtils.clean("    abc    ") = "abc"
276      * StringUtils.clean("   ")       = ""
277      *
278      *
279      * @see java.lang.String#trim()
280      * @param strthe String to clean, may be null
281      * @return the trimmed text, never null
282      * @deprecated Use the clearer named {@link #trimToEmpty(String)}.
283      *             Method will be removed in Commons Lang 3.0.
284      */
285   public static String clean(String str) {
286         return str == null ? EMPTY : str.trim();
287   }
288
289   /**
290      * Removes control characters (char &lt;= 32) from both
291      * ends of this String, handling null by returning
292      * null.
293      *
294      * The String is trimmed using {@link String#trim()}.
295      * Trim removes start and end characters &lt;= 32.
296      * To strip whitespace use {@link #strip(String)}.
297      *
298      * To trim your choice of characters, use the
299      * {@link #strip(String, String)} methods.
300      *
301      *
302      * StringUtils.trim(null)          = null
303      * StringUtils.trim("")            = ""
304      * StringUtils.trim("   ")       = ""
305      * StringUtils.trim("abc")         = "abc"
306      * StringUtils.trim("    abc    ") = "abc"
307      *
308      *
309      * @param strthe String to be trimmed, may be null
310      * @return the trimmed string, null if null String input
311      */
312   public static String trim(String str) {
313         return str == null ? null : str.trim();
314   }
315
316   /**
317      * Removes control characters (char &lt;= 32) from both
318      * ends of this String returning null if the String is
319      * empty ("") after the trim or if it is null.
320      *
321      * The String is trimmed using {@link String#trim()}.
322      * Trim removes start and end characters &lt;= 32.
323      * To strip whitespace use {@link #stripToNull(String)}.
324      *
325      *
326      * StringUtils.trimToNull(null)          = null
327      * StringUtils.trimToNull("")            = null
328      * StringUtils.trimToNull("   ")       = null
329      * StringUtils.trimToNull("abc")         = "abc"
330      * StringUtils.trimToNull("    abc    ") = "abc"
331      *
332      *
333      * @param strthe String to be trimmed, may be null
334      * @return the trimmed String,
335      *null if only chars &lt;= 32, empty or null String input
336      * @since 2.0
337      */
338   public static String trimToNull(String str) {
339         String ts = trim(str);
340         return isEmpty(ts) ? null : ts;
341   }
342
343   /**
344      * Removes control characters (char &lt;= 32) from both
345      * ends of this String returning an empty String ("") if the String
346      * is empty ("") after the trim or if it is null.
347      *
348      * The String is trimmed using {@link String#trim()}.
349      * Trim removes start and end characters &lt;= 32.
350      * To strip whitespace use {@link #stripToEmpty(String)}.
351      *
352      *
353      * StringUtils.trimToEmpty(null)          = ""
354      * StringUtils.trimToEmpty("")            = ""
355      * StringUtils.trimToEmpty("   ")       = ""
356      * StringUtils.trimToEmpty("abc")         = "abc"
357      * StringUtils.trimToEmpty("    abc    ") = "abc"
358      *
359      *
360      * @param strthe String to be trimmed, may be null
361      * @return the trimmed String, or an empty String if null input
362      * @since 2.0
363      */
364   public static String trimToEmpty(String str) {
365         return str == null ? EMPTY : str.trim();
366   }
367
368   // Stripping
369   //-----------------------------------------------------------------------
370   /**
371      * Strips whitespace from the start and end of a String.
372      *
373      * This is similar to {@link #trim(String)} but removes whitespace.
374      * Whitespace is defined by {@link Character#isWhitespace(char)}.
375      *
376      * A null input String returns null.
377      *
378      *
379      * StringUtils.strip(null)   = null
380      * StringUtils.strip("")       = ""
381      * StringUtils.strip("   ")    = ""
382      * StringUtils.strip("abc")    = "abc"
383      * StringUtils.strip("abc")= "abc"
384      * StringUtils.strip("abc")= "abc"
385      * StringUtils.strip(" abc ")= "abc"
386      * StringUtils.strip(" ab c ") = "ab c"
387      *
388      *
389      * @param strthe String to remove whitespace from, may be null
390      * @return the stripped String, null if null String input
391      */
392   public static String strip(String str) {
393         return strip(str, null);
394   }
395
396   /**
397      * Strips whitespace from the start and end of a Stringreturning
398      * null if the String is empty ("") after the strip.
399      *
400      * This is similar to {@link #trimToNull(String)} but removes whitespace.
401      * Whitespace is defined by {@link Character#isWhitespace(char)}.
402      *
403      *
404      * StringUtils.stripToNull(null)   = null
405      * StringUtils.stripToNull("")       = null
406      * StringUtils.stripToNull("   ")    = null
407      * StringUtils.stripToNull("abc")    = "abc"
408      * StringUtils.stripToNull("abc")= "abc"
409      * StringUtils.stripToNull("abc")= "abc"
410      * StringUtils.stripToNull(" abc ")= "abc"
411      * StringUtils.stripToNull(" ab c ") = "ab c"
412      *
413      *
414      * @param strthe String to be stripped, may be null
415      * @return the stripped String,
416      *null if whitespace, empty or null String input
417      * @since 2.0
418      */
419   public static String stripToNull(String str) {
420         if (str == null) {
421             return null;
422         }
423         str = strip(str, null);
424         return str.length() == 0 ? null : str;
425   }
426
427   /**
428      * Strips whitespace from the start and end of a Stringreturning
429      * an empty String if null input.
430      *
431      * This is similar to {@link #trimToEmpty(String)} but removes whitespace.
432      * Whitespace is defined by {@link Character#isWhitespace(char)}.
433      *
434      *
435      * StringUtils.stripToEmpty(null)   = ""
436      * StringUtils.stripToEmpty("")       = ""
437      * StringUtils.stripToEmpty("   ")    = ""
438      * StringUtils.stripToEmpty("abc")    = "abc"
439      * StringUtils.stripToEmpty("abc")= "abc"
440      * StringUtils.stripToEmpty("abc")= "abc"
441      * StringUtils.stripToEmpty(" abc ")= "abc"
442      * StringUtils.stripToEmpty(" ab c ") = "ab c"
443      *
444      *
445      * @param strthe String to be stripped, may be null
446      * @return the trimmed String, or an empty String if null input
447      * @since 2.0
448      */
449   public static String stripToEmpty(String str) {
450         return str == null ? EMPTY : strip(str, null);
451   }
452
453   /**
454      * Strips any of a set of characters from the start and end of a String.
455      * This is similar to {@link String#trim()} but allows the characters
456      * to be stripped to be controlled.
457      *
458      * A null input String returns null.
459      * An empty string ("") input returns the empty string.
460      *
461      * If the stripChars String is null, whitespace is
462      * stripped as defined by {@link Character#isWhitespace(char)}.
463      * Alternatively use {@link #strip(String)}.
464      *
465      *
466      * StringUtils.strip(null, *)          = null
467      * StringUtils.strip("", *)            = ""
468      * StringUtils.strip("abc", null)      = "abc"
469      * StringUtils.strip("abc", null)    = "abc"
470      * StringUtils.strip("abc", null)    = "abc"
471      * StringUtils.strip(" abc ", null)    = "abc"
472      * StringUtils.strip("abcyx", "xyz") = "abc"
473      *
474      *
475      * @param strthe String to remove characters from, may be null
476      * @param stripCharsthe characters to remove, null treated as whitespace
477      * @return the stripped String, null if null String input
478      */
479   public static String strip(String str, String stripChars) {
480         if (isEmpty(str)) {
481             return str;
482         }
483         str = stripStart(str, stripChars);
484         return stripEnd(str, stripChars);
485   }
486
487   /**
488      * Strips any of a set of characters from the start of a String.
489      *
490      * A null input String returns null.
491      * An empty string ("") input returns the empty string.
492      *
493      * If the stripChars String is null, whitespace is
494      * stripped as defined by {@link Character#isWhitespace(char)}.
495      *
496      *
497      * StringUtils.stripStart(null, *)          = null
498      * StringUtils.stripStart("", *)            = ""
499      * StringUtils.stripStart("abc", "")      = "abc"
500      * StringUtils.stripStart("abc", null)      = "abc"
501      * StringUtils.stripStart("abc", null)    = "abc"
502      * StringUtils.stripStart("abc", null)    = "abc"
503      * StringUtils.stripStart(" abc ", null)    = "abc "
504      * StringUtils.stripStart("yxabc", "xyz") = "abc"
505      *
506      *
507      * @param strthe String to remove characters from, may be null
508      * @param stripCharsthe characters to remove, null treated as whitespace
509      * @return the stripped String, null if null String input
510      */
511   public static String stripStart(String str, String stripChars) {
512         int strLen;
513         if (str == null || (strLen = str.length()) == 0) {
514             return str;
515         }
516         int start = 0;
517         if (stripChars == null) {
518             while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {
519               start++;
520             }
521         } else if (stripChars.length() == 0) {
522             return str;
523         } else {
524             while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND)) {
525               start++;
526             }
527         }
528         return str.substring(start);
529   }
530
531   /**
532      * Strips any of a set of characters from the end of a String.
533      *
534      * A null input String returns null.
535      * An empty string ("") input returns the empty string.
536      *
537      * If the stripChars String is null, whitespace is
538      * stripped as defined by {@link Character#isWhitespace(char)}.
539      *
540      *
541      * StringUtils.stripEnd(null, *)          = null
542      * StringUtils.stripEnd("", *)            = ""
543      * StringUtils.stripEnd("abc", "")      = "abc"
544      * StringUtils.stripEnd("abc", null)      = "abc"
545      * StringUtils.stripEnd("abc", null)    = "abc"
546      * StringUtils.stripEnd("abc", null)    = "abc"
547      * StringUtils.stripEnd(" abc ", null)    = " abc"
548      * StringUtils.stripEnd("abcyx", "xyz") = "abc"
549      * StringUtils.stripEnd("120.00", ".0")   = "12"
550      *
551      *
552      * @param strthe String to remove characters from, may be null
553      * @param stripCharsthe set of characters to remove, null treated as whitespace
554      * @return the stripped String, null if null String input
555      */
556   public static String stripEnd(String str, String stripChars) {
557         int end;
558         if (str == null || (end = str.length()) == 0) {
559             return str;
560         }
561
562         if (stripChars == null) {
563             while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
564               end--;
565             }
566         } else if (stripChars.length() == 0) {
567             return str;
568         } else {
569             while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND)) {
570               end--;
571             }
572         }
573         return str.substring(0, end);
574   }
575
576   // StripAll
577   //-----------------------------------------------------------------------
578   /**
579      * Strips whitespace from the start and end of every String in an array.
580      * Whitespace is defined by {@link Character#isWhitespace(char)}.
581      *
582      * A new array is returned each time, except for length zero.
583      * A null array will return null.
584      * An empty array will return itself.
585      * A null array entry will be ignored.
586      *
587      *
588      * StringUtils.stripAll(null)             = null
589      * StringUtils.stripAll([])               = []
590      * StringUtils.stripAll(["abc", "abc"]) = ["abc", "abc"]
591      * StringUtils.stripAll(["abc", null])= ["abc", null]
592      *
593      *
594      * @param strsthe array to remove whitespace from, may be null
595      * @return the stripped Strings, null if null array input
596      */
597   public static String[] stripAll(String[] strs) {
598         return stripAll(strs, null);
599   }
600
601   /**
602      * Strips any of a set of characters from the start and end of every
603      * String in an array.
604      * Whitespace is defined by {@link Character#isWhitespace(char)}.
605      *
606      * A new array is returned each time, except for length zero.
607      * A null array will return null.
608      * An empty array will return itself.
609      * A null array entry will be ignored.
610      * A null stripChars will strip whitespace as defined by
611      * {@link Character#isWhitespace(char)}.
612      *
613      *
614      * StringUtils.stripAll(null, *)                = null
615      * StringUtils.stripAll([], *)                  = []
616      * StringUtils.stripAll(["abc", "abc"], null) = ["abc", "abc"]
617      * StringUtils.stripAll(["abc", null], null)= ["abc", null]
618      * StringUtils.stripAll(["abc", null], "yz")= ["abc", null]
619      * StringUtils.stripAll(["yabcz", null], "yz")= ["abc", null]
620      *
621      *
622      * @param strsthe array to remove characters from, may be null
623      * @param stripCharsthe characters to remove, null treated as whitespace
624      * @return the stripped Strings, null if null array input
625      */
626   public static String[] stripAll(String[] strs, String stripChars) {
627         int strsLen;
628         if (strs == null || (strsLen = strs.length) == 0) {
629             return strs;
630         }
631         String[] newArr = new String;
632         for (int i = 0; i < strsLen; i++) {
633             newArr = strip(strs, stripChars);
634         }
635         return newArr;
636   }
637
638   // Equals
639   //-----------------------------------------------------------------------
640   /**
641      * Compares two Strings, returning true if they are equal.
642      *
643      * nulls are handled without exceptions. Two null
644      * references are considered to be equal. The comparison is case sensitive.
645      *
646      *
647      * StringUtils.equals(null, null)   = true
648      * StringUtils.equals(null, "abc")= false
649      * StringUtils.equals("abc", null)= false
650      * StringUtils.equals("abc", "abc") = true
651      * StringUtils.equals("abc", "ABC") = false
652      *
653      *
654      * @see java.lang.String#equals(Object)
655      * @param str1the first String, may be null
656      * @param str2the second String, may be null
657      * @return true if the Strings are equal, case sensitive, or
658      *both null
659      */
660   public static boolean equals(String str1, String str2) {
661         return str1 == null ? str2 == null : str1.equals(str2);
662   }
663
664   /**
665      * Compares two Strings, returning true if they are equal ignoring
666      * the case.
667      *
668      * nulls are handled without exceptions. Two null
669      * references are considered equal. Comparison is case insensitive.
670      *
671      *
672      * StringUtils.equalsIgnoreCase(null, null)   = true
673      * StringUtils.equalsIgnoreCase(null, "abc")= false
674      * StringUtils.equalsIgnoreCase("abc", null)= false
675      * StringUtils.equalsIgnoreCase("abc", "abc") = true
676      * StringUtils.equalsIgnoreCase("abc", "ABC") = true
677      *
678      *
679      * @see java.lang.String#equalsIgnoreCase(String)
680      * @param str1the first String, may be null
681      * @param str2the second String, may be null
682      * @return true if the Strings are equal, case insensitive, or
683      *both null
684      */
685   public static boolean equalsIgnoreCase(String str1, String str2) {
686         return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
687   }
688
689   // IndexOf
690   //-----------------------------------------------------------------------
691   /**
692      * Finds the first index within a String, handling null.
693      * This method uses {@link String#indexOf(int)}.
694      *
695      * A null or empty ("") String will return INDEX_NOT_FOUND (-1).
696      *
697      *
698      * StringUtils.indexOf(null, *)         = -1
699      * StringUtils.indexOf("", *)         = -1
700      * StringUtils.indexOf("aabaabaa", 'a') = 0
701      * StringUtils.indexOf("aabaabaa", 'b') = 2
702      *
703      *
704      * @param strthe String to check, may be null
705      * @param searchCharthe character to find
706      * @return the first index of the search character,
707      *-1 if no match or null string input
708      * @since 2.0
709      */
710   public static int indexOf(String str, char searchChar) {
711         if (isEmpty(str)) {
712             return INDEX_NOT_FOUND;
713         }
714         return str.indexOf(searchChar);
715   }
716
717   /**
718      * Finds the first index within a String from a start position,
719      * handling null.
720      * This method uses {@link String#indexOf(int, int)}.
721      *
722      * A null or empty ("") String will return (INDEX_NOT_FOUND) -1.
723      * A negative start position is treated as zero.
724      * A start position greater than the string length returns -1.
725      *
726      *
727      * StringUtils.indexOf(null, *, *)          = -1
728      * StringUtils.indexOf("", *, *)            = -1
729      * StringUtils.indexOf("aabaabaa", 'b', 0)= 2
730      * StringUtils.indexOf("aabaabaa", 'b', 3)= 5
731      * StringUtils.indexOf("aabaabaa", 'b', 9)= -1
732      * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
733      *
734      *
735      * @param strthe String to check, may be null
736      * @param searchCharthe character to find
737      * @param startPosthe start position, negative treated as zero
738      * @return the first index of the search character,
739      *-1 if no match or null string input
740      * @since 2.0
741      */
742   public static int indexOf(String str, char searchChar, int startPos) {
743         if (isEmpty(str)) {
744             return INDEX_NOT_FOUND;
745         }
746         return str.indexOf(searchChar, startPos);
747   }
748
749   /**
750      * Finds the first index within a String, handling null.
751      * This method uses {@link String#indexOf(String)}.
752      *
753      * A null String will return -1.
754      *
755      *
756      * StringUtils.indexOf(null, *)          = -1
757      * StringUtils.indexOf(*, null)          = -1
758      * StringUtils.indexOf("", "")         = 0
759      * StringUtils.indexOf("", *)            = -1 (except when * = "")
760      * StringUtils.indexOf("aabaabaa", "a")= 0
761      * StringUtils.indexOf("aabaabaa", "b")= 2
762      * StringUtils.indexOf("aabaabaa", "ab") = 1
763      * StringUtils.indexOf("aabaabaa", "")   = 0
764      *
765      *
766      * @param strthe String to check, may be null
767      * @param searchStrthe String to find, may be null
768      * @return the first index of the search String,
769      *-1 if no match or null string input
770      * @since 2.0
771      */
772   public static int indexOf(String str, String searchStr) {
773         if (str == null || searchStr == null) {
774             return INDEX_NOT_FOUND;
775         }
776         return str.indexOf(searchStr);
777   }
778
779   /**
780      * Finds the n-th index within a String, handling null.
781      * This method uses {@link String#indexOf(String)}.
782      *
783      * A null String will return -1.
784      *
785      *
786      * StringUtils.ordinalIndexOf(null, *, *)          = -1
787      * StringUtils.ordinalIndexOf(*, null, *)          = -1
788      * StringUtils.ordinalIndexOf("", "", *)         = 0
789      * StringUtils.ordinalIndexOf("aabaabaa", "a", 1)= 0
790      * StringUtils.ordinalIndexOf("aabaabaa", "a", 2)= 1
791      * StringUtils.ordinalIndexOf("aabaabaa", "b", 1)= 2
792      * StringUtils.ordinalIndexOf("aabaabaa", "b", 2)= 5
793      * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
794      * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
795      * StringUtils.ordinalIndexOf("aabaabaa", "", 1)   = 0
796      * StringUtils.ordinalIndexOf("aabaabaa", "", 2)   = 0
797      *
798      *
799      * Note that 'head(String str, int n)' may be implemented as:
800      *
801      *
802      *   str.substring(0, lastOrdinalIndexOf(str, "\n", n))
803      *
804      *
805      * @param strthe String to check, may be null
806      * @param searchStrthe String to find, may be null
807      * @param ordinalthe n-th searchStr to find
808      * @return the n-th index of the search String,
809      *-1 (INDEX_NOT_FOUND) if no match or null string input
810      * @since 2.1
811      */
812   public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
813         return ordinalIndexOf(str, searchStr, ordinal, false);
814   }
815
816   /**
817      * Finds the n-th index within a String, handling null.
818      * This method uses {@link String#indexOf(String)}.
819      *
820      * A null String will return -1.
821      *
822      * @param strthe String to check, may be null
823      * @param searchStrthe String to find, may be null
824      * @param ordinalthe n-th searchStr to find
825      * @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf()
826      * @return the n-th index of the search String,
827      *-1 (INDEX_NOT_FOUND) if no match or null string input
828      */
829   // Shared code between ordinalIndexOf(String,String,int) and lastOrdinalIndexOf(String,String,int)
830   private static int ordinalIndexOf(String str, String searchStr, int ordinal, boolean lastIndex) {
831         if (str == null || searchStr == null || ordinalstr.length for "", hence
890         if (searchStr.length() == 0 && startPos >= str.length()) {
891             return str.length();
892         }
893         return str.indexOf(searchStr, startPos);
894   }
895
896   /**
897      * Case in-sensitive find of the first index within a String.
898      *
899      * A null String will return -1.
900      * A negative start position is treated as zero.
901      * An empty ("") search String always matches.
902      * A start position greater than the string length only matches
903      * an empty search String.
904      *
905      *
906      * StringUtils.indexOfIgnoreCase(null, *)          = -1
907      * StringUtils.indexOfIgnoreCase(*, null)          = -1
908      * StringUtils.indexOfIgnoreCase("", "")         = 0
909      * StringUtils.indexOfIgnoreCase("aabaabaa", "a")= 0
910      * StringUtils.indexOfIgnoreCase("aabaabaa", "b")= 2
911      * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1
912      *
913      *
914      * @param strthe String to check, may be null
915      * @param searchStrthe String to find, may be null
916      * @return the first index of the search String,
917      *-1 if no match or null string input
918      * @since 2.5
919      */
920   public static int indexOfIgnoreCase(String str, String searchStr) {
921         return indexOfIgnoreCase(str, searchStr, 0);
922   }
923
924   /**
925      * Case in-sensitive find of the first index within a String
926      * from the specified position.
927      *
928      * A null String will return -1.
929      * A negative start position is treated as zero.
930      * An empty ("") search String always matches.
931      * A start position greater than the string length only matches
932      * an empty search String.
933      *
934      *
935      * StringUtils.indexOfIgnoreCase(null, *, *)          = -1
936      * StringUtils.indexOfIgnoreCase(*, null, *)          = -1
937      * StringUtils.indexOfIgnoreCase("", "", 0)         = 0
938      * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0)= 0
939      * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0)= 2
940      * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
941      * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3)= 5
942      * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9)= -1
943      * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
944      * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
945      * StringUtils.indexOfIgnoreCase("abc", "", 9)      = 3
946      *
947      *
948      * @param strthe String to check, may be null
949      * @param searchStrthe String to find, may be null
950      * @param startPosthe start position, negative treated as zero
951      * @return the first index of the search String,
952      *-1 if no match or null string input
953      * @since 2.5
954      */
955   public static int indexOfIgnoreCase(String str, String searchStr, int startPos) {
956         if (str == null || searchStr == null) {
957             return INDEX_NOT_FOUND;
958         }
959         if (startPos < 0) {
960             startPos = 0;
961         }
962         int endLimit = (str.length() - searchStr.length()) + 1;
963         if (startPos > endLimit) {
964             return INDEX_NOT_FOUND;
965         }
966         if (searchStr.length() == 0) {
967             return startPos;
968         }
969         for (int i = startPos; i < endLimit; i++) {
970             if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) {
971               return i;
972             }
973         }
974         return INDEX_NOT_FOUND;
975   }
976
977   // LastIndexOf
978   //-----------------------------------------------------------------------
979   /**
980      * Finds the last index within a String, handling null.
981      * This method uses {@link String#lastIndexOf(int)}.
982      *
983      * A null or empty ("") String will return -1.
984      *
985      *
986      * StringUtils.lastIndexOf(null, *)         = -1
987      * StringUtils.lastIndexOf("", *)         = -1
988      * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
989      * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
990      *
991      *
992      * @param strthe String to check, may be null
993      * @param searchCharthe character to find
994      * @return the last index of the search character,
995      *-1 if no match or null string input
996      * @since 2.0
997      */
998   public static int lastIndexOf(String str, char searchChar) {
999         if (isEmpty(str)) {
1000             return INDEX_NOT_FOUND;
1001         }
1002         return str.lastIndexOf(searchChar);
1003   }
1004
1005   /**
1006      * Finds the last index within a String from a start position,
1007      * handling null.
1008      * This method uses {@link String#lastIndexOf(int, int)}.
1009      *
1010      * A null or empty ("") String will return -1.
1011      * A negative start position returns -1.
1012      * A start position greater than the string length searches the whole string.
1013      *
1014      *
1015      * StringUtils.lastIndexOf(null, *, *)          = -1
1016      * StringUtils.lastIndexOf("", *,*)         = -1
1017      * StringUtils.lastIndexOf("aabaabaa", 'b', 8)= 5
1018      * StringUtils.lastIndexOf("aabaabaa", 'b', 4)= 2
1019      * StringUtils.lastIndexOf("aabaabaa", 'b', 0)= -1
1020      * StringUtils.lastIndexOf("aabaabaa", 'b', 9)= 5
1021      * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
1022      * StringUtils.lastIndexOf("aabaabaa", 'a', 0)= 0
1023      *
1024      *
1025      * @param strthe String to check, may be null
1026      * @param searchCharthe character to find
1027      * @param startPosthe start position
1028      * @return the last index of the search character,
1029      *-1 if no match or null string input
1030      * @since 2.0
1031      */
1032   public static int lastIndexOf(String str, char searchChar, int startPos) {
1033         if (isEmpty(str)) {
1034             return INDEX_NOT_FOUND;
1035         }
1036         return str.lastIndexOf(searchChar, startPos);
1037   }
1038
1039   /**
1040      * Finds the last index within a String, handling null.
1041      * This method uses {@link String#lastIndexOf(String)}.
1042      *
1043      * A null String will return -1.
1044      *
1045      *
1046      * StringUtils.lastIndexOf(null, *)          = -1
1047      * StringUtils.lastIndexOf(*, null)          = -1
1048      * StringUtils.lastIndexOf("", "")         = 0
1049      * StringUtils.lastIndexOf("aabaabaa", "a")= 7
1050      * StringUtils.lastIndexOf("aabaabaa", "b")= 5
1051      * StringUtils.lastIndexOf("aabaabaa", "ab") = 4
1052      * StringUtils.lastIndexOf("aabaabaa", "")   = 8
1053      *
1054      *
1055      * @param strthe String to check, may be null
1056      * @param searchStrthe String to find, may be null
1057      * @return the last index of the search String,
1058      *-1 if no match or null string input
1059      * @since 2.0
1060      */
1061   public static int lastIndexOf(String str, String searchStr) {
1062         if (str == null || searchStr == null) {
1063             return INDEX_NOT_FOUND;
1064         }
1065         return str.lastIndexOf(searchStr);
1066   }
1067
1068   /**
1069      * Finds the n-th last index within a String, handling null.
1070      * This method uses {@link String#lastIndexOf(String)}.
1071      *
1072      * A null String will return -1.
1073      *
1074      *
1075      * StringUtils.lastOrdinalIndexOf(null, *, *)          = -1
1076      * StringUtils.lastOrdinalIndexOf(*, null, *)          = -1
1077      * StringUtils.lastOrdinalIndexOf("", "", *)         = 0
1078      * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1)= 7
1079      * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2)= 6
1080      * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1)= 5
1081      * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2)= 2
1082      * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4
1083      * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1
1084      * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1)   = 8
1085      * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2)   = 8
1086      *
1087      *
1088      * Note that 'tail(String str, int n)' may be implemented as:
1089      *
1090      *
1091      *   str.substring(lastOrdinalIndexOf(str, "\n", n) + 1)
1092      *
1093      *
1094      * @param strthe String to check, may be null
1095      * @param searchStrthe String to find, may be null
1096      * @param ordinalthe n-th last searchStr to find
1097      * @return the n-th last index of the search String,
1098      *-1 (INDEX_NOT_FOUND) if no match or null string input
1099      * @since 2.5
1100      */
1101   public static int lastOrdinalIndexOf(String str, String searchStr, int ordinal) {
1102         return ordinalIndexOf(str, searchStr, ordinal, true);
1103   }
1104
1105   /**
1106      * Finds the first index within a String, handling null.
1107      * This method uses {@link String#lastIndexOf(String, int)}.
1108      *
1109      * A null String will return -1.
1110      * A negative start position returns -1.
1111      * An empty ("") search String always matches unless the start position is negative.
1112      * A start position greater than the string length searches the whole string.
1113      *
1114      *
1115      * StringUtils.lastIndexOf(null, *, *)          = -1
1116      * StringUtils.lastIndexOf(*, null, *)          = -1
1117      * StringUtils.lastIndexOf("aabaabaa", "a", 8)= 7
1118      * StringUtils.lastIndexOf("aabaabaa", "b", 8)= 5
1119      * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
1120      * StringUtils.lastIndexOf("aabaabaa", "b", 9)= 5
1121      * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
1122      * StringUtils.lastIndexOf("aabaabaa", "a", 0)= 0
1123      * StringUtils.lastIndexOf("aabaabaa", "b", 0)= -1
1124      *
1125      *
1126      * @param strthe String to check, may be null
1127      * @param searchStrthe String to find, may be null
1128      * @param startPosthe start position, negative treated as zero
1129      * @return the first index of the search String,
1130      *-1 if no match or null string input
1131      * @since 2.0
1132      */
1133   public static int lastIndexOf(String str, String searchStr, int startPos) {
1134         if (str == null || searchStr == null) {
1135             return INDEX_NOT_FOUND;
1136         }
1137         return str.lastIndexOf(searchStr, startPos);
1138   }
1139
1140   /**
1141      * Case in-sensitive find of the last index within a String.
1142      *
1143      * A null String will return -1.
1144      * A negative start position returns -1.
1145      * An empty ("") search String always matches unless the start position is negative.
1146      * A start position greater than the string length searches the whole string.
1147      *
1148      *
1149      * StringUtils.lastIndexOfIgnoreCase(null, *)          = -1
1150      * StringUtils.lastIndexOfIgnoreCase(*, null)          = -1
1151      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A")= 7
1152      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B")= 5
1153      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4
1154      *
1155      *
1156      * @param strthe String to check, may be null
1157      * @param searchStrthe String to find, may be null
1158      * @return the first index of the search String,
1159      *-1 if no match or null string input
1160      * @since 2.5
1161      */
1162   public static int lastIndexOfIgnoreCase(String str, String searchStr) {
1163         if (str == null || searchStr == null) {
1164             return INDEX_NOT_FOUND;
1165         }
1166         return lastIndexOfIgnoreCase(str, searchStr, str.length());
1167   }
1168
1169   /**
1170      * Case in-sensitive find of the last index within a String
1171      * from the specified position.
1172      *
1173      * A null String will return -1.
1174      * A negative start position returns -1.
1175      * An empty ("") search String always matches unless the start position is negative.
1176      * A start position greater than the string length searches the whole string.
1177      *
1178      *
1179      * StringUtils.lastIndexOfIgnoreCase(null, *, *)          = -1
1180      * StringUtils.lastIndexOfIgnoreCase(*, null, *)          = -1
1181      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8)= 7
1182      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8)= 5
1183      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
1184      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9)= 5
1185      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
1186      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0)= 0
1187      * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0)= -1
1188      *
1189      *
1190      * @param strthe String to check, may be null
1191      * @param searchStrthe String to find, may be null
1192      * @param startPosthe start position
1193      * @return the first index of the search String,
1194      *-1 if no match or null string input
1195      * @since 2.5
1196      */
1197   public static int lastIndexOfIgnoreCase(String str, String searchStr, int startPos) {
1198         if (str == null || searchStr == null) {
1199             return INDEX_NOT_FOUND;
1200         }
1201         if (startPos > (str.length() - searchStr.length())) {
1202             startPos = str.length() - searchStr.length();
1203         }
1204         if (startPos < 0) {
1205             return INDEX_NOT_FOUND;
1206         }
1207         if (searchStr.length() == 0) {
1208             return startPos;
1209         }
1210
1211         for (int i = startPos; i >= 0; i--) {
1212             if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) {
1213               return i;
1214             }
1215         }
1216         return INDEX_NOT_FOUND;
1217   }
1218
1219   // Contains
1220   //-----------------------------------------------------------------------
1221   /**
1222      * Checks if String contains a search character, handling null.
1223      * This method uses {@link String#indexOf(int)}.
1224      *
1225      * A null or empty ("") String will return false.
1226      *
1227      *
1228      * StringUtils.contains(null, *)    = false
1229      * StringUtils.contains("", *)      = false
1230      * StringUtils.contains("abc", 'a') = true
1231      * StringUtils.contains("abc", 'z') = false
1232      *
1233      *
1234      * @param strthe String to check, may be null
1235      * @param searchCharthe character to find
1236      * @return true if the String contains the search character,
1237      *false if not or null string input
1238      * @since 2.0
1239      */
1240   public static boolean contains(String str, char searchChar) {
1241         if (isEmpty(str)) {
1242             return false;
1243         }
1244         return str.indexOf(searchChar) >= 0;
1245   }
1246
1247   /**
1248      * Checks if String contains a search String, handling null.
1249      * This method uses {@link String#indexOf(String)}.
1250      *
1251      * A null String will return false.
1252      *
1253      *
1254      * StringUtils.contains(null, *)   = false
1255      * StringUtils.contains(*, null)   = false
1256      * StringUtils.contains("", "")      = true
1257      * StringUtils.contains("abc", "")   = true
1258      * StringUtils.contains("abc", "a")= true
1259      * StringUtils.contains("abc", "z")= false
1260      *
1261      *
1262      * @param strthe String to check, may be null
1263      * @param searchStrthe String to find, may be null
1264      * @return true if the String contains the search String,
1265      *false if not or null string input
1266      * @since 2.0
1267      */
1268   public static boolean contains(String str, String searchStr) {
1269         if (str == null || searchStr == null) {
1270             return false;
1271         }
1272         return str.indexOf(searchStr) >= 0;
1273   }
1274
1275   /**
1276      * Checks if String contains a search String irrespective of case,
1277      * handling null. Case-insensitivity is defined as by
1278      * {@link String#equalsIgnoreCase(String)}.
1279      *
1280      * A null String will return false.
1281      *
1282      *
1283      * StringUtils.contains(null, *) = false
1284      * StringUtils.contains(*, null) = false
1285      * StringUtils.contains("", "") = true
1286      * StringUtils.contains("abc", "") = true
1287      * StringUtils.contains("abc", "a") = true
1288      * StringUtils.contains("abc", "z") = false
1289      * StringUtils.contains("abc", "A") = true
1290      * StringUtils.contains("abc", "Z") = false
1291      *
1292      *
1293      * @param strthe String to check, may be null
1294      * @param searchStrthe String to find, may be null
1295      * @return true if the String contains the search String irrespective of
1296      * case or false if not or null string input
1297      */
1298   public static boolean containsIgnoreCase(String str, String searchStr) {
1299         if (str == null || searchStr == null) {
1300             return false;
1301         }
1302         int len = searchStr.length();
1303         int max = str.length() - len;
1304         for (int i = 0; i = 0;
1561             if (i + 1 < strLen && CharUtils.isHighSurrogate(ch)) {
1562               char ch2 = str.charAt(i + 1);
1563               if (chFound && searchChars.indexOf(ch2) < 0) {
1564                     return i;
1565               }
1566             } else {
1567               if (!chFound) {
1568                     return i;
1569               }
1570             }
1571         }
1572         return INDEX_NOT_FOUND;
1573   }
1574
1575   // ContainsOnly
1576   //-----------------------------------------------------------------------
1577   /**
1578      * Checks if the String contains only certain characters.
1579      *
1580      * A null String will return false.
1581      * A null valid character array will return false.
1582      * An empty String (length()=0) always returns true.
1583      *
1584      *
1585      * StringUtils.containsOnly(null, *)       = false
1586      * StringUtils.containsOnly(*, null)       = false
1587      * StringUtils.containsOnly("", *)         = true
1588      * StringUtils.containsOnly("ab", '')      = false
1589      * StringUtils.containsOnly("abab", 'abc') = true
1590      * StringUtils.containsOnly("ab1", 'abc')= false
1591      * StringUtils.containsOnly("abz", 'abc')= false
1592      *
1593      *
1594      * @param strthe String to check, may be null
1595      * @param validan array of valid chars, may be null
1596      * @return true if it only contains valid chars and is non-null
1597      */
1598   public static boolean containsOnly(String str, char[] valid) {
1599         // All these pre-checks are to maintain API with an older version
1600         if ((valid == null) || (str == null)) {
1601             return false;
1602         }
1603         if (str.length() == 0) {
1604             return true;
1605         }
1606         if (valid.length == 0) {
1607             return false;
1608         }
1609         return indexOfAnyBut(str, valid) == INDEX_NOT_FOUND;
1610   }
1611
1612   /**
1613      * Checks if the String contains only certain characters.
1614      *
1615      * A null String will return false.
1616      * A null valid character String will return false.
1617      * An empty String (length()=0) always returns true.
1618      *
1619      *
1620      * StringUtils.containsOnly(null, *)       = false
1621      * StringUtils.containsOnly(*, null)       = false
1622      * StringUtils.containsOnly("", *)         = true
1623      * StringUtils.containsOnly("ab", "")      = false
1624      * StringUtils.containsOnly("abab", "abc") = true
1625      * StringUtils.containsOnly("ab1", "abc")= false
1626      * StringUtils.containsOnly("abz", "abc")= false
1627      *
1628      *
1629      * @param strthe String to check, may be null
1630      * @param validCharsa String of valid chars, may be null
1631      * @return true if it only contains valid chars and is non-null
1632      * @since 2.0
1633      */
1634   public static boolean containsOnly(String str, String validChars) {
1635         if (str == null || validChars == null) {
1636             return false;
1637         }
1638         return containsOnly(str, validChars.toCharArray());
1639   }
1640
1641   // ContainsNone
1642   //-----------------------------------------------------------------------
1643   /**
1644      * Checks that the String does not contain certain characters.
1645      *
1646      * A null String will return true.
1647      * A null invalid character array will return true.
1648      * An empty String (length()=0) always returns true.
1649      *
1650      *
1651      * StringUtils.containsNone(null, *)       = true
1652      * StringUtils.containsNone(*, null)       = true
1653      * StringUtils.containsNone("", *)         = true
1654      * StringUtils.containsNone("ab", '')      = true
1655      * StringUtils.containsNone("abab", 'xyz') = true
1656      * StringUtils.containsNone("ab1", 'xyz')= true
1657      * StringUtils.containsNone("abz", 'xyz')= false
1658      *
1659      *
1660      * @param strthe String to check, may be null
1661      * @param searchCharsan array of invalid chars, may be null
1662      * @return true if it contains none of the invalid chars, or is null
1663      * @since 2.0
1664      */
1665   public static boolean containsNone(String str, char[] searchChars) {
1666         if (str == null || searchChars == null) {
1667             return true;
1668         }
1669         int csLen = str.length();
1670         int csLast = csLen - 1;
1671         int searchLen = searchChars.length;
1672         int searchLast = searchLen - 1;
1673         for (int i = 0; i < csLen; i++) {
1674             char ch = str.charAt(i);
1675             for (int j = 0; j < searchLen; j++) {
1676               if (searchChars == ch) {
1677                     if (CharUtils.isHighSurrogate(ch)) {
1678                         if (j == searchLast) {
1679                           // missing low surrogate, fine, like String.indexOf(String)
1680                           return false;
1681                         }
1682                         if (i < csLast && searchChars == str.charAt(i + 1)) {
1683                           return false;
1684                         }
1685                     } else {
1686                         // ch is in the Basic Multilingual Plane
1687                         return false;
1688                     }
1689               }
1690             }
1691         }
1692         return true;
1693   }
1694
1695   /**
1696      * Checks that the String does not contain certain characters.
1697      *
1698      * A null String will return true.
1699      * A null invalid character array will return true.
1700      * An empty String ("") always returns true.
1701      *
1702      *
1703      * StringUtils.containsNone(null, *)       = true
1704      * StringUtils.containsNone(*, null)       = true
1705      * StringUtils.containsNone("", *)         = true
1706      * StringUtils.containsNone("ab", "")      = true
1707      * StringUtils.containsNone("abab", "xyz") = true
1708      * StringUtils.containsNone("ab1", "xyz")= true
1709      * StringUtils.containsNone("abz", "xyz")= false
1710      *
1711      *
1712      * @param strthe String to check, may be null
1713      * @param invalidCharsa String of invalid chars, may be null
1714      * @return true if it contains none of the invalid chars, or is null
1715      * @since 2.0
1716      */
1717   public static boolean containsNone(String str, String invalidChars) {
1718         if (str == null || invalidChars == null) {
1719             return true;
1720         }
1721         return containsNone(str, invalidChars.toCharArray());
1722   }
1723
1724   // IndexOfAny strings
1725   //-----------------------------------------------------------------------
1726   /**
1727      * Find the first index of any of a set of potential substrings.
1728      *
1729      * A null String will return -1.
1730      * A null or zero length search array will return -1.
1731      * A null search array entry will be ignored, but a search
1732      * array containing "" will return 0 if str is not
1733      * null. This method uses {@link String#indexOf(String)}.
1734      *
1735      *
1736      * StringUtils.indexOfAny(null, *)                     = -1
1737      * StringUtils.indexOfAny(*, null)                     = -1
1738      * StringUtils.indexOfAny(*, [])                     = -1
1739      * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
1740      * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
1741      * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
1742      * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
1743      * StringUtils.indexOfAny("zzabyycdxx", [""])          = 0
1744      * StringUtils.indexOfAny("", [""])                  = 0
1745      * StringUtils.indexOfAny("", ["a"])                   = -1
1746      *
1747      *
1748      * @param strthe String to check, may be null
1749      * @param searchStrsthe Strings to search for, may be null
1750      * @return the first index of any of the searchStrs in str, -1 if no match
1751      */
1752   public static int indexOfAny(String str, String[] searchStrs) {
1753         if ((str == null) || (searchStrs == null)) {
1754             return INDEX_NOT_FOUND;
1755         }
1756         int sz = searchStrs.length;
1757
1758         // String's can't have a MAX_VALUEth index.
1759         int ret = Integer.MAX_VALUE;
1760
1761         int tmp = 0;
1762         for (int i = 0; i < sz; i++) {
1763             String search = searchStrs;
1764             if (search == null) {
1765               continue;
1766             }
1767             tmp = str.indexOf(search);
1768             if (tmp == INDEX_NOT_FOUND) {
1769               continue;
1770             }
1771
1772             if (tmp < ret) {
1773               ret = tmp;
1774             }
1775         }
1776
1777         return (ret == Integer.MAX_VALUE) ? INDEX_NOT_FOUND : ret;
1778   }
1779
1780   /**
1781      * Find the latest index of any of a set of potential substrings.
1782      *
1783      * A null String will return -1.
1784      * A null search array will return -1.
1785      * A null or zero length search array entry will be ignored,
1786      * but a search array containing "" will return the length of str
1787      * if str is not null. This method uses {@link String#indexOf(String)}
1788      *
1789      *
1790      * StringUtils.lastIndexOfAny(null, *)                   = -1
1791      * StringUtils.lastIndexOfAny(*, null)                   = -1
1792      * StringUtils.lastIndexOfAny(*, [])                     = -1
1793      * StringUtils.lastIndexOfAny(*, )               = -1
1794      * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
1795      * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
1796      * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1797      * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1798      * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
1799      *
1800      *
1801      * @param strthe String to check, may be null
1802      * @param searchStrsthe Strings to search for, may be null
1803      * @return the last index of any of the Strings, -1 if no match
1804      */
1805   public static int lastIndexOfAny(String str, String[] searchStrs) {
1806         if ((str == null) || (searchStrs == null)) {
1807             return INDEX_NOT_FOUND;
1808         }
1809         int sz = searchStrs.length;
1810         int ret = INDEX_NOT_FOUND;
1811         int tmp = 0;
1812         for (int i = 0; i < sz; i++) {
1813             String search = searchStrs;
1814             if (search == null) {
1815               continue;
1816             }
1817             tmp = str.lastIndexOf(search);
1818             if (tmp > ret) {
1819               ret = tmp;
1820             }
1821         }
1822         return ret;
1823   }
1824
1825   // Substring
1826   //-----------------------------------------------------------------------
1827   /**
1828      * Gets a substring from the specified String avoiding exceptions.
1829      *
1830      * A negative start position can be used to start n
1831      * characters from the end of the String.
1832      *
1833      * A null String will return null.
1834      * An empty ("") String will return "".
1835      *
1836      *
1837      * StringUtils.substring(null, *)   = null
1838      * StringUtils.substring("", *)   = ""
1839      * StringUtils.substring("abc", 0)= "abc"
1840      * StringUtils.substring("abc", 2)= "c"
1841      * StringUtils.substring("abc", 4)= ""
1842      * StringUtils.substring("abc", -2) = "bc"
1843      * StringUtils.substring("abc", -4) = "abc"
1844      *
1845      *
1846      * @param strthe String to get the substring from, may be null
1847      * @param startthe position to start from, negative means
1848      *count back from the end of the String by this many characters
1849      * @return substring from start position, null if null String input
1850      */
1851   public static String substring(String str, int start) {
1852         if (str == null) {
1853             return null;
1854         }
1855
1856         // handle negatives, which means last n characters
1857         if (start < 0) {
1858             start = str.length() + start; // remember start is negative
1859         }
1860
1861         if (start < 0) {
1862             start = 0;
1863         }
1864         if (start > str.length()) {
1865             return EMPTY;
1866         }
1867
1868         return str.substring(start);
1869   }
1870
1871   /**
1872      * Gets a substring from the specified String avoiding exceptions.
1873      *
1874      * A negative start position can be used to start/end n
1875      * characters from the end of the String.
1876      *
1877      * The returned substring starts with the character in the start
1878      * position and ends before the end position. All position counting is
1879      * zero-based -- i.e., to start at the beginning of the string use
1880      * start = 0. Negative start and end positions can be used to
1881      * specify offsets relative to the end of the String.
1882      *
1883      * If start is not strictly to the left of end, ""
1884      * is returned.
1885      *
1886      *
1887      * StringUtils.substring(null, *, *)    = null
1888      * StringUtils.substring("", * ,*)    = "";
1889      * StringUtils.substring("abc", 0, 2)   = "ab"
1890      * StringUtils.substring("abc", 2, 0)   = ""
1891      * StringUtils.substring("abc", 2, 4)   = "c"
1892      * StringUtils.substring("abc", 4, 6)   = ""
1893      * StringUtils.substring("abc", 2, 2)   = ""
1894      * StringUtils.substring("abc", -2, -1) = "b"
1895      * StringUtils.substring("abc", -4, 2)= "ab"
1896      *
1897      *
1898      * @param strthe String to get the substring from, may be null
1899      * @param startthe position to start from, negative means
1900      *count back from the end of the String by this many characters
1901      * @param endthe position to end at (exclusive), negative means
1902      *count back from the end of the String by this many characters
1903      * @return substring from start position to end positon,
1904      *null if null String input
1905      */
1906   public static String substring(String str, int start, int end) {
1907         if (str == null) {
1908             return null;
1909         }
1910
1911         // handle negatives
1912         if (end < 0) {
1913             end = str.length() + end; // remember end is negative
1914         }
1915         if (start < 0) {
1916             start = str.length() + start; // remember start is negative
1917         }
1918
1919         // check length next
1920         if (end > str.length()) {
1921             end = str.length();
1922         }
1923
1924         // if start is greater than end, return ""
1925         if (start > end) {
1926             return EMPTY;
1927         }
1928
1929         if (start < 0) {
1930             start = 0;
1931         }
1932         if (end < 0) {
1933             end = 0;
1934         }
1935
1936         return str.substring(start, end);
1937   }
1938
1939   // Left/Right/Mid
1940   //-----------------------------------------------------------------------
1941   /**
1942      * Gets the leftmost len characters of a String.
1943      *
1944      * If len characters are not available, or the
1945      * String is null, the String will be returned without
1946      * an exception. An empty String is returned if len is negative.
1947      *
1948      *
1949      * StringUtils.left(null, *)    = null
1950      * StringUtils.left(*, -ve)   = ""
1951      * StringUtils.left("", *)      = ""
1952      * StringUtils.left("abc", 0)   = ""
1953      * StringUtils.left("abc", 2)   = "ab"
1954      * StringUtils.left("abc", 4)   = "abc"
1955      *
1956      *
1957      * @param strthe String to get the leftmost characters from, may be null
1958      * @param lenthe length of the required String
1959      * @return the leftmost characters, null if null String input
1960      */
1961   public static String left(String str, int len) {
1962         if (str == null) {
1963             return null;
1964         }
1965         if (len < 0) {
1966             return EMPTY;
1967         }
1968         if (str.length()beg) {
2675                     numberOfSubstrings += 1;
2676
2677                     if (numberOfSubstrings == max) {
2678                         end = len;
2679                         substrings.add(str.substring(beg));
2680                     } else {
2681                         // The following is OK, because String.substring( beg, end ) excludes
2682                         // the character at the position 'end'.
2683                         substrings.add(str.substring(beg, end));
2684
2685                         // Set the starting point for the next search.
2686                         // The following is equivalent to beg = end + (separatorLength - 1) + 1,
2687                         // which is the right calculation:
2688                         beg = end + separatorLength;
2689                     }
2690               } else {
2691                     // We found a consecutive occurrence of the separator, so skip it.
2692                     if (preserveAllTokens) {
2693                         numberOfSubstrings += 1;
2694                         if (numberOfSubstrings == max) {
2695                           end = len;
2696                           substrings.add(str.substring(beg));
2697                         } else {
2698                           substrings.add(EMPTY);
2699                         }
2700                     }
2701                     beg = end + separatorLength;
2702               }
2703             } else {
2704               // String.substring( beg ) goes from 'beg' to the end of the String.
2705               substrings.add(str.substring(beg));
2706               end = len;
2707             }
2708         }
2709
2710         return (String[]) substrings.toArray(new String);
2711   }
2712
2713   // -----------------------------------------------------------------------
2714   /**
2715      * Splits the provided text into an array, using whitespace as the
2716      * separator, preserving all tokens, including empty tokens created by
2717      * adjacent separators. This is an alternative to using StringTokenizer.
2718      * Whitespace is defined by {@link Character#isWhitespace(char)}.
2719      *
2720      * The separator is not included in the returned String array.
2721      * Adjacent separators are treated as separators for empty tokens.
2722      * For more control over the split use the StrTokenizer class.
2723      *
2724      * A null input String returns null.
2725      *
2726      *
2727      * StringUtils.splitPreserveAllTokens(null)       = null
2728      * StringUtils.splitPreserveAllTokens("")         = []
2729      * StringUtils.splitPreserveAllTokens("abc def")= ["abc", "def"]
2730      * StringUtils.splitPreserveAllTokens("abcdef") = ["abc", "", "def"]
2731      * StringUtils.splitPreserveAllTokens(" abc ")    = ["", "abc", ""]
2732      *
2733      *
2734      * @param strthe String to parse, may be null
2735      * @return an array of parsed Strings, null if null String input
2736      * @since 2.1
2737      */
2738   public static String[] splitPreserveAllTokens(String str) {
2739         return splitWorker(str, null, -1, true);
2740   }
2741
2742   /**
2743      * Splits the provided text into an array, separator specified,
2744      * preserving all tokens, including empty tokens created by adjacent
2745      * separators. This is an alternative to using StringTokenizer.
2746      *
2747      * The separator is not included in the returned String array.
2748      * Adjacent separators are treated as separators for empty tokens.
2749      * For more control over the split use the StrTokenizer class.
2750      *
2751      * A null input String returns null.
2752      *
2753      *
2754      * StringUtils.splitPreserveAllTokens(null, *)         = null
2755      * StringUtils.splitPreserveAllTokens("", *)         = []
2756      * StringUtils.splitPreserveAllTokens("a.b.c", '.')    = ["a", "b", "c"]
2757      * StringUtils.splitPreserveAllTokens("a..b.c", '.')   = ["a", "", "b", "c"]
2758      * StringUtils.splitPreserveAllTokens("a:b:c", '.')    = ["a:b:c"]
2759      * StringUtils.splitPreserveAllTokens("a\tb\nc", null) = ["a", "b", "c"]
2760      * StringUtils.splitPreserveAllTokens("a b c", ' ')    = ["a", "b", "c"]
2761      * StringUtils.splitPreserveAllTokens("a b c ", ' ')   = ["a", "b", "c", ""]
2762      * StringUtils.splitPreserveAllTokens("a b c", ' ')   = ["a", "b", "c", "", ""]
2763      * StringUtils.splitPreserveAllTokens(" a b c", ' ')   = ["", a", "b", "c"]
2764      * StringUtils.splitPreserveAllTokens("a b c", ' ')= ["", "", a", "b", "c"]
2765      * StringUtils.splitPreserveAllTokens(" a b c ", ' ')= ["", a", "b", "c", ""]
2766      *
2767      *
2768      * @param strthe String to parse, may be null
2769      * @param separatorCharthe character used as the delimiter,
2770      *null splits on whitespace
2771      * @return an array of parsed Strings, null if null String input
2772      * @since 2.1
2773      */
2774   public static String[] splitPreserveAllTokens(String str, char separatorChar) {
2775         return splitWorker(str, separatorChar, true);
2776   }
2777
2778   /**
2779      * Performs the logic for the split and
2780      * splitPreserveAllTokens methods that do not return a
2781      * maximum array length.
2782      *
2783      * @param strthe String to parse, may be null
2784      * @param separatorChar the separate character
2785      * @param preserveAllTokens if true, adjacent separators are
2786      * treated as empty token separators; if false, adjacent
2787      * separators are treated as one separator.
2788      * @return an array of parsed Strings, null if null String input
2789      */
2790   private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
2791         // Performance tuned for 2.0 (JDK1.4)
2792
2793         if (str == null) {
2794             return null;
2795         }
2796         int len = str.length();
2797         if (len == 0) {
2798             return ArrayUtils.EMPTY_STRING_ARRAY;
2799         }
2800         List list = new ArrayList();
2801         int i = 0, start = 0;
2802         boolean match = false;
2803         boolean lastMatch = false;
2804         while (i < len) {
2805             if (str.charAt(i) == separatorChar) {
2806               if (match || preserveAllTokens) {
2807                     list.add(str.substring(start, i));
2808                     match = false;
2809                     lastMatch = true;
2810               }
2811               start = ++i;
2812               continue;
2813             }
2814             lastMatch = false;
2815             match = true;
2816             i++;
2817         }
2818         if (match || (preserveAllTokens && lastMatch)) {
2819             list.add(str.substring(start, i));
2820         }
2821         return (String[]) list.toArray(new String);
2822   }
2823
2824   /**
2825      * Splits the provided text into an array, separators specified,
2826      * preserving all tokens, including empty tokens created by adjacent
2827      * separators. This is an alternative to using StringTokenizer.
2828      *
2829      * The separator is not included in the returned String array.
2830      * Adjacent separators are treated as separators for empty tokens.
2831      * For more control over the split use the StrTokenizer class.
2832      *
2833      * A null input String returns null.
2834      * A null separatorChars splits on whitespace.
2835      *
2836      *
2837      * StringUtils.splitPreserveAllTokens(null, *)         = null
2838      * StringUtils.splitPreserveAllTokens("", *)             = []
2839      * StringUtils.splitPreserveAllTokens("abc def", null)   = ["abc", "def"]
2840      * StringUtils.splitPreserveAllTokens("abc def", " ")    = ["abc", "def"]
2841      * StringUtils.splitPreserveAllTokens("abcdef", " ")   = ["abc", "", def"]
2842      * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":")   = ["ab", "cd", "ef"]
2843      * StringUtils.splitPreserveAllTokens("ab:cd:ef:", ":")= ["ab", "cd", "ef", ""]
2844      * StringUtils.splitPreserveAllTokens("ab:cd:ef::", ":") = ["ab", "cd", "ef", "", ""]
2845      * StringUtils.splitPreserveAllTokens("ab::cd:ef", ":")= ["ab", "", cd", "ef"]
2846      * StringUtils.splitPreserveAllTokens(":cd:ef", ":")   = ["", cd", "ef"]
2847      * StringUtils.splitPreserveAllTokens("::cd:ef", ":")    = ["", "", cd", "ef"]
2848      * StringUtils.splitPreserveAllTokens(":cd:ef:", ":")    = ["", cd", "ef", ""]
2849      *
2850      *
2851      * @param strthe String to parse, may be null
2852      * @param separatorCharsthe characters used as the delimiters,
2853      *null splits on whitespace
2854      * @return an array of parsed Strings, null if null String input
2855      * @since 2.1
2856      */
2857   public static String[] splitPreserveAllTokens(String str, String separatorChars) {
2858         return splitWorker(str, separatorChars, -1, true);
2859   }
2860
2861   /**
2862      * Splits the provided text into an array with a maximum length,
2863      * separators specified, preserving all tokens, including empty tokens
2864      * created by adjacent separators.
2865      *
2866      * The separator is not included in the returned String array.
2867      * Adjacent separators are treated as separators for empty tokens.
2868      * Adjacent separators are treated as one separator.
2869      *
2870      * A null input String returns null.
2871      * A null separatorChars splits on whitespace.
2872      *
2873      * If more than max delimited substrings are found, the last
2874      * returned string includes all characters after the first max - 1
2875      * returned strings (including separator characters).
2876      *
2877      *
2878      * StringUtils.splitPreserveAllTokens(null, *, *)            = null
2879      * StringUtils.splitPreserveAllTokens("", *, *)            = []
2880      * StringUtils.splitPreserveAllTokens("ab de fg", null, 0)   = ["ab", "cd", "ef"]
2881      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 0) = ["ab", "cd", "ef"]
2882      * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]
2883      * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]
2884      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 2) = ["ab", "de fg"]
2885      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 3) = ["ab", "", " de fg"]
2886      * StringUtils.splitPreserveAllTokens("ab   de fg", null, 4) = ["ab", "", "", "de fg"]
2887      *
2888      *
2889      * @param strthe String to parse, may be null
2890      * @param separatorCharsthe characters used as the delimiters,
2891      *null splits on whitespace
2892      * @param maxthe maximum number of elements to include in the
2893      *array. A zero or negative value implies no limit
2894      * @return an array of parsed Strings, null if null String input
2895      * @since 2.1
2896      */
2897   public static String[] splitPreserveAllTokens(String str, String separatorChars, int max) {
2898         return splitWorker(str, separatorChars, max, true);
2899   }
2900
2901   /**
2902      * Performs the logic for the split and
2903      * splitPreserveAllTokens methods that return a maximum array
2904      * length.
2905      *
2906      * @param strthe String to parse, may be null
2907      * @param separatorChars the separate character
2908      * @param maxthe maximum number of elements to include in the
2909      *array. A zero or negative value implies no limit.
2910      * @param preserveAllTokens if true, adjacent separators are
2911      * treated as empty token separators; if false, adjacent
2912      * separators are treated as one separator.
2913      * @return an array of parsed Strings, null if null String input
2914      */
2915   private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
2916         // Performance tuned for 2.0 (JDK1.4)
2917         // Direct code is quicker than StringTokenizer.
2918         // Also, StringTokenizer uses isSpace() not isWhitespace()
2919
2920         if (str == null) {
2921             return null;
2922         }
2923         int len = str.length();
2924         if (len == 0) {
2925             return ArrayUtils.EMPTY_STRING_ARRAY;
2926         }
2927         List list = new ArrayList();
2928         int sizePlus1 = 1;
2929         int i = 0, start = 0;
2930         boolean match = false;
2931         boolean lastMatch = false;
2932         if (separatorChars == null) {
2933             // Null separator means use whitespace
2934             while (i < len) {
2935               if (Character.isWhitespace(str.charAt(i))) {
2936                     if (match || preserveAllTokens) {
2937                         lastMatch = true;
2938                         if (sizePlus1++ == max) {
2939                           i = len;
2940                           lastMatch = false;
2941                         }
2942                         list.add(str.substring(start, i));
2943                         match = false;
2944                     }
2945                     start = ++i;
2946                     continue;
2947               }
2948               lastMatch = false;
2949               match = true;
2950               i++;
2951             }
2952         } else if (separatorChars.length() == 1) {
2953             // Optimise 1 character case
2954             char sep = separatorChars.charAt(0);
2955             while (i < len) {
2956               if (str.charAt(i) == sep) {
2957                     if (match || preserveAllTokens) {
2958                         lastMatch = true;
2959                         if (sizePlus1++ == max) {
2960                           i = len;
2961                           lastMatch = false;
2962                         }
2963                         list.add(str.substring(start, i));
2964                         match = false;
2965                     }
2966                     start = ++i;
2967                     continue;
2968               }
2969               lastMatch = false;
2970               match = true;
2971               i++;
2972             }
2973         } else {
2974             // standard case
2975             while (i < len) {
2976               if (separatorChars.indexOf(str.charAt(i)) >= 0) {
2977                     if (match || preserveAllTokens) {
2978                         lastMatch = true;
2979                         if (sizePlus1++ == max) {
2980                           i = len;
2981                           lastMatch = false;
2982                         }
2983                         list.add(str.substring(start, i));
2984                         match = false;
2985                     }
2986                     start = ++i;
2987                     continue;
2988               }
2989               lastMatch = false;
2990               match = true;
2991               i++;
2992             }
2993         }
2994         if (match || (preserveAllTokens && lastMatch)) {
2995             list.add(str.substring(start, i));
2996         }
2997         return (String[]) list.toArray(new String);
2998   }
2999
3000   /**
3001      * Splits a String by Character type as returned by
3002      * java.lang.Character.getType(char). Groups of contiguous
3003      * characters of the same type are returned as complete tokens.
3004      *
3005      * StringUtils.splitByCharacterType(null)         = null
3006      * StringUtils.splitByCharacterType("")         = []
3007      * StringUtils.splitByCharacterType("ab de fg")   = ["ab", " ", "de", " ", "fg"]
3008      * StringUtils.splitByCharacterType("ab   de fg") = ["ab", "   ", "de", " ", "fg"]
3009      * StringUtils.splitByCharacterType("ab:cd:ef")   = ["ab", ":", "cd", ":", "ef"]
3010      * StringUtils.splitByCharacterType("number5")    = ["number", "5"]
3011      * StringUtils.splitByCharacterType("fooBar")   = ["foo", "B", "ar"]
3012      * StringUtils.splitByCharacterType("foo200Bar")= ["foo", "200", "B", "ar"]
3013      * StringUtils.splitByCharacterType("ASFRules")   = ["ASFR", "ules"]
3014      *
3015      * @param str the String to split, may be null
3016      * @return an array of parsed Strings, null if null String input
3017      * @since 2.4
3018      */
3019   public static String[] splitByCharacterType(String str) {
3020         return splitByCharacterType(str, false);
3021   }
3022
3023   /**
3024      * Splits a String by Character type as returned by
3025      * java.lang.Character.getType(char). Groups of contiguous
3026      * characters of the same type are returned as complete tokens, with the
3027      * following exception: the character of type
3028      * Character.UPPERCASE_LETTER, if any, immediately
3029      * preceding a token of type Character.LOWERCASE_LETTER
3030      * will belong to the following token rather than to the preceding, if any,
3031      * Character.UPPERCASE_LETTER token.
3032      *
3033      * StringUtils.splitByCharacterTypeCamelCase(null)         = null
3034      * StringUtils.splitByCharacterTypeCamelCase("")         = []
3035      * StringUtils.splitByCharacterTypeCamelCase("ab de fg")   = ["ab", " ", "de", " ", "fg"]
3036      * StringUtils.splitByCharacterTypeCamelCase("ab   de fg") = ["ab", "   ", "de", " ", "fg"]
3037      * StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef")   = ["ab", ":", "cd", ":", "ef"]
3038      * StringUtils.splitByCharacterTypeCamelCase("number5")    = ["number", "5"]
3039      * StringUtils.splitByCharacterTypeCamelCase("fooBar")   = ["foo", "Bar"]
3040      * StringUtils.splitByCharacterTypeCamelCase("foo200Bar")= ["foo", "200", "Bar"]
3041      * StringUtils.splitByCharacterTypeCamelCase("ASFRules")   = ["ASF", "Rules"]
3042      *
3043      * @param str the String to split, may be null
3044      * @return an array of parsed Strings, null if null String input
3045      * @since 2.4
3046      */
3047   public static String[] splitByCharacterTypeCamelCase(String str) {
3048         return splitByCharacterType(str, true);
3049   }
3050
3051   /**
3052      * Splits a String by Character type as returned by
3053      * java.lang.Character.getType(char). Groups of contiguous
3054      * characters of the same type are returned as complete tokens, with the
3055      * following exception: if camelCase is true,
3056      * the character of type Character.UPPERCASE_LETTER, if any,
3057      * immediately preceding a token of type Character.LOWERCASE_LETTER
3058      * will belong to the following token rather than to the preceding, if any,
3059      * Character.UPPERCASE_LETTER token.
3060      * @param str the String to split, may be null
3061      * @param camelCase whether to use so-called "camel-case" for letter types
3062      * @return an array of parsed Strings, null if null String input
3063      * @since 2.4
3064      */
3065   private static String[] splitByCharacterType(String str, boolean camelCase) {
3066         if (str == null) {
3067             return null;
3068         }
3069         if (str.length() == 0) {
3070             return ArrayUtils.EMPTY_STRING_ARRAY;
3071         }
3072         char[] c = str.toCharArray();
3073         List list = new ArrayList();
3074         int tokenStart = 0;
3075         int currentType = Character.getType(c);
3076         for (int pos = tokenStart + 1; pos < c.length; pos++) {
3077             int type = Character.getType(c);
3078             if (type == currentType) {
3079               continue;
3080             }
3081             if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) {
3082               int newTokenStart = pos - 1;
3083               if (newTokenStart != tokenStart) {
3084                     list.add(new String(c, tokenStart, newTokenStart - tokenStart));
3085                     tokenStart = newTokenStart;
3086               }
3087             } else {
3088               list.add(new String(c, tokenStart, pos - tokenStart));
3089               tokenStart = pos;
3090             }
3091             currentType = type;
3092         }
3093         list.add(new String(c, tokenStart, c.length - tokenStart));
3094         return (String[]) list.toArray(new String);
3095   }
3096
3097   // Joining
3098   //-----------------------------------------------------------------------
3099   /**
3100      * Joins the provided elements into a single String.
3101      *
3102      * No separator is added to the joined String.
3103      * Null objects or empty string elements are represented by
3104      * empty strings.
3105      *
3106      *
3107      * StringUtils.concatenate(null)            = null
3108      * StringUtils.concatenate([])            = ""
3109      * StringUtils.concatenate()          = ""
3110      * StringUtils.concatenate(["a", "b", "c"]) = "abc"
3111      * StringUtils.concatenate() = "a"
3112      *
3113      *
3114      * @param arraythe array of values to concatenate, may be null
3115      * @return the concatenated String, null if null array input
3116      * @deprecated Use the better named {@link #join(Object[])} instead.
3117      *             Method will be removed in Commons Lang 3.0.
3118      */
3119   public static String concatenate(Object[] array) {
3120         return join(array, null);
3121   }
3122
3123   /**
3124      * Joins the elements of the provided array into a single String
3125      * containing the provided list of elements.
3126      *
3127      * No separator is added to the joined String.
3128      * Null objects or empty strings within the array are represented by
3129      * empty strings.
3130      *
3131      *
3132      * StringUtils.join(null)            = null
3133      * StringUtils.join([])            = ""
3134      * StringUtils.join()          = ""
3135      * StringUtils.join(["a", "b", "c"]) = "abc"
3136      * StringUtils.join() = "a"
3137      *
3138      *
3139      * @param arraythe array of values to join together, may be null
3140      * @return the joined String, null if null array input
3141      * @since 2.0
3142      */
3143   public static String join(Object[] array) {
3144         return join(array, null);
3145   }
3146
3147   /**
3148      * Joins the elements of the provided array into a single String
3149      * containing the provided list of elements.
3150      *
3151      * No delimiter is added before or after the list.
3152      * Null objects or empty strings within the array are represented by
3153      * empty strings.
3154      *
3155      *
3156      * StringUtils.join(null, *)               = null
3157      * StringUtils.join([], *)               = ""
3158      * StringUtils.join(, *)             = ""
3159      * StringUtils.join(["a", "b", "c"], ';')= "a;b;c"
3160      * StringUtils.join(["a", "b", "c"], null) = "abc"
3161      * StringUtils.join(, ';')= ";;a"
3162      *
3163      *
3164      * @param arraythe array of values to join together, may be null
3165      * @param separatorthe separator character to use
3166      * @return the joined String, null if null array input
3167      * @since 2.0
3168      */
3169   public static String join(Object[] array, char separator) {
3170         if (array == null) {
3171             return null;
3172         }
3173
3174         return join(array, separator, 0, array.length);
3175   }
3176
3177   /**
3178      * Joins the elements of the provided array into a single String
3179      * containing the provided list of elements.
3180      *
3181      * No delimiter is added before or after the list.
3182      * Null objects or empty strings within the array are represented by
3183      * empty strings.
3184      *
3185      *
3186      * StringUtils.join(null, *)               = null
3187      * StringUtils.join([], *)               = ""
3188      * StringUtils.join(, *)             = ""
3189      * StringUtils.join(["a", "b", "c"], ';')= "a;b;c"
3190      * StringUtils.join(["a", "b", "c"], null) = "abc"
3191      * StringUtils.join(, ';')= ";;a"
3192      *
3193      *
3194      * @param arraythe array of values to join together, may be null
3195      * @param separatorthe separator character to use
3196      * @param startIndex the first index to start joining from.It is
3197      * an error to pass in an end index past the end of the array
3198      * @param endIndex the index to stop joining from (exclusive). It is
3199      * an error to pass in an end index past the end of the array
3200      * @return the joined String, null if null array input
3201      * @since 2.0
3202      */
3203   public static String join(Object[] array, char separator, int startIndex, int endIndex) {
3204         if (array == null) {
3205             return null;
3206         }
3207         int bufSize = (endIndex - startIndex);
3208         if (bufSizestartIndex) {
3217               buf.append(separator);
3218             }
3219             if (array != null) {
3220               buf.append(array);
3221             }
3222         }
3223         return buf.toString();
3224   }
3225
3226
3227   /**
3228      * Joins the elements of the provided array into a single String
3229      * containing the provided list of elements.
3230      *
3231      * No delimiter is added before or after the list.
3232      * A null separator is the same as an empty String ("").
3233      * Null objects or empty strings within the array are represented by
3234      * empty strings.
3235      *
3236      *
3237      * StringUtils.join(null, *)                = null
3238      * StringUtils.join([], *)                  = ""
3239      * StringUtils.join(, *)            = ""
3240      * StringUtils.join(["a", "b", "c"], "--")= "a--b--c"
3241      * StringUtils.join(["a", "b", "c"], null)= "abc"
3242      * StringUtils.join(["a", "b", "c"], "")    = "abc"
3243      * StringUtils.join(, ',')   = ",,a"
3244      *
3245      *
3246      * @param arraythe array of values to join together, may be null
3247      * @param separatorthe separator character to use, null treated as ""
3248      * @return the joined String, null if null array input
3249      */
3250   public static String join(Object[] array, String separator) {
3251         if (array == null) {
3252             return null;
3253         }
3254         return join(array, separator, 0, array.length);
3255   }
3256
3257   /**
3258      * Joins the elements of the provided array into a single String
3259      * containing the provided list of elements.
3260      *
3261      * No delimiter is added before or after the list.
3262      * A null separator is the same as an empty String ("").
3263      * Null objects or empty strings within the array are represented by
3264      * empty strings.
3265      *
3266      *
3267      * StringUtils.join(null, *)                = null
3268      * StringUtils.join([], *)                  = ""
3269      * StringUtils.join(, *)            = ""
3270      * StringUtils.join(["a", "b", "c"], "--")= "a--b--c"
3271      * StringUtils.join(["a", "b", "c"], null)= "abc"
3272      * StringUtils.join(["a", "b", "c"], "")    = "abc"
3273      * StringUtils.join(, ',')   = ",,a"
3274      *
3275      *
3276      * @param arraythe array of values to join together, may be null
3277      * @param separatorthe separator character to use, null treated as ""
3278      * @param startIndex the first index to start joining from.It is
3279      * an error to pass in an end index past the end of the array
3280      * @param endIndex the index to stop joining from (exclusive). It is
3281      * an error to pass in an end index past the end of the array
3282      * @return the joined String, null if null array input
3283      */
3284   public static String join(Object[] array, String separator, int startIndex, int endIndex) {
3285         if (array == null) {
3286             return null;
3287         }
3288         if (separator == null) {
3289             separator = EMPTY;
3290         }
3291
3292         // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))
3293         //         (Assuming that all Strings are roughly equally long)
3294         int bufSize = (endIndex - startIndex);
3295         if (bufSizestartIndex) {
3306               buf.append(separator);
3307             }
3308             if (array != null) {
3309               buf.append(array);
3310             }
3311         }
3312         return buf.toString();
3313   }
3314
3315   /**
3316      * Joins the elements of the provided Iterator into
3317      * a single String containing the provided elements.
3318      *
3319      * No delimiter is added before or after the list. Null objects or empty
3320      * strings within the iteration are represented by empty strings.
3321      *
3322      * See the examples here: {@link #join(Object[],char)}.
3323      *
3324      * @param iteratorthe Iterator of values to join together, may be null
3325      * @param separatorthe separator character to use
3326      * @return the joined String, null if null iterator input
3327      * @since 2.0
3328      */
3329   public static String join(Iterator iterator, char separator) {
3330
3331         // handle null, zero and one elements before building a buffer
3332         if (iterator == null) {
3333             return null;
3334         }
3335         if (!iterator.hasNext()) {
3336             return EMPTY;
3337         }
3338         Object first = iterator.next();
3339         if (!iterator.hasNext()) {
3340             return ObjectUtils.toString(first);
3341         }
3342
3343         // two or more elements
3344         StrBuilder buf = new StrBuilder(256); // Java default is 16, probably too small
3345         if (first != null) {
3346             buf.append(first);
3347         }
3348
3349         while (iterator.hasNext()) {
3350             buf.append(separator);
3351             Object obj = iterator.next();
3352             if (obj != null) {
3353               buf.append(obj);
3354             }
3355         }
3356
3357         return buf.toString();
3358   }
3359
3360   /**
3361      * Joins the elements of the provided Iterator into
3362      * a single String containing the provided elements.
3363      *
3364      * No delimiter is added before or after the list.
3365      * A null separator is the same as an empty String ("").
3366      *
3367      * See the examples here: {@link #join(Object[],String)}.
3368      *
3369      * @param iteratorthe Iterator of values to join together, may be null
3370      * @param separatorthe separator character to use, null treated as ""
3371      * @return the joined String, null if null iterator input
3372      */
3373   public static String join(Iterator iterator, String separator) {
3374
3375         // handle null, zero and one elements before building a buffer
3376         if (iterator == null) {
3377             return null;
3378         }
3379         if (!iterator.hasNext()) {
3380             return EMPTY;
3381         }
3382         Object first = iterator.next();
3383         if (!iterator.hasNext()) {
3384             return ObjectUtils.toString(first);
3385         }
3386
3387         // two or more elements
3388         StrBuilder buf = new StrBuilder(256); // Java default is 16, probably too small
3389         if (first != null) {
3390             buf.append(first);
3391         }
3392
3393         while (iterator.hasNext()) {
3394             if (separator != null) {
3395               buf.append(separator);
3396             }
3397             Object obj = iterator.next();
3398             if (obj != null) {
3399               buf.append(obj);
3400             }
3401         }
3402         return buf.toString();
3403   }
3404
3405   /**
3406      * Joins the elements of the provided Collection into
3407      * a single String containing the provided elements.
3408      *
3409      * No delimiter is added before or after the list. Null objects or empty
3410      * strings within the iteration are represented by empty strings.
3411      *
3412      * See the examples here: {@link #join(Object[],char)}.
3413      *
3414      * @param collectionthe Collection of values to join together, may be null
3415      * @param separatorthe separator character to use
3416      * @return the joined String, null if null iterator input
3417      * @since 2.3
3418      */
3419   public static String join(Collection collection, char separator) {
3420         if (collection == null) {
3421             return null;
3422         }
3423         return join(collection.iterator(), separator);
3424   }
3425
3426   /**
3427      * Joins the elements of the provided Collection into
3428      * a single String containing the provided elements.
3429      *
3430      * No delimiter is added before or after the list.
3431      * A null separator is the same as an empty String ("").
3432      *
3433      * See the examples here: {@link #join(Object[],String)}.
3434      *
3435      * @param collectionthe Collection of values to join together, may be null
3436      * @param separatorthe separator character to use, null treated as ""
3437      * @return the joined String, null if null iterator input
3438      * @since 2.3
3439      */
3440   public static String join(Collection collection, String separator) {
3441         if (collection == null) {
3442             return null;
3443         }
3444         return join(collection.iterator(), separator);
3445   }
3446
3447   // Delete
3448   //-----------------------------------------------------------------------
3449   /**
3450      * Deletes all 'space' characters from a String as defined by
3451      * {@link Character#isSpace(char)}.
3452      *
3453      * This is the only StringUtils method that uses the
3454      * isSpace definition. You are advised to use
3455      * {@link #deleteWhitespace(String)} instead as whitespace is much
3456      * better localized.
3457      *
3458      *
3459      * StringUtils.deleteSpaces(null)         = null
3460      * StringUtils.deleteSpaces("")             = ""
3461      * StringUtils.deleteSpaces("abc")          = "abc"
3462      * StringUtils.deleteSpaces(" \tabc \n ") = "abc"
3463      * StringUtils.deleteSpaces("abc")      = "abc"
3464      * StringUtils.deleteSpaces("a\nb\tc   ") = "abc"
3465      *
3466      *
3467      * Spaces are defined as {' ', '\t', '\r', '\n', '\b'}
3468      * in line with the deprecated isSpace method.
3469      *
3470      * @param strthe String to delete spaces from, may be null
3471      * @return the String without 'spaces', null if null String input
3472      * @deprecated Use the better localized {@link #deleteWhitespace(String)}.
3473      *             Method will be removed in Commons Lang 3.0.
3474      */
3475   public static String deleteSpaces(String str) {
3476         if (str == null) {
3477             return null;
3478         }
3479         return CharSetUtils.delete(str, " \t\r\n\b");
3480   }
3481
3482   /**
3483      * Deletes all whitespaces from a String as defined by
3484      * {@link Character#isWhitespace(char)}.
3485      *
3486      *
3487      * StringUtils.deleteWhitespace(null)         = null
3488      * StringUtils.deleteWhitespace("")         = ""
3489      * StringUtils.deleteWhitespace("abc")      = "abc"
3490      * StringUtils.deleteWhitespace("   abc") = "abc"
3491      *
3492      *
3493      * @param strthe String to delete whitespace from, may be null
3494      * @return the String without whitespaces, null if null String input
3495      */
3496   public static String deleteWhitespace(String str) {
3497         if (isEmpty(str)) {
3498             return str;
3499         }
3500         int sz = str.length();
3501         char[] chs = new char;
3502         int count = 0;
3503         for (int i = 0; i < sz; i++) {
3504             if (!Character.isWhitespace(str.charAt(i))) {
3505               chs = str.charAt(i);
3506             }
3507         }
3508         if (count == sz) {
3509             return str;
3510         }
3511         return new String(chs, 0, count);
3512   }
3513
3514   // Remove
3515   //-----------------------------------------------------------------------
3516   /**
3517      * Removes a substring only if it is at the begining of a source string,
3518      * otherwise returns the source string.
3519      *
3520      * A null source string will return null.
3521      * An empty ("") source string will return the empty string.
3522      * A null search string will return the source string.
3523      *
3524      *
3525      * StringUtils.removeStart(null, *)      = null
3526      * StringUtils.removeStart("", *)      = ""
3527      * StringUtils.removeStart(*, null)      = *
3528      * StringUtils.removeStart("www.domain.com", "www.")   = "domain.com"
3529      * StringUtils.removeStart("domain.com", "www.")       = "domain.com"
3530      * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
3531      * StringUtils.removeStart("abc", "")    = "abc"
3532      *
3533      *
3534      * @param strthe source String to search, may be null
3535      * @param removethe String to search for and remove, may be null
3536      * @return the substring with the string removed if found,
3537      *null if null String input
3538      * @since 2.1
3539      */
3540   public static String removeStart(String str, String remove) {
3541         if (isEmpty(str) || isEmpty(remove)) {
3542             return str;
3543         }
3544         if (str.startsWith(remove)){
3545             return str.substring(remove.length());
3546         }
3547         return str;
3548   }
3549
3550   /**
3551      * Case insensitive removal of a substring if it is at the begining of a source string,
3552      * otherwise returns the source string.
3553      *
3554      * A null source string will return null.
3555      * An empty ("") source string will return the empty string.
3556      * A null search string will return the source string.
3557      *
3558      *
3559      * StringUtils.removeStartIgnoreCase(null, *)      = null
3560      * StringUtils.removeStartIgnoreCase("", *)      = ""
3561      * StringUtils.removeStartIgnoreCase(*, null)      = *
3562      * StringUtils.removeStartIgnoreCase("www.domain.com", "www.")   = "domain.com"
3563      * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.")   = "domain.com"
3564      * StringUtils.removeStartIgnoreCase("domain.com", "www.")       = "domain.com"
3565      * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain.com"
3566      * StringUtils.removeStartIgnoreCase("abc", "")    = "abc"
3567      *
3568      *
3569      * @param strthe source String to search, may be null
3570      * @param removethe String to search for (case insensitive) and remove, may be null
3571      * @return the substring with the string removed if found,
3572      *null if null String input
3573      * @since 2.4
3574      */
3575   public static String removeStartIgnoreCase(String str, String remove) {
3576         if (isEmpty(str) || isEmpty(remove)) {
3577             return str;
3578         }
3579         if (startsWithIgnoreCase(str, remove)) {
3580             return str.substring(remove.length());
3581         }
3582         return str;
3583   }
3584
3585   /**
3586      * Removes a substring only if it is at the end of a source string,
3587      * otherwise returns the source string.
3588      *
3589      * A null source string will return null.
3590      * An empty ("") source string will return the empty string.
3591      * A null search string will return the source string.
3592      *
3593      *
3594      * StringUtils.removeEnd(null, *)      = null
3595      * StringUtils.removeEnd("", *)      = ""
3596      * StringUtils.removeEnd(*, null)      = *
3597      * StringUtils.removeEnd("www.domain.com", ".com.")= "www.domain.com"
3598      * StringUtils.removeEnd("www.domain.com", ".com")   = "www.domain"
3599      * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
3600      * StringUtils.removeEnd("abc", "")    = "abc"
3601      *
3602      *
3603      * @param strthe source String to search, may be null
3604      * @param removethe String to search for and remove, may be null
3605      * @return the substring with the string removed if found,
3606      *null if null String input
3607      * @since 2.1
3608      */
3609   public static String removeEnd(String str, String remove) {
3610         if (isEmpty(str) || isEmpty(remove)) {
3611             return str;
3612         }
3613         if (str.endsWith(remove)) {
3614             return str.substring(0, str.length() - remove.length());
3615         }
3616         return str;
3617   }
3618
3619   /**
3620      * Case insensitive removal of a substring if it is at the end of a source string,
3621      * otherwise returns the source string.
3622      *
3623      * A null source string will return null.
3624      * An empty ("") source string will return the empty string.
3625      * A null search string will return the source string.
3626      *
3627      *
3628      * StringUtils.removeEndIgnoreCase(null, *)      = null
3629      * StringUtils.removeEndIgnoreCase("", *)      = ""
3630      * StringUtils.removeEndIgnoreCase(*, null)      = *
3631      * StringUtils.removeEndIgnoreCase("www.domain.com", ".com.")= "www.domain.com"
3632      * StringUtils.removeEndIgnoreCase("www.domain.com", ".com")   = "www.domain"
3633      * StringUtils.removeEndIgnoreCase("www.domain.com", "domain") = "www.domain.com"
3634      * StringUtils.removeEndIgnoreCase("abc", "")    = "abc"
3635      * StringUtils.removeEndIgnoreCase("www.domain.com", ".COM") = "www.domain")
3636      * StringUtils.removeEndIgnoreCase("www.domain.COM", ".com") = "www.domain")
3637      *
3638      *
3639      * @param strthe source String to search, may be null
3640      * @param removethe String to search for (case insensitive) and remove, may be null
3641      * @return the substring with the string removed if found,
3642      *null if null String input
3643      * @since 2.4
3644      */
3645   public static String removeEndIgnoreCase(String str, String remove) {
3646         if (isEmpty(str) || isEmpty(remove)) {
3647             return str;
3648         }
3649         if (endsWithIgnoreCase(str, remove)) {
3650             return str.substring(0, str.length() - remove.length());
3651         }
3652         return str;
3653   }
3654
3655   /**
3656      * Removes all occurrences of a substring from within the source string.
3657      *
3658      * A null source string will return null.
3659      * An empty ("") source string will return the empty string.
3660      * A null remove string will return the source string.
3661      * An empty ("") remove string will return the source string.
3662      *
3663      *
3664      * StringUtils.remove(null, *)      = null
3665      * StringUtils.remove("", *)          = ""
3666      * StringUtils.remove(*, null)      = *
3667      * StringUtils.remove(*, "")          = *
3668      * StringUtils.remove("queued", "ue") = "qd"
3669      * StringUtils.remove("queued", "zz") = "queued"
3670      *
3671      *
3672      * @param strthe source String to search, may be null
3673      * @param removethe String to search for and remove, may be null
3674      * @return the substring with the string removed if found,
3675      *null if null String input
3676      * @since 2.1
3677      */
3678   public static String remove(String str, String remove) {
3679         if (isEmpty(str) || isEmpty(remove)) {
3680             return str;
3681         }
3682         return replace(str, remove, EMPTY, -1);
3683   }
3684
3685   /**
3686      * Removes all occurrences of a character from within the source string.
3687      *
3688      * A null source string will return null.
3689      * An empty ("") source string will return the empty string.
3690      *
3691      *
3692      * StringUtils.remove(null, *)       = null
3693      * StringUtils.remove("", *)         = ""
3694      * StringUtils.remove("queued", 'u') = "qeed"
3695      * StringUtils.remove("queued", 'z') = "queued"
3696      *
3697      *
3698      * @param strthe source String to search, may be null
3699      * @param removethe char to search for and remove, may be null
3700      * @return the substring with the char removed if found,
3701      *null if null String input
3702      * @since 2.1
3703      */
3704   public static String remove(String str, char remove) {
3705         if (isEmpty(str) || str.indexOf(remove) == INDEX_NOT_FOUND) {
3706             return str;
3707         }
3708         char[] chars = str.toCharArray();
3709         int pos = 0;
3710         for (int i = 0; i < chars.length; i++) {
3711             if (chars != remove) {
3712               chars = chars;
3713             }
3714         }
3715         return new String(chars, 0, pos);
3716   }
3717
3718   // Replacing
3719   //-----------------------------------------------------------------------
3720   /**
3721      * Replaces a String with another String inside a larger String, once.
3722      *
3723      * A null reference passed to this method is a no-op.
3724      *
3725      *
3726      * StringUtils.replaceOnce(null, *, *)      = null
3727      * StringUtils.replaceOnce("", *, *)          = ""
3728      * StringUtils.replaceOnce("any", null, *)    = "any"
3729      * StringUtils.replaceOnce("any", *, null)    = "any"
3730      * StringUtils.replaceOnce("any", "", *)      = "any"
3731      * StringUtils.replaceOnce("aba", "a", null)= "aba"
3732      * StringUtils.replaceOnce("aba", "a", "")    = "ba"
3733      * StringUtils.replaceOnce("aba", "a", "z")   = "zba"
3734      *
3735      *
3736      * @see #replace(String text, String searchString, String replacement, int max)
3737      * @param texttext to search and replace in, may be null
3738      * @param searchStringthe String to search for, may be null
3739      * @param replacementthe String to replace with, may be null
3740      * @return the text with any replacements processed,
3741      *null if null String input
3742      */
3743   public static String replaceOnce(String text, String searchString, String replacement) {
3744         return replace(text, searchString, replacement, 1);
3745   }
3746
3747   /**
3748      * Replaces all occurrences of a String within another String.
3749      *
3750      * A null reference passed to this method is a no-op.
3751      *
3752      *
3753      * StringUtils.replace(null, *, *)      = null
3754      * StringUtils.replace("", *, *)          = ""
3755      * StringUtils.replace("any", null, *)    = "any"
3756      * StringUtils.replace("any", *, null)    = "any"
3757      * StringUtils.replace("any", "", *)      = "any"
3758      * StringUtils.replace("aba", "a", null)= "aba"
3759      * StringUtils.replace("aba", "a", "")    = "b"
3760      * StringUtils.replace("aba", "a", "z")   = "zbz"
3761      *
3762      *
3763      * @see #replace(String text, String searchString, String replacement, int max)
3764      * @param texttext to search and replace in, may be null
3765      * @param searchStringthe String to search for, may be null
3766      * @param replacementthe String to replace it with, may be null
3767      * @return the text with any replacements processed,
3768      *null if null String input
3769      */
3770   public static String replace(String text, String searchString, String replacement) {
3771         return replace(text, searchString, replacement, -1);
3772   }
3773
3774   /**
3775      * Replaces a String with another String inside a larger String,
3776      * for the first max values of the search String.
3777      *
3778      * A null reference passed to this method is a no-op.
3779      *
3780      *
3781      * StringUtils.replace(null, *, *, *)         = null
3782      * StringUtils.replace("", *, *, *)         = ""
3783      * StringUtils.replace("any", null, *, *)   = "any"
3784      * StringUtils.replace("any", *, null, *)   = "any"
3785      * StringUtils.replace("any", "", *, *)       = "any"
3786      * StringUtils.replace("any", *, *, 0)      = "any"
3787      * StringUtils.replace("abaa", "a", null, -1) = "abaa"
3788      * StringUtils.replace("abaa", "a", "", -1)   = "b"
3789      * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
3790      * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
3791      * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
3792      * StringUtils.replace("abaa", "a", "z", -1)= "zbzz"
3793      *
3794      *
3795      * @param texttext to search and replace in, may be null
3796      * @param searchStringthe String to search for, may be null
3797      * @param replacementthe String to replace it with, may be null
3798      * @param maxmaximum number of values to replace, or -1 if no maximum
3799      * @return the text with any replacements processed,
3800      *null if null String input
3801      */
3802   public static String replace(String text, String searchString, String replacement, int max) {
3803         if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
3804             return text;
3805         }
3806         int start = 0;
3807         int end = text.indexOf(searchString, start);
3808         if (end == INDEX_NOT_FOUND) {
3809             return text;
3810         }
3811         int replLength = searchString.length();
3812         int increase = replacement.length() - replLength;
3813         increase = (increase < 0 ? 0 : increase);
3814         increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
3815         StrBuilder buf = new StrBuilder(text.length() + increase);
3816         while (end != INDEX_NOT_FOUND) {
3817             buf.append(text.substring(start, end)).append(replacement);
3818             start = end + replLength;
3819             if (--max == 0) {
3820               break;
3821             }
3822             end = text.indexOf(searchString, start);
3823         }
3824         buf.append(text.substring(start));
3825         return buf.toString();
3826   }
3827
3828   /**
3829      *
3830      * Replaces all occurrences of Strings within another String.
3831      *
3832      *
3833      *
3834      * A null reference passed to this method is a no-op, or if
3835      * any "search string" or "string to replace" is null, that replace will be
3836      * ignored. This will not repeat. For repeating replaces, call the
3837      * overloaded method.
3838      *
3839      *
3840      *
3841      *StringUtils.replaceEach(null, *, *)      = null
3842      *StringUtils.replaceEach("", *, *)          = ""
3843      *StringUtils.replaceEach("aba", null, null) = "aba"
3844      *StringUtils.replaceEach("aba", new String, null) = "aba"
3845      *StringUtils.replaceEach("aba", null, new String) = "aba"
3846      *StringUtils.replaceEach("aba", new String[]{"a"}, null)= "aba"
3847      *StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""})= "b"
3848      *StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"})= "aba"
3849      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"})= "wcte"
3850      *(example of how it does not repeat)
3851      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"})= "dcte"
3852      *
3853      *
3854      * @param text
3855      *            text to search and replace in, no-op if null
3856      * @param searchList
3857      *            the Strings to search for, no-op if null
3858      * @param replacementList
3859      *            the Strings to replace them with, no-op if null
3860      * @return the text with any replacements processed, null if
3861      *         null String input
3862      * @throws IndexOutOfBoundsException
3863      *             if the lengths of the arrays are not the same (null is ok,
3864      *             and/or size 0)
3865      * @since 2.4
3866      */
3867   public static String replaceEach(String text, String[] searchList, String[] replacementList) {
3868         return replaceEach(text, searchList, replacementList, false, 0);
3869   }
3870
3871   /**
3872      *
3873      * Replaces all occurrences of Strings within another String.
3874      *
3875      *
3876      *
3877      * A null reference passed to this method is a no-op, or if
3878      * any "search string" or "string to replace" is null, that replace will be
3879      * ignored. This will not repeat. For repeating replaces, call the
3880      * overloaded method.
3881      *
3882      *
3883      *
3884      *StringUtils.replaceEach(null, *, *, *) = null
3885      *StringUtils.replaceEach("", *, *, *) = ""
3886      *StringUtils.replaceEach("aba", null, null, *) = "aba"
3887      *StringUtils.replaceEach("aba", new String, null, *) = "aba"
3888      *StringUtils.replaceEach("aba", null, new String, *) = "aba"
3889      *StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
3890      *StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
3891      *StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
3892      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
3893      *(example of how it repeats)
3894      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
3895      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
3896      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, true) = IllegalArgumentException
3897      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, false) = "dcabe"
3898      *
3899      *
3900      * @param text
3901      *            text to search and replace in, no-op if null
3902      * @param searchList
3903      *            the Strings to search for, no-op if null
3904      * @param replacementList
3905      *            the Strings to replace them with, no-op if null
3906      * @return the text with any replacements processed, null if
3907      *         null String input
3908      * @throws IllegalArgumentException
3909      *             if the search is repeating and there is an endless loop due
3910      *             to outputs of one being inputs to another
3911      * @throws IndexOutOfBoundsException
3912      *             if the lengths of the arrays are not the same (null is ok,
3913      *             and/or size 0)
3914      * @since 2.4
3915      */
3916   public static String replaceEachRepeatedly(String text, String[] searchList, String[] replacementList) {
3917         // timeToLive should be 0 if not used or nothing to replace, else it's
3918         // the length of the replace array
3919         int timeToLive = searchList == null ? 0 : searchList.length;
3920         return replaceEach(text, searchList, replacementList, true, timeToLive);
3921   }
3922
3923   /**
3924      *
3925      * Replaces all occurrences of Strings within another String.
3926      *
3927      *
3928      *
3929      * A null reference passed to this method is a no-op, or if
3930      * any "search string" or "string to replace" is null, that replace will be
3931      * ignored.
3932      *
3933      *
3934      *
3935      *StringUtils.replaceEach(null, *, *, *) = null
3936      *StringUtils.replaceEach("", *, *, *) = ""
3937      *StringUtils.replaceEach("aba", null, null, *) = "aba"
3938      *StringUtils.replaceEach("aba", new String, null, *) = "aba"
3939      *StringUtils.replaceEach("aba", null, new String, *) = "aba"
3940      *StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
3941      *StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
3942      *StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
3943      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
3944      *(example of how it repeats)
3945      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
3946      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
3947      *StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, *) = IllegalArgumentException
3948      *
3949      *
3950      * @param text
3951      *            text to search and replace in, no-op if null
3952      * @param searchList
3953      *            the Strings to search for, no-op if null
3954      * @param replacementList
3955      *            the Strings to replace them with, no-op if null
3956      * @param repeat if true, then replace repeatedly
3957      *       until there are no more possible replacements or timeToLive < 0
3958      * @param timeToLive
3959      *            if less than 0 then there is a circular reference and endless
3960      *            loop
3961      * @return the text with any replacements processed, null if
3962      *         null String input
3963      * @throws IllegalArgumentException
3964      *             if the search is repeating and there is an endless loop due
3965      *             to outputs of one being inputs to another
3966      * @throws IndexOutOfBoundsException
3967      *             if the lengths of the arrays are not the same (null is ok,
3968      *             and/or size 0)
3969      * @since 2.4
3970      */
3971   private static String replaceEach(String text, String[] searchList, String[] replacementList,
3972                                       boolean repeat, int timeToLive)
3973   {
3974
3975         // mchyzer Performance note: This creates very few new objects (one major goal)
3976         // let me know if there are performance requests, we can create a harness to measure
3977
3978         if (text == null || text.length() == 0 || searchList == null ||
3979             searchList.length == 0 || replacementList == null || replacementList.length == 0)
3980         {
3981             return text;
3982         }
3983
3984         // if recursing, this shouldnt be less than 0
3985         if (timeToLive < 0) {
3986             throw new IllegalStateException("TimeToLive of " + timeToLive + " is less than 0: " + text);
3987         }
3988
3989         int searchLength = searchList.length;
3990         int replacementLength = replacementList.length;
3991
3992         // make sure lengths are ok, these need to be equal
3993         if (searchLength != replacementLength) {
3994             throw new IllegalArgumentException("Search and Replace array lengths don't match: "
3995               + searchLength
3996               + " vs "
3997               + replacementLength);
3998         }
3999
4000         // keep track of which still have matches
4001         boolean[] noMoreMatchesForReplIndex = new boolean;
4002
4003         // index on index that the match was found
4004         int textIndex = -1;
4005         int replaceIndex = -1;
4006         int tempIndex = -1;
4007
4008         // index of replace array that will replace the search string found
4009         // NOTE: logic duplicated below START
4010         for (int i = 0; i < searchLength; i++) {
4011             if (noMoreMatchesForReplIndex || searchList == null ||
4012               searchList.length() == 0 || replacementList == null)
4013             {
4014               continue;
4015             }
4016             tempIndex = text.indexOf(searchList);
4017
4018             // see if we need to keep searching for this
4019             if (tempIndex == -1) {
4020               noMoreMatchesForReplIndex = true;
4021             } else {
4022               if (textIndex == -1 || tempIndex < textIndex) {
4023                     textIndex = tempIndex;
4024                     replaceIndex = i;
4025               }
4026             }
4027         }
4028         // NOTE: logic mostly below END
4029
4030         // no search strings found, we are done
4031         if (textIndex == -1) {
4032             return text;
4033         }
4034
4035         int start = 0;
4036
4037         // get a good guess on the size of the result buffer so it doesnt have to double if it goes over a bit
4038         int increase = 0;
4039
4040         // count the replacement text elements that are larger than their corresponding text being replaced
4041         for (int i = 0; i < searchList.length; i++) {
4042             if (searchList == null || replacementList == null) {
4043               continue;
4044             }
4045             int greater = replacementList.length() - searchList.length();
4046             if (greater > 0) {
4047               increase += 3 * greater; // assume 3 matches
4048             }
4049         }
4050         // have upper-bound at 20% increase, then let Java take over
4051         increase = Math.min(increase, text.length() / 5);
4052
4053         StrBuilder buf = new StrBuilder(text.length() + increase);
4054
4055         while (textIndex != -1) {
4056
4057             for (int i = start; i < textIndex; i++) {
4058               buf.append(text.charAt(i));
4059             }
4060             buf.append(replacementList);
4061
4062             start = textIndex + searchList.length();
4063
4064             textIndex = -1;
4065             replaceIndex = -1;
4066             tempIndex = -1;
4067             // find the next earliest match
4068             // NOTE: logic mostly duplicated above START
4069             for (int i = 0; i < searchLength; i++) {
4070               if (noMoreMatchesForReplIndex || searchList == null ||
4071                     searchList.length() == 0 || replacementList == null)
4072               {
4073                     continue;
4074               }
4075               tempIndex = text.indexOf(searchList, start);
4076
4077               // see if we need to keep searching for this
4078               if (tempIndex == -1) {
4079                     noMoreMatchesForReplIndex = true;
4080               } else {
4081                     if (textIndex == -1 || tempIndex < textIndex) {
4082                         textIndex = tempIndex;
4083                         replaceIndex = i;
4084                     }
4085               }
4086             }
4087             // NOTE: logic duplicated above END
4088
4089         }
4090         int textLength = text.length();
4091         for (int i = start; i < textLength; i++) {
4092             buf.append(text.charAt(i));
4093         }
4094         String result = buf.toString();
4095         if (!repeat) {
4096             return result;
4097         }
4098
4099         return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
4100   }
4101
4102   // Replace, character based
4103   //-----------------------------------------------------------------------
4104   /**
4105      * Replaces all occurrences of a character in a String with another.
4106      * This is a null-safe version of {@link String#replace(char, char)}.
4107      *
4108      * A null string input returns null.
4109      * An empty ("") string input returns an empty string.
4110      *
4111      *
4112      * StringUtils.replaceChars(null, *, *)      = null
4113      * StringUtils.replaceChars("", *, *)          = ""
4114      * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
4115      * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
4116      *
4117      *
4118      * @param strString to replace characters in, may be null
4119      * @param searchCharthe character to search for, may be null
4120      * @param replaceCharthe character to replace, may be null
4121      * @return modified String, null if null string input
4122      * @since 2.0
4123      */
4124   public static String replaceChars(String str, char searchChar, char replaceChar) {
4125         if (str == null) {
4126             return null;
4127         }
4128         return str.replace(searchChar, replaceChar);
4129   }
4130
4131   /**
4132      * Replaces multiple characters in a String in one go.
4133      * This method can also be used to delete characters.
4134      *
4135      * For example:
4136      * replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = jelly.
4137      *
4138      * A null string input returns null.
4139      * An empty ("") string input returns an empty string.
4140      * A null or empty set of search characters returns the input string.
4141      *
4142      * The length of the search characters should normally equal the length
4143      * of the replace characters.
4144      * If the search characters is longer, then the extra search characters
4145      * are deleted.
4146      * If the search characters is shorter, then the extra replace characters
4147      * are ignored.
4148      *
4149      *
4150      * StringUtils.replaceChars(null, *, *)         = null
4151      * StringUtils.replaceChars("", *, *)             = ""
4152      * StringUtils.replaceChars("abc", null, *)       = "abc"
4153      * StringUtils.replaceChars("abc", "", *)         = "abc"
4154      * StringUtils.replaceChars("abc", "b", null)   = "ac"
4155      * StringUtils.replaceChars("abc", "b", "")       = "ac"
4156      * StringUtils.replaceChars("abcba", "bc", "yz")= "ayzya"
4157      * StringUtils.replaceChars("abcba", "bc", "y")   = "ayya"
4158      * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
4159      *
4160      *
4161      * @param strString to replace characters in, may be null
4162      * @param searchCharsa set of characters to search for, may be null
4163      * @param replaceCharsa set of characters to replace, may be null
4164      * @return modified String, null if null string input
4165      * @since 2.0
4166      */
4167   public static String replaceChars(String str, String searchChars, String replaceChars) {
4168         if (isEmpty(str) || isEmpty(searchChars)) {
4169             return str;
4170         }
4171         if (replaceChars == null) {
4172             replaceChars = EMPTY;
4173         }
4174         boolean modified = false;
4175         int replaceCharsLength = replaceChars.length();
4176         int strLength = str.length();
4177         StrBuilder buf = new StrBuilder(strLength);
4178         for (int i = 0; i < strLength; i++) {
4179             char ch = str.charAt(i);
4180             int index = searchChars.indexOf(ch);
4181             if (index >= 0) {
4182               modified = true;
4183               if (index < replaceCharsLength) {
4184                     buf.append(replaceChars.charAt(index));
4185               }
4186             } else {
4187               buf.append(ch);
4188             }
4189         }
4190         if (modified) {
4191             return buf.toString();
4192         }
4193         return str;
4194   }
4195
4196   // Overlay
4197   //-----------------------------------------------------------------------
4198   /**
4199      * Overlays part of a String with another String.
4200      *
4201      *
4202      * StringUtils.overlayString(null, *, *, *)         = NullPointerException
4203      * StringUtils.overlayString(*, null, *, *)         = NullPointerException
4204      * StringUtils.overlayString("", "abc", 0, 0)         = "abc"
4205      * StringUtils.overlayString("abcdef", null, 2, 4)    = "abef"
4206      * StringUtils.overlayString("abcdef", "", 2, 4)      = "abef"
4207      * StringUtils.overlayString("abcdef", "zzzz", 2, 4)= "abzzzzef"
4208      * StringUtils.overlayString("abcdef", "zzzz", 4, 2)= "abcdzzzzcdef"
4209      * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsException
4210      * StringUtils.overlayString("abcdef", "zzzz", 2, 8)= IndexOutOfBoundsException
4211      *
4212      *
4213      * @param textthe String to do overlaying in, may be null
4214      * @param overlaythe String to overlay, may be null
4215      * @param startthe position to start overlaying at, must be valid
4216      * @param endthe position to stop overlaying before, must be valid
4217      * @return overlayed String, null if null String input
4218      * @throws NullPointerException if text or overlay is null
4219      * @throws IndexOutOfBoundsException if either position is invalid
4220      * @deprecated Use better named {@link #overlay(String, String, int, int)} instead.
4221      *             Method will be removed in Commons Lang 3.0.
4222      */
4223   public static String overlayString(String text, String overlay, int start, int end) {
4224         return new StrBuilder(start + overlay.length() + text.length() - end + 1)
4225             .append(text.substring(0, start))
4226             .append(overlay)
4227             .append(text.substring(end))
4228             .toString();
4229   }
4230
4231   /**
4232      * Overlays part of a String with another String.
4233      *
4234      * A null string input returns null.
4235      * A negative index is treated as zero.
4236      * An index greater than the string length is treated as the string length.
4237      * The start index is always the smaller of the two indices.
4238      *
4239      *
4240      * StringUtils.overlay(null, *, *, *)            = null
4241      * StringUtils.overlay("", "abc", 0, 0)          = "abc"
4242      * StringUtils.overlay("abcdef", null, 2, 4)   = "abef"
4243      * StringUtils.overlay("abcdef", "", 2, 4)       = "abef"
4244      * StringUtils.overlay("abcdef", "", 4, 2)       = "abef"
4245      * StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
4246      * StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
4247      * StringUtils.overlay("abcdef", "zzzz", -1, 4)= "zzzzef"
4248      * StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
4249      * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
4250      * StringUtils.overlay("abcdef", "zzzz", 8, 10)= "abcdefzzzz"
4251      *
4252      *
4253      * @param strthe String to do overlaying in, may be null
4254      * @param overlaythe String to overlay, may be null
4255      * @param startthe position to start overlaying at
4256      * @param endthe position to stop overlaying before
4257      * @return overlayed String, null if null String input
4258      * @since 2.0
4259      */
4260   public static String overlay(String str, String overlay, int start, int end) {
4261         if (str == null) {
4262             return null;
4263         }
4264         if (overlay == null) {
4265             overlay = EMPTY;
4266         }
4267         int len = str.length();
4268         if (start < 0) {
4269             start = 0;
4270         }
4271         if (start > len) {
4272             start = len;
4273         }
4274         if (end < 0) {
4275             end = 0;
4276         }
4277         if (end > len) {
4278             end = len;
4279         }
4280         if (start > end) {
4281             int temp = start;
4282             start = end;
4283             end = temp;
4284         }
4285         return new StrBuilder(len + start - end + overlay.length() + 1)
4286             .append(str.substring(0, start))
4287             .append(overlay)
4288             .append(str.substring(end))
4289             .toString();
4290   }
4291
4292   // Chomping
4293   //-----------------------------------------------------------------------
4294   /**
4295      * Removes one newline from end of a String if it's there,
4296      * otherwise leave it alone.A newline is &quot;\n&quot;,
4297      * &quot;\r&quot;, or &quot;\r\n&quot;.
4298      *
4299      * NOTE: This method changed in 2.0.
4300      * It now more closely matches Perl chomp.
4301      *
4302      *
4303      * StringUtils.chomp(null)          = null
4304      * StringUtils.chomp("")            = ""
4305      * StringUtils.chomp("abc \r")      = "abc "
4306      * StringUtils.chomp("abc\n")       = "abc"
4307      * StringUtils.chomp("abc\r\n")   = "abc"
4308      * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
4309      * StringUtils.chomp("abc\n\r")   = "abc\n"
4310      * StringUtils.chomp("abc\n\rabc")= "abc\n\rabc"
4311      * StringUtils.chomp("\r")          = ""
4312      * StringUtils.chomp("\n")          = ""
4313      * StringUtils.chomp("\r\n")      = ""
4314      *
4315      *
4316      * @param strthe String to chomp a newline from, may be null
4317      * @return String without newline, null if null String input
4318      */
4319   public static String chomp(String str) {
4320         if (isEmpty(str)) {
4321             return str;
4322         }
4323
4324         if (str.length() == 1) {
4325             char ch = str.charAt(0);
4326             if (ch == CharUtils.CR || ch == CharUtils.LF) {
4327               return EMPTY;
4328             }
4329             return str;
4330         }
4331
4332         int lastIdx = str.length() - 1;
4333         char last = str.charAt(lastIdx);
4334
4335         if (last == CharUtils.LF) {
4336             if (str.charAt(lastIdx - 1) == CharUtils.CR) {
4337               lastIdx--;
4338             }
4339         } else if (last != CharUtils.CR) {
4340             lastIdx++;
4341         }
4342         return str.substring(0, lastIdx);
4343   }
4344
4345   /**
4346      * Removes separator from the end of
4347      * str if it's there, otherwise leave it alone.
4348      *
4349      * NOTE: This method changed in version 2.0.
4350      * It now more closely matches Perl chomp.
4351      * For the previous behavior, use {@link #substringBeforeLast(String, String)}.
4352      * This method uses {@link String#endsWith(String)}.
4353      *
4354      *
4355      * StringUtils.chomp(null, *)         = null
4356      * StringUtils.chomp("", *)         = ""
4357      * StringUtils.chomp("foobar", "bar") = "foo"
4358      * StringUtils.chomp("foobar", "baz") = "foobar"
4359      * StringUtils.chomp("foo", "foo")    = ""
4360      * StringUtils.chomp("foo ", "foo")   = "foo "
4361      * StringUtils.chomp(" foo", "foo")   = " "
4362      * StringUtils.chomp("foo", "foooo")= "foo"
4363      * StringUtils.chomp("foo", "")       = "foo"
4364      * StringUtils.chomp("foo", null)   = "foo"
4365      *
4366      *
4367      * @param strthe String to chomp from, may be null
4368      * @param separatorseparator String, may be null
4369      * @return String without trailing separator, null if null String input
4370      */
4371   public static String chomp(String str, String separator) {
4372         if (isEmpty(str) || separator == null) {
4373             return str;
4374         }
4375         if (str.endsWith(separator)) {
4376             return str.substring(0, str.length() - separator.length());
4377         }
4378         return str;
4379   }
4380
4381   /**
4382      * Remove any &quot;\n&quot; if and only if it is at the end
4383      * of the supplied String.
4384      *
4385      * @param strthe String to chomp from, must not be null
4386      * @return String without chomped ending
4387      * @throws NullPointerException if str is null
4388      * @deprecated Use {@link #chomp(String)} instead.
4389      *             Method will be removed in Commons Lang 3.0.
4390      */
4391   public static String chompLast(String str) {
4392         return chompLast(str, "\n");
4393   }
4394
4395   /**
4396      * Remove a value if and only if the String ends with that value.
4397      *
4398      * @param strthe String to chomp from, must not be null
4399      * @param septhe String to chomp, must not be null
4400      * @return String without chomped ending
4401      * @throws NullPointerException if str or sep is null
4402      * @deprecated Use {@link #chomp(String,String)} instead.
4403      *             Method will be removed in Commons Lang 3.0.
4404      */
4405   public static String chompLast(String str, String sep) {
4406         if (str.length() == 0) {
4407             return str;
4408         }
4409         String sub = str.substring(str.length() - sep.length());
4410         if (sep.equals(sub)) {
4411             return str.substring(0, str.length() - sep.length());
4412         }
4413         return str;
4414   }
4415
4416   /**
4417      * Remove everything and return the last value of a supplied String, and
4418      * everything after it from a String.
4419      *
4420      * @param strthe String to chomp from, must not be null
4421      * @param septhe String to chomp, must not be null
4422      * @return String chomped
4423      * @throws NullPointerException if str or sep is null
4424      * @deprecated Use {@link #substringAfterLast(String, String)} instead
4425      *             (although this doesn't include the separator)
4426      *             Method will be removed in Commons Lang 3.0.
4427      */
4428   public static String getChomp(String str, String sep) {
4429         int idx = str.lastIndexOf(sep);
4430         if (idx == str.length() - sep.length()) {
4431             return sep;
4432         } else if (idx != -1) {
4433             return str.substring(idx);
4434         } else {
4435             return EMPTY;
4436         }
4437   }
4438
4439   /**
4440      * Remove the first value of a supplied String, and everything before it
4441      * from a String.
4442      *
4443      * @param strthe String to chomp from, must not be null
4444      * @param septhe String to chomp, must not be null
4445      * @return String without chomped beginning
4446      * @throws NullPointerException if str or sep is null
4447      * @deprecated Use {@link #substringAfter(String,String)} instead.
4448      *             Method will be removed in Commons Lang 3.0.
4449      */
4450   public static String prechomp(String str, String sep) {
4451         int idx = str.indexOf(sep);
4452         if (idx == -1) {
4453             return str;
4454         }            
4455         return str.substring(idx + sep.length());
4456   }
4457
4458   /**
4459      * Remove and return everything before the first value of a
4460      * supplied String from another String.
4461      *
4462      * @param strthe String to chomp from, must not be null
4463      * @param septhe String to chomp, must not be null
4464      * @return String prechomped
4465      * @throws NullPointerException if str or sep is null
4466      * @deprecated Use {@link #substringBefore(String,String)} instead
4467      *             (although this doesn't include the separator).
4468      *             Method will be removed in Commons Lang 3.0.
4469      */
4470   public static String getPrechomp(String str, String sep) {
4471         int idx = str.indexOf(sep);
4472         if (idx == -1) {
4473             return EMPTY;
4474         }
4475         return str.substring(0, idx + sep.length());
4476   }
4477
4478   // Chopping
4479   //-----------------------------------------------------------------------
4480   /**
4481      * Remove the last character from a String.
4482      *
4483      * If the String ends in \r\n, then remove both
4484      * of them.
4485      *
4486      *
4487      * StringUtils.chop(null)          = null
4488      * StringUtils.chop("")            = ""
4489      * StringUtils.chop("abc \r")      = "abc "
4490      * StringUtils.chop("abc\n")       = "abc"
4491      * StringUtils.chop("abc\r\n")   = "abc"
4492      * StringUtils.chop("abc")         = "ab"
4493      * StringUtils.chop("abc\nabc")    = "abc\nab"
4494      * StringUtils.chop("a")         = ""
4495      * StringUtils.chop("\r")          = ""
4496      * StringUtils.chop("\n")          = ""
4497      * StringUtils.chop("\r\n")      = ""
4498      *
4499      *
4500      * @param strthe String to chop last character from, may be null
4501      * @return String without last character, null if null String input
4502      */
4503   public static String chop(String str) {
4504         if (str == null) {
4505             return null;
4506         }
4507         int strLen = str.length();
4508         if (strLen < 2) {
4509             return EMPTY;
4510         }
4511         int lastIdx = strLen - 1;
4512         String ret = str.substring(0, lastIdx);
4513         char last = str.charAt(lastIdx);
4514         if (last == CharUtils.LF) {
4515             if (ret.charAt(lastIdx - 1) == CharUtils.CR) {
4516               return ret.substring(0, lastIdx - 1);
4517             }
4518         }
4519         return ret;
4520   }
4521
4522   /**
4523      * Removes \n from end of a String if it's there.
4524      * If a \r precedes it, then remove that too.
4525      *
4526      * @param strthe String to chop a newline from, must not be null
4527      * @return String without newline
4528      * @throws NullPointerException if str is null
4529      * @deprecated Use {@link #chomp(String)} instead.
4530      *             Method will be removed in Commons Lang 3.0.
4531      */
4532   public static String chopNewline(String str) {
4533         int lastIdx = str.length() - 1;
4534         if (lastIdx"robot".
6002      *
6003      *
6004      * StringUtils.difference(null, null) = null
6005      * StringUtils.difference("", "") = ""
6006      * StringUtils.difference("", "abc") = "abc"
6007      * StringUtils.difference("abc", "") = ""
6008      * StringUtils.difference("abc", "abc") = ""
6009      * StringUtils.difference("ab", "abxyz") = "xyz"
6010      * StringUtils.difference("abcde", "abxyz") = "xyz"
6011      * StringUtils.difference("abcde", "xyz") = "xyz"
6012      *
6013      *
6014      * @param str1the first String, may be null
6015      * @param str2the second String, may be null
6016      * @return the portion of str2 where it differs from str1; returns the
6017      * empty String if they are equal
6018      * @since 2.0
6019      */
6020   public static String difference(String str1, String str2) {
6021         if (str1 == null) {
6022             return str2;
6023         }
6024         if (str2 == null) {
6025             return str1;
6026         }
6027         int at = indexOfDifference(str1, str2);
6028         if (at == INDEX_NOT_FOUND) {
6029             return EMPTY;
6030         }
6031         return str2.substring(at);
6032   }
6033
6034   /**
6035      * Compares two Strings, and returns the index at which the
6036      * Strings begin to differ.
6037      *
6038      * For example,
6039      * indexOfDifference("i am a machine", "i am a robot") -> 7
6040      *
6041      *
6042      * StringUtils.indexOfDifference(null, null) = -1
6043      * StringUtils.indexOfDifference("", "") = -1
6044      * StringUtils.indexOfDifference("", "abc") = 0
6045      * StringUtils.indexOfDifference("abc", "") = 0
6046      * StringUtils.indexOfDifference("abc", "abc") = -1
6047      * StringUtils.indexOfDifference("ab", "abxyz") = 2
6048      * StringUtils.indexOfDifference("abcde", "abxyz") = 2
6049      * StringUtils.indexOfDifference("abcde", "xyz") = 0
6050      *
6051      *
6052      * @param str1the first String, may be null
6053      * @param str2the second String, may be null
6054      * @return the index where str2 and str1 begin to differ; -1 if they are equal
6055      * @since 2.0
6056      */
6057   public static int indexOfDifference(String str1, String str2) {
6058         if (str1 == str2) {
6059             return INDEX_NOT_FOUND;
6060         }
6061         if (str1 == null || str2 == null) {
6062             return 0;
6063         }
6064         int i;
6065         for (i = 0; i < str1.length() && i < str2.length(); ++i) {
6066             if (str1.charAt(i) != str2.charAt(i)) {
6067               break;
6068             }
6069         }
6070         if (i < str2.length() || i < str1.length()) {
6071             return i;
6072         }
6073         return INDEX_NOT_FOUND;
6074   }
6075
6076   /**
6077      * Compares all Strings in an array and returns the index at which the
6078      * Strings begin to differ.
6079      *
6080      * For example,
6081      * indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7
6082      *
6083      *
6084      * StringUtils.indexOfDifference(null) = -1
6085      * StringUtils.indexOfDifference(new String[] {}) = -1
6086      * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
6087      * StringUtils.indexOfDifference(new String[] {null, null}) = -1
6088      * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
6089      * StringUtils.indexOfDifference(new String[] {"", null}) = 0
6090      * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
6091      * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
6092      * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
6093      * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
6094      * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
6095      * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
6096      * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
6097      * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
6098      * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
6099      * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
6100      * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
6101      *
6102      *
6103      * @param strsarray of strings, entries may be null
6104      * @return the index where the strings begin to differ; -1 if they are all equal
6105      * @since 2.4
6106      */
6107   public static int indexOfDifference(String[] strs) {
6108         if (strs == null || strs.lengthm) {
6286             // swap the input strings to consume less memory
6287             String tmp = s;
6288             s = t;
6289             t = tmp;
6290             n = m;
6291             m = t.length();
6292         }
6293
6294         int p[] = new int; //'previous' cost array, horizontally
6295         int d[] = new int; // cost array, horizontally
6296         int _d[]; //placeholder to assist in swapping p and d
6297
6298         // indexes into strings s and t
6299         int i; // iterates through s
6300         int j; // iterates through t
6301
6302         char t_j; // jth character of t
6303
6304         int cost; // cost
6305
6306         for (i = 0; i
页: [1]
查看完整版本: java开发_org.apache.commons.lang.StringUtils工具类源码