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 <= 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 <= 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 <= 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 <= 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 <= 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 <= 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 <= 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 <= 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("hello", "ho", "jy") = 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 "\n",
4297 * "\r", or "\r\n".
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 "\n" 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]