/[Apache-SVN]/commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java
ViewVC logotype

Contents of /commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 830042 - (show annotations)
Tue Oct 27 01:14:57 2009 UTC (3 weeks, 5 days ago) by scolebourne
File size: 226681 byte(s)
LANG-548 - Use Iterable instead of Collection
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.Iterator;
21 import java.util.List;
22 import java.util.Locale;
23
24 /**
25 * <p>Operations on {@link java.lang.String} that are
26 * <code>null</code> safe.</p>
27 *
28 * <ul>
29 * <li><b>IsEmpty/IsBlank</b>
30 * - checks if a String contains text</li>
31 * <li><b>Trim/Strip</b>
32 * - removes leading and trailing whitespace</li>
33 * <li><b>Equals</b>
34 * - compares two strings null-safe</li>
35 * <li><b>startsWith</b>
36 * - check if a String starts with a prefix null-safe</li>
37 * <li><b>endsWith</b>
38 * - check if a String ends with a suffix null-safe</li>
39 * <li><b>IndexOf/LastIndexOf/Contains</b>
40 * - null-safe index-of checks
41 * <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
42 * - index-of any of a set of Strings</li>
43 * <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
44 * - does String contains only/none/any of these characters</li>
45 * <li><b>Substring/Left/Right/Mid</b>
46 * - null-safe substring extractions</li>
47 * <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
48 * - substring extraction relative to other strings</li>
49 * <li><b>Split/Join</b>
50 * - splits a String into an array of substrings and vice versa</li>
51 * <li><b>Remove/Delete</b>
52 * - removes part of a String</li>
53 * <li><b>Replace/Overlay</b>
54 * - Searches a String and replaces one String with another</li>
55 * <li><b>Chomp/Chop</b>
56 * - removes the last part of a String</li>
57 * <li><b>LeftPad/RightPad/Center/Repeat</b>
58 * - pads a String</li>
59 * <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
60 * - changes the case of a String</li>
61 * <li><b>CountMatches</b>
62 * - counts the number of occurrences of one String in another</li>
63 * <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
64 * - checks the characters in a String</li>
65 * <li><b>DefaultString</b>
66 * - protects against a null input String</li>
67 * <li><b>Reverse/ReverseDelimited</b>
68 * - reverses a String</li>
69 * <li><b>Abbreviate</b>
70 * - abbreviates a string using ellipsis</li>
71 * <li><b>Difference</b>
72 * - compares Strings and reports on their differences</li>
73 * <li><b>LevensteinDistance</b>
74 * - the number of changes needed to change one String into another</li>
75 * </ul>
76 *
77 * <p>The <code>StringUtils</code> class defines certain words related to
78 * String handling.</p>
79 *
80 * <ul>
81 * <li>null - <code>null</code></li>
82 * <li>empty - a zero-length string (<code>""</code>)</li>
83 * <li>space - the space character (<code>' '</code>, char 32)</li>
84 * <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li>
85 * <li>trim - the characters &lt;= 32 as in {@link String#trim()}</li>
86 * </ul>
87 *
88 * <p><code>StringUtils</code> handles <code>null</code> input Strings quietly.
89 * That is to say that a <code>null</code> input will return <code>null</code>.
90 * Where a <code>boolean</code> or <code>int</code> is being returned
91 * details vary by method.</p>
92 *
93 * <p>A side effect of the <code>null</code> handling is that a
94 * <code>NullPointerException</code> should be considered a bug in
95 * <code>StringUtils</code>.</p>
96 *
97 * <p>Methods in this class give sample code to explain their operation.
98 * The symbol <code>*</code> is used to indicate any input including <code>null</code>.</p>
99 *
100 * @see java.lang.String
101 * @author Apache Software Foundation
102 * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</a>
103 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
104 * @author Daniel L. Rall
105 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
106 * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
107 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
108 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
109 * @author Holger Krauth
110 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
111 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
112 * @author Arun Mammen Thomas
113 * @author Gary Gregory
114 * @author Phil Steitz
115 * @author Al Chou
116 * @author Michael Davey
117 * @author Reuben Sivan
118 * @author Chris Hyzer
119 * @author Scott Johnson
120 * @since 1.0
121 * @version $Id$
122 */
123 //@Immutable
124 public class StringUtils {
125 // Performance testing notes (JDK 1.4, Jul03, scolebourne)
126 // Whitespace:
127 // Character.isWhitespace() is faster than WHITESPACE.indexOf()
128 // where WHITESPACE is a string of all whitespace characters
129 //
130 // Character access:
131 // String.charAt(n) versus toCharArray(), then array[n]
132 // String.charAt(n) is about 15% worse for a 10K string
133 // They are about equal for a length 50 string
134 // String.charAt(n) is about 4 times better for a length 3 string
135 // String.charAt(n) is best bet overall
136 //
137 // Append:
138 // String.concat about twice as fast as StringBuffer.append
139 // (not sure who tested this)
140
141 /**
142 * The empty String <code>""</code>.
143 * @since 2.0
144 */
145 public static final String EMPTY = "";
146
147 /**
148 * Represents a failed index search.
149 * @since 2.1
150 */
151 public static final int INDEX_NOT_FOUND = -1;
152
153 /**
154 * <p>The maximum size to which the padding constant(s) can expand.</p>
155 */
156 private static final int PAD_LIMIT = 8192;
157
158 /**
159 * <p><code>StringUtils</code> instances should NOT be constructed in
160 * standard programming. Instead, the class should be used as
161 * <code>StringUtils.trim(" foo ");</code>.</p>
162 *
163 * <p>This constructor is public to permit tools that require a JavaBean
164 * instance to operate.</p>
165 */
166 public StringUtils() {
167 super();
168 }
169
170 // Empty checks
171 //-----------------------------------------------------------------------
172 /**
173 * <p>Checks if a String is empty ("") or null.</p>
174 *
175 * <pre>
176 * StringUtils.isEmpty(null) = true
177 * StringUtils.isEmpty("") = true
178 * StringUtils.isEmpty(" ") = false
179 * StringUtils.isEmpty("bob") = false
180 * StringUtils.isEmpty(" bob ") = false
181 * </pre>
182 *
183 * <p>NOTE: This method changed in Lang version 2.0.
184 * It no longer trims the String.
185 * That functionality is available in isBlank().</p>
186 *
187 * @param str the String to check, may be null
188 * @return <code>true</code> if the String is empty or null
189 */
190 public static boolean isEmpty(CharSequence str) {
191 return str == null || str.length() == 0;
192 }
193
194 /**
195 * <p>Checks if a String is not empty ("") and not null.</p>
196 *
197 * <pre>
198 * StringUtils.isNotEmpty(null) = false
199 * StringUtils.isNotEmpty("") = false
200 * StringUtils.isNotEmpty(" ") = true
201 * StringUtils.isNotEmpty("bob") = true
202 * StringUtils.isNotEmpty(" bob ") = true
203 * </pre>
204 *
205 * @param str the String to check, may be null
206 * @return <code>true</code> if the String is not empty and not null
207 */
208 public static boolean isNotEmpty(CharSequence str) {
209 return !StringUtils.isEmpty(str);
210 }
211
212 /**
213 * <p>Checks if a String is whitespace, empty ("") or null.</p>
214 *
215 * <pre>
216 * StringUtils.isBlank(null) = true
217 * StringUtils.isBlank("") = true
218 * StringUtils.isBlank(" ") = true
219 * StringUtils.isBlank("bob") = false
220 * StringUtils.isBlank(" bob ") = false
221 * </pre>
222 *
223 * @param str the String to check, may be null
224 * @return <code>true</code> if the String is null, empty or whitespace
225 * @since 2.0
226 */
227 public static boolean isBlank(CharSequence str) {
228 int strLen;
229 if (str == null || (strLen = str.length()) == 0) {
230 return true;
231 }
232 for (int i = 0; i < strLen; i++) {
233 if ((Character.isWhitespace(str.charAt(i)) == false)) {
234 return false;
235 }
236 }
237 return true;
238 }
239
240 /**
241 * <p>Checks if a String is not empty (""), not null and not whitespace only.</p>
242 *
243 * <pre>
244 * StringUtils.isNotBlank(null) = false
245 * StringUtils.isNotBlank("") = false
246 * StringUtils.isNotBlank(" ") = false
247 * StringUtils.isNotBlank("bob") = true
248 * StringUtils.isNotBlank(" bob ") = true
249 * </pre>
250 *
251 * @param str the String to check, may be null
252 * @return <code>true</code> if the String is
253 * not empty and not null and not whitespace
254 * @since 2.0
255 */
256 public static boolean isNotBlank(CharSequence str) {
257 return !StringUtils.isBlank(str);
258 }
259
260 // Trim
261 //-----------------------------------------------------------------------
262 /**
263 * <p>Removes control characters (char &lt;= 32) from both
264 * ends of this String, handling <code>null</code> by returning
265 * <code>null</code>.</p>
266 *
267 * <p>The String is trimmed using {@link String#trim()}.
268 * Trim removes start and end characters &lt;= 32.
269 * To strip whitespace use {@link #strip(String)}.</p>
270 *
271 * <p>To trim your choice of characters, use the
272 * {@link #strip(String, String)} methods.</p>
273 *
274 * <pre>
275 * StringUtils.trim(null) = null
276 * StringUtils.trim("") = ""
277 * StringUtils.trim(" ") = ""
278 * StringUtils.trim("abc") = "abc"
279 * StringUtils.trim(" abc ") = "abc"
280 * </pre>
281 *
282 * @param str the String to be trimmed, may be null
283 * @return the trimmed string, <code>null</code> if null String input
284 */
285 public static String trim(String str) {
286 return str == null ? null : str.trim();
287 }
288
289 /**
290 * <p>Removes control characters (char &lt;= 32) from both
291 * ends of this String returning <code>null</code> if the String is
292 * empty ("") after the trim or if it is <code>null</code>.
293 *
294 * <p>The String is trimmed using {@link String#trim()}.
295 * Trim removes start and end characters &lt;= 32.
296 * To strip whitespace use {@link #stripToNull(String)}.</p>
297 *
298 * <pre>
299 * StringUtils.trimToNull(null) = null
300 * StringUtils.trimToNull("") = null
301 * StringUtils.trimToNull(" ") = null
302 * StringUtils.trimToNull("abc") = "abc"
303 * StringUtils.trimToNull(" abc ") = "abc"
304 * </pre>
305 *
306 * @param str the String to be trimmed, may be null
307 * @return the trimmed String,
308 * <code>null</code> if only chars &lt;= 32, empty or null String input
309 * @since 2.0
310 */
311 public static String trimToNull(String str) {
312 String ts = trim(str);
313 return isEmpty(ts) ? null : ts;
314 }
315
316 /**
317 * <p>Removes control characters (char &lt;= 32) from both
318 * ends of this String returning an empty String ("") if the String
319 * is empty ("") after the trim or if it is <code>null</code>.
320 *
321 * <p>The String is trimmed using {@link String#trim()}.
322 * Trim removes start and end characters &lt;= 32.
323 * To strip whitespace use {@link #stripToEmpty(String)}.</p>
324 *
325 * <pre>
326 * StringUtils.trimToEmpty(null) = ""
327 * StringUtils.trimToEmpty("") = ""
328 * StringUtils.trimToEmpty(" ") = ""
329 * StringUtils.trimToEmpty("abc") = "abc"
330 * StringUtils.trimToEmpty(" abc ") = "abc"
331 * </pre>
332 *
333 * @param str the String to be trimmed, may be null
334 * @return the trimmed String, or an empty String if <code>null</code> input
335 * @since 2.0
336 */
337 public static String trimToEmpty(String str) {
338 return str == null ? EMPTY : str.trim();
339 }
340
341 // Stripping
342 //-----------------------------------------------------------------------
343 /**
344 * <p>Strips whitespace from the start and end of a String.</p>
345 *
346 * <p>This is similar to {@link #trim(String)} but removes whitespace.
347 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
348 *
349 * <p>A <code>null</code> input String returns <code>null</code>.</p>
350 *
351 * <pre>
352 * StringUtils.strip(null) = null
353 * StringUtils.strip("") = ""
354 * StringUtils.strip(" ") = ""
355 * StringUtils.strip("abc") = "abc"
356 * StringUtils.strip(" abc") = "abc"
357 * StringUtils.strip("abc ") = "abc"
358 * StringUtils.strip(" abc ") = "abc"
359 * StringUtils.strip(" ab c ") = "ab c"
360 * </pre>
361 *
362 * @param str the String to remove whitespace from, may be null
363 * @return the stripped String, <code>null</code> if null String input
364 */
365 public static String strip(String str) {
366 return strip(str, null);
367 }
368
369 /**
370 * <p>Strips whitespace from the start and end of a String returning
371 * <code>null</code> if the String is empty ("") after the strip.</p>
372 *
373 * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.
374 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
375 *
376 * <pre>
377 * StringUtils.stripToNull(null) = null
378 * StringUtils.stripToNull("") = null
379 * StringUtils.stripToNull(" ") = null
380 * StringUtils.stripToNull("abc") = "abc"
381 * StringUtils.stripToNull(" abc") = "abc"
382 * StringUtils.stripToNull("abc ") = "abc"
383 * StringUtils.stripToNull(" abc ") = "abc"
384 * StringUtils.stripToNull(" ab c ") = "ab c"
385 * </pre>
386 *
387 * @param str the String to be stripped, may be null
388 * @return the stripped String,
389 * <code>null</code> if whitespace, empty or null String input
390 * @since 2.0
391 */
392 public static String stripToNull(String str) {
393 if (str == null) {
394 return null;
395 }
396 str = strip(str, null);
397 return str.length() == 0 ? null : str;
398 }
399
400 /**
401 * <p>Strips whitespace from the start and end of a String returning
402 * an empty String if <code>null</code> input.</p>
403 *
404 * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.
405 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
406 *
407 * <pre>
408 * StringUtils.stripToEmpty(null) = ""
409 * StringUtils.stripToEmpty("") = ""
410 * StringUtils.stripToEmpty(" ") = ""
411 * StringUtils.stripToEmpty("abc") = "abc"
412 * StringUtils.stripToEmpty(" abc") = "abc"
413 * StringUtils.stripToEmpty("abc ") = "abc"
414 * StringUtils.stripToEmpty(" abc ") = "abc"
415 * StringUtils.stripToEmpty(" ab c ") = "ab c"
416 * </pre>
417 *
418 * @param str the String to be stripped, may be null
419 * @return the trimmed String, or an empty String if <code>null</code> input
420 * @since 2.0
421 */
422 public static String stripToEmpty(String str) {
423 return str == null ? EMPTY : strip(str, null);
424 }
425
426 /**
427 * <p>Strips any of a set of characters from the start and end of a String.
428 * This is similar to {@link String#trim()} but allows the characters
429 * to be stripped to be controlled.</p>
430 *
431 * <p>A <code>null</code> input String returns <code>null</code>.
432 * An empty string ("") input returns the empty string.</p>
433 *
434 * <p>If the stripChars String is <code>null</code>, whitespace is
435 * stripped as defined by {@link Character#isWhitespace(char)}.
436 * Alternatively use {@link #strip(String)}.</p>
437 *
438 * <pre>
439 * StringUtils.strip(null, *) = null
440 * StringUtils.strip("", *) = ""
441 * StringUtils.strip("abc", null) = "abc"
442 * StringUtils.strip(" abc", null) = "abc"
443 * StringUtils.strip("abc ", null) = "abc"
444 * StringUtils.strip(" abc ", null) = "abc"
445 * StringUtils.strip(" abcyx", "xyz") = " abc"
446 * </pre>
447 *
448 * @param str the String to remove characters from, may be null
449 * @param stripChars the characters to remove, null treated as whitespace
450 * @return the stripped String, <code>null</code> if null String input
451 */
452 public static String strip(String str, String stripChars) {
453 if (isEmpty(str)) {
454 return str;
455 }
456 str = stripStart(str, stripChars);
457 return stripEnd(str, stripChars);
458 }
459
460 /**
461 * <p>Strips any of a set of characters from the start of a String.</p>
462 *
463 * <p>A <code>null</code> input String returns <code>null</code>.
464 * An empty string ("") input returns the empty string.</p>
465 *
466 * <p>If the stripChars String is <code>null</code>, whitespace is
467 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
468 *
469 * <pre>
470 * StringUtils.stripStart(null, *) = null
471 * StringUtils.stripStart("", *) = ""
472 * StringUtils.stripStart("abc", "") = "abc"
473 * StringUtils.stripStart("abc", null) = "abc"
474 * StringUtils.stripStart(" abc", null) = "abc"
475 * StringUtils.stripStart("abc ", null) = "abc "
476 * StringUtils.stripStart(" abc ", null) = "abc "
477 * StringUtils.stripStart("yxabc ", "xyz") = "abc "
478 * </pre>
479 *
480 * @param str the String to remove characters from, may be null
481 * @param stripChars the characters to remove, null treated as whitespace
482 * @return the stripped String, <code>null</code> if null String input
483 */
484 public static String stripStart(String str, String stripChars) {
485 int strLen;
486 if (str == null || (strLen = str.length()) == 0) {
487 return str;
488 }
489 int start = 0;
490 if (stripChars == null) {
491 while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {
492 start++;
493 }
494 } else if (stripChars.length() == 0) {
495 return str;
496 } else {
497 while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) {
498 start++;
499 }
500 }
501 return str.substring(start);
502 }
503
504 /**
505 * <p>Strips any of a set of characters from the end of a String.</p>
506 *
507 * <p>A <code>null</code> input String returns <code>null</code>.
508 * An empty string ("") input returns the empty string.</p>
509 *
510 * <p>If the stripChars String is <code>null</code>, whitespace is
511 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
512 *
513 * <pre>
514 * StringUtils.stripEnd(null, *) = null
515 * StringUtils.stripEnd("", *) = ""
516 * StringUtils.stripEnd("abc", "") = "abc"
517 * StringUtils.stripEnd("abc", null) = "abc"
518 * StringUtils.stripEnd(" abc", null) = " abc"
519 * StringUtils.stripEnd("abc ", null) = "abc"
520 * StringUtils.stripEnd(" abc ", null) = " abc"
521 * StringUtils.stripEnd(" abcyx", "xyz") = " abc"
522 * </pre>
523 *
524 * @param str the String to remove characters from, may be null
525 * @param stripChars the characters to remove, null treated as whitespace
526 * @return the stripped String, <code>null</code> if null String input
527 */
528 public static String stripEnd(String str, String stripChars) {
529 int end;
530 if (str == null || (end = str.length()) == 0) {
531 return str;
532 }
533
534 if (stripChars == null) {
535 while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
536 end--;
537 }
538 } else if (stripChars.length() == 0) {
539 return str;
540 } else {
541 while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
542 end--;
543 }
544 }
545 return str.substring(0, end);
546 }
547
548 // StripAll
549 //-----------------------------------------------------------------------
550 /**
551 * <p>Strips whitespace from the start and end of every String in an array.
552 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
553 *
554 * <p>A new array is returned each time, except for length zero.
555 * A <code>null</code> array will return <code>null</code>.
556 * An empty array will return itself.
557 * A <code>null</code> array entry will be ignored.</p>
558 *
559 * <pre>
560 * StringUtils.stripAll(null) = null
561 * StringUtils.stripAll([]) = []
562 * StringUtils.stripAll(["abc", " abc"]) = ["abc", "abc"]
563 * StringUtils.stripAll(["abc ", null]) = ["abc", null]
564 * </pre>
565 *
566 * @param strs the array to remove whitespace from, may be null
567 * @return the stripped Strings, <code>null</code> if null array input
568 */
569 public static String[] stripAll(String[] strs) {
570 return stripAll(strs, null);
571 }
572
573 /**
574 * <p>Strips any of a set of characters from the start and end of every
575 * String in an array.</p>
576 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
577 *
578 * <p>A new array is returned each time, except for length zero.
579 * A <code>null</code> array will return <code>null</code>.
580 * An empty array will return itself.
581 * A <code>null</code> array entry will be ignored.
582 * A <code>null</code> stripChars will strip whitespace as defined by
583 * {@link Character#isWhitespace(char)}.</p>
584 *
585 * <pre>
586 * StringUtils.stripAll(null, *) = null
587 * StringUtils.stripAll([], *) = []
588 * StringUtils.stripAll(["abc", " abc"], null) = ["abc", "abc"]
589 * StringUtils.stripAll(["abc ", null], null) = ["abc", null]
590 * StringUtils.stripAll(["abc ", null], "yz") = ["abc ", null]
591 * StringUtils.stripAll(["yabcz", null], "yz") = ["abc", null]
592 * </pre>
593 *
594 * @param strs the array to remove characters from, may be null
595 * @param stripChars the characters to remove, null treated as whitespace
596 * @return the stripped Strings, <code>null</code> if null array input
597 */
598 public static String[] stripAll(String[] strs, String stripChars) {
599 int strsLen;
600 if (strs == null || (strsLen = strs.length) == 0) {
601 return strs;
602 }
603 String[] newArr = new String[strsLen];
604 for (int i = 0; i < strsLen; i++) {
605 newArr[i] = strip(strs[i], stripChars);
606 }
607 return newArr;
608 }
609
610 // Equals
611 //-----------------------------------------------------------------------
612 /**
613 * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
614 *
615 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
616 * references are considered to be equal. The comparison is case sensitive.</p>
617 *
618 * <pre>
619 * StringUtils.equals(null, null) = true
620 * StringUtils.equals(null, "abc") = false
621 * StringUtils.equals("abc", null) = false
622 * StringUtils.equals("abc", "abc") = true
623 * StringUtils.equals("abc", "ABC") = false
624 * </pre>
625 *
626 * @see java.lang.String#equals(Object)
627 * @param str1 the first String, may be null
628 * @param str2 the second String, may be null
629 * @return <code>true</code> if the Strings are equal, case sensitive, or
630 * both <code>null</code>
631 */
632 public static boolean equals(String str1, String str2) {
633 return str1 == null ? str2 == null : str1.equals(str2);
634 }
635
636 /**
637 * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring
638 * the case.</p>
639 *
640 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
641 * references are considered equal. Comparison is case insensitive.</p>
642 *
643 * <pre>
644 * StringUtils.equalsIgnoreCase(null, null) = true
645 * StringUtils.equalsIgnoreCase(null, "abc") = false
646 * StringUtils.equalsIgnoreCase("abc", null) = false
647 * StringUtils.equalsIgnoreCase("abc", "abc") = true
648 * StringUtils.equalsIgnoreCase("abc", "ABC") = true
649 * </pre>
650 *
651 * @see java.lang.String#equalsIgnoreCase(String)
652 * @param str1 the first String, may be null
653 * @param str2 the second String, may be null
654 * @return <code>true</code> if the Strings are equal, case insensitive, or
655 * both <code>null</code>
656 */
657 public static boolean equalsIgnoreCase(String str1, String str2) {
658 return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
659 }
660
661 // IndexOf
662 //-----------------------------------------------------------------------
663 /**
664 * <p>Finds the first index within a String, handling <code>null</code>.
665 * This method uses {@link String#indexOf(int)}.</p>
666 *
667 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p>
668 *
669 * <pre>
670 * StringUtils.indexOf(null, *) = -1
671 * StringUtils.indexOf("", *) = -1
672 * StringUtils.indexOf("aabaabaa", 'a') = 0
673 * StringUtils.indexOf("aabaabaa", 'b') = 2
674 * </pre>
675 *
676 * @param str the String to check, may be null
677 * @param searchChar the character to find
678 * @return the first index of the search character,
679 * -1 if no match or <code>null</code> string input
680 * @since 2.0
681 */
682 public static int indexOf(String str, char searchChar) {
683 if (isEmpty(str)) {
684 return -1;
685 }
686 return str.indexOf(searchChar);
687 }
688
689 /**
690 * <p>Finds the first index within a String from a start position,
691 * handling <code>null</code>.
692 * This method uses {@link String#indexOf(int, int)}.</p>
693 *
694 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
695 * A negative start position is treated as zero.
696 * A start position greater than the string length returns <code>-1</code>.</p>
697 *
698 * <pre>
699 * StringUtils.indexOf(null, *, *) = -1
700 * StringUtils.indexOf("", *, *) = -1
701 * StringUtils.indexOf("aabaabaa", 'b', 0) = 2
702 * StringUtils.indexOf("aabaabaa", 'b', 3) = 5
703 * StringUtils.indexOf("aabaabaa", 'b', 9) = -1
704 * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
705 * </pre>
706 *
707 * @param str the String to check, may be null
708 * @param searchChar the character to find
709 * @param startPos the start position, negative treated as zero
710 * @return the first index of the search character,
711 * -1 if no match or <code>null</code> string input
712 * @since 2.0
713 */
714 public static int indexOf(String str, char searchChar, int startPos) {
715 if (isEmpty(str)) {
716 return -1;
717 }
718 return str.indexOf(searchChar, startPos);
719 }
720
721 /**
722 * <p>Finds the first index within a String, handling <code>null</code>.
723 * This method uses {@link String#indexOf(String)}.</p>
724 *
725 * <p>A <code>null</code> String will return <code>-1</code>.</p>
726 *
727 * <pre>
728 * StringUtils.indexOf(null, *) = -1
729 * StringUtils.indexOf(*, null) = -1
730 * StringUtils.indexOf("", "") = 0
731 * StringUtils.indexOf("aabaabaa", "a") = 0
732 * StringUtils.indexOf("aabaabaa", "b") = 2
733 * StringUtils.indexOf("aabaabaa", "ab") = 1
734 * StringUtils.indexOf("aabaabaa", "") = 0
735 * </pre>
736 *
737 * @param str the String to check, may be null
738 * @param searchStr the String to find, may be null
739 * @return the first index of the search String,
740 * -1 if no match or <code>null</code> string input
741 * @since 2.0
742 */
743 public static int indexOf(String str, String searchStr) {
744 if (str == null || searchStr == null) {
745 return -1;
746 }
747 return str.indexOf(searchStr);
748 }
749
750 /**
751 * <p>Finds the n-th index within a String, handling <code>null</code>.
752 * This method uses {@link String#indexOf(String)}.</p>
753 *
754 * <p>A <code>null</code> String will return <code>-1</code>.</p>
755 *
756 * <pre>
757 * StringUtils.ordinalIndexOf(null, *, *) = -1
758 * StringUtils.ordinalIndexOf(*, null, *) = -1
759 * StringUtils.ordinalIndexOf("", "", *) = 0
760 * StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0
761 * StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1
762 * StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2
763 * StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5
764 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
765 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
766 * StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0
767 * StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0
768 * </pre>
769 *
770 * @param str the String to check, may be null
771 * @param searchStr the String to find, may be null
772 * @param ordinal the n-th <code>searchStr</code> to find
773 * @return the n-th index of the search String,
774 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input
775 * @since 2.1
776 */
777 public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
778 if (str == null || searchStr == null || ordinal <= 0) {
779 return INDEX_NOT_FOUND;
780 }
781 if (searchStr.length() == 0) {
782 return 0;
783 }
784 int found = 0;
785 int index = INDEX_NOT_FOUND;
786 do {
787 index = str.indexOf(searchStr, index + 1);
788 if (index < 0) {
789 return index;
790 }
791 found++;
792 } while (found < ordinal);
793 return index;
794 }
795
796 /**
797 * <p>Finds the first index within a String, handling <code>null</code>.
798 * This method uses {@link String#indexOf(String, int)}.</p>
799 *
800 * <p>A <code>null</code> String will return <code>-1</code>.
801 * A negative start position is treated as zero.
802 * An empty ("") search String always matches.
803 * A start position greater than the string length only matches
804 * an empty search String.</p>
805 *
806 * <pre>
807 * StringUtils.indexOf(null, *, *) = -1
808 * StringUtils.indexOf(*, null, *) = -1
809 * StringUtils.indexOf("", "", 0) = 0
810 * StringUtils.indexOf("aabaabaa", "a", 0) = 0
811 * StringUtils.indexOf("aabaabaa", "b", 0) = 2
812 * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
813 * StringUtils.indexOf("aabaabaa", "b", 3) = 5
814 * StringUtils.indexOf("aabaabaa", "b", 9) = -1
815 * StringUtils.indexOf("aabaabaa", "b", -1) = 2
816 * StringUtils.indexOf("aabaabaa", "", 2) = 2
817 * StringUtils.indexOf("abc", "", 9) = 3
818 * </pre>
819 *
820 * @param str the String to check, may be null
821 * @param searchStr the String to find, may be null
822 * @param startPos the start position, negative treated as zero
823 * @return the first index of the search String,
824 * -1 if no match or <code>null</code> string input
825 * @since 2.0
826 */
827 public static int indexOf(String str, String searchStr, int startPos) {
828 if (str == null || searchStr == null) {
829 return -1;
830 }
831 // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence
832 if (searchStr.length() == 0 && startPos >= str.length()) {
833 return str.length();
834 }
835 return str.indexOf(searchStr, startPos);
836 }
837
838 // LastIndexOf
839 //-----------------------------------------------------------------------
840 /**
841 * <p>Finds the last index within a String, handling <code>null</code>.
842 * This method uses {@link String#lastIndexOf(int)}.</p>
843 *
844 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p>
845 *
846 * <pre>
847 * StringUtils.lastIndexOf(null, *) = -1
848 * StringUtils.lastIndexOf("", *) = -1
849 * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
850 * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
851 * </pre>
852 *
853 * @param str the String to check, may be null
854 * @param searchChar the character to find
855 * @return the last index of the search character,
856 * -1 if no match or <code>null</code> string input
857 * @since 2.0
858 */
859 public static int lastIndexOf(String str, char searchChar) {
860 if (isEmpty(str)) {
861 return -1;
862 }
863 return str.lastIndexOf(searchChar);
864 }
865
866 /**
867 * <p>Finds the last index within a String from a start position,
868 * handling <code>null</code>.
869 * This method uses {@link String#lastIndexOf(int, int)}.</p>
870 *
871 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
872 * A negative start position returns <code>-1</code>.
873 * A start position greater than the string length searches the whole string.</p>
874 *
875 * <pre>
876 * StringUtils.lastIndexOf(null, *, *) = -1
877 * StringUtils.lastIndexOf("", *, *) = -1
878 * StringUtils.lastIndexOf("aabaabaa", 'b', 8) = 5
879 * StringUtils.lastIndexOf("aabaabaa", 'b', 4) = 2
880 * StringUtils.lastIndexOf("aabaabaa", 'b', 0) = -1
881 * StringUtils.lastIndexOf("aabaabaa", 'b', 9) = 5
882 * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
883 * StringUtils.lastIndexOf("aabaabaa", 'a', 0) = 0
884 * </pre>
885 *
886 * @param str the String to check, may be null
887 * @param searchChar the character to find
888 * @param startPos the start position
889 * @return the last index of the search character,
890 * -1 if no match or <code>null</code> string input
891 * @since 2.0
892 */
893 public static int lastIndexOf(String str, char searchChar, int startPos) {
894 if (isEmpty(str)) {
895 return -1;
896 }
897 return str.lastIndexOf(searchChar, startPos);
898 }
899
900 /**
901 * <p>Finds the last index within a String, handling <code>null</code>.
902 * This method uses {@link String#lastIndexOf(String)}.</p>
903 *
904 * <p>A <code>null</code> String will return <code>-1</code>.</p>
905 *
906 * <pre>
907 * StringUtils.lastIndexOf(null, *) = -1
908 * StringUtils.lastIndexOf(*, null) = -1
909 * StringUtils.lastIndexOf("", "") = 0
910 * StringUtils.lastIndexOf("aabaabaa", "a") = 0
911 * StringUtils.lastIndexOf("aabaabaa", "b") = 2
912 * StringUtils.lastIndexOf("aabaabaa", "ab") = 1
913 * StringUtils.lastIndexOf("aabaabaa", "") = 8
914 * </pre>
915 *
916 * @param str the String to check, may be null
917 * @param searchStr the String to find, may be null
918 * @return the last index of the search String,
919 * -1 if no match or <code>null</code> string input
920 * @since 2.0
921 */
922 public static int lastIndexOf(String str, String searchStr) {
923 if (str == null || searchStr == null) {
924 return -1;
925 }
926 return str.lastIndexOf(searchStr);
927 }
928
929 /**
930 * <p>Finds the first index within a String, handling <code>null</code>.
931 * This method uses {@link String#lastIndexOf(String, int)}.</p>
932 *
933 * <p>A <code>null</code> String will return <code>-1</code>.
934 * A negative start position returns <code>-1</code>.
935 * An empty ("") search String always matches unless the start position is negative.
936 * A start position greater than the string length searches the whole string.</p>
937 *
938 * <pre>
939 * StringUtils.lastIndexOf(null, *, *) = -1
940 * StringUtils.lastIndexOf(*, null, *) = -1
941 * StringUtils.lastIndexOf("aabaabaa", "a", 8) = 7
942 * StringUtils.lastIndexOf("aabaabaa", "b", 8) = 5
943 * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
944 * StringUtils.lastIndexOf("aabaabaa", "b", 9) = 5
945 * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
946 * StringUtils.lastIndexOf("aabaabaa", "a", 0) = 0
947 * StringUtils.lastIndexOf("aabaabaa", "b", 0) = -1
948 * </pre>
949 *
950 * @param str the String to check, may be null
951 * @param searchStr the String to find, may be null
952 * @param startPos the start position, negative treated as zero
953 * @return the first index of the search String,
954 * -1 if no match or <code>null</code> string input
955 * @since 2.0
956 */
957 public static int lastIndexOf(String str, String searchStr, int startPos) {
958 if (str == null || searchStr == null) {
959 return -1;
960 }
961 return str.lastIndexOf(searchStr, startPos);
962 }
963
964 // Contains
965 //-----------------------------------------------------------------------
966 /**
967 * <p>Checks if String contains a search character, handling <code>null</code>.
968 * This method uses {@link String#indexOf(int)}.</p>
969 *
970 * <p>A <code>null</code> or empty ("") String will return <code>false</code>.</p>
971 *
972 * <pre>
973 * StringUtils.contains(null, *) = false
974 * StringUtils.contains("", *) = false
975 * StringUtils.contains("abc", 'a') = true
976 * StringUtils.contains("abc", 'z') = false
977 * </pre>
978 *
979 * @param str the String to check, may be null
980 * @param searchChar the character to find
981 * @return true if the String contains the search character,
982 * false if not or <code>null</code> string input
983 * @since 2.0
984 */
985 public static boolean contains(String str, char searchChar) {
986 if (isEmpty(str)) {
987 return false;
988 }
989 return str.indexOf(searchChar) >= 0;
990 }
991
992 /**
993 * <p>Checks if String contains a search String, handling <code>null</code>.
994 * This method uses {@link String#indexOf(String)}.</p>
995 *
996 * <p>A <code>null</code> String will return <code>false</code>.</p>
997 *
998 * <pre>
999 * StringUtils.contains(null, *) = false
1000 * StringUtils.contains(*, null) = false
1001 * StringUtils.contains("", "") = true
1002 * StringUtils.contains("abc", "") = true
1003 * StringUtils.contains("abc", "a") = true
1004 * StringUtils.contains("abc", "z") = false
1005 * </pre>
1006 *
1007 * @param str the String to check, may be null
1008 * @param searchStr the String to find, may be null
1009 * @return true if the String contains the search String,
1010 * false if not or <code>null</code> string input
1011 * @since 2.0
1012 */
1013 public static boolean contains(String str, String searchStr) {
1014 if (str == null || searchStr == null) {
1015 return false;
1016 }
1017 return str.indexOf(searchStr) >= 0;
1018 }
1019
1020 /**
1021 * <p>Checks if String contains a search String irrespective of case,
1022 * handling <code>null</code>. Case-insensitivity is defined as by
1023 * {@link String#equalsIgnoreCase(String)}.
1024 *
1025 * <p>A <code>null</code> String will return <code>false</code>.</p>
1026 *
1027 * <pre>
1028 * StringUtils.contains(null, *) = false
1029 * StringUtils.contains(*, null) = false
1030 * StringUtils.contains("", "") = true
1031 * StringUtils.contains("abc", "") = true
1032 * StringUtils.contains("abc", "a") = true
1033 * StringUtils.contains("abc", "z") = false
1034 * StringUtils.contains("abc", "A") = true
1035 * StringUtils.contains("abc", "Z") = false
1036 * </pre>
1037 *
1038 * @param str the String to check, may be null
1039 * @param searchStr the String to find, may be null
1040 * @return true if the String contains the search String irrespective of
1041 * case or false if not or <code>null</code> string input
1042 */
1043 public static boolean containsIgnoreCase(String str, String searchStr) {
1044 if (str == null || searchStr == null) {
1045 return false;
1046 }
1047 int len = searchStr.length();
1048 int max = str.length() - len;
1049 for (int i = 0; i <= max; i++) {
1050 if (str.regionMatches(true, i, searchStr, 0, len)) {
1051 return true;
1052 }
1053 }
1054 return false;
1055 }
1056
1057 // IndexOfAny chars
1058 //-----------------------------------------------------------------------
1059 /**
1060 * <p>Search a String to find the first index of any
1061 * character in the given set of characters.</p>
1062 *
1063 * <p>A <code>null</code> String will return <code>-1</code>.
1064 * A <code>null</code> or zero length search array will return <code>-1</code>.</p>
1065 *
1066 * <pre>
1067 * StringUtils.indexOfAny(null, *) = -1
1068 * StringUtils.indexOfAny("", *) = -1
1069 * StringUtils.indexOfAny(*, null) = -1
1070 * StringUtils.indexOfAny(*, []) = -1
1071 * StringUtils.indexOfAny("zzabyycdxx",['z','a']) = 0
1072 * StringUtils.indexOfAny("zzabyycdxx",['b','y']) = 3
1073 * StringUtils.indexOfAny("aba", ['z']) = -1
1074 * </pre>
1075 *
1076 * @param str the String to check, may be null
1077 * @param searchChars the chars to search for, may be null
1078 * @return the index of any of the chars, -1 if no match or null input
1079 * @since 2.0
1080 */
1081 public static int indexOfAny(String str, char[] searchChars) {
1082 if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
1083 return -1;
1084 }
1085 for (int i = 0; i < str.length(); i++) {
1086 char ch = str.charAt(i);
1087 for (int j = 0; j < searchChars.length; j++) {
1088 if (searchChars[j] == ch) {
1089 return i;
1090 }
1091 }
1092 }
1093 return -1;
1094 }
1095
1096 /**
1097 * <p>Search a String to find the first index of any
1098 * character in the given set of characters.</p>
1099 *
1100 * <p>A <code>null</code> String will return <code>-1</code>.
1101 * A <code>null</code> search string will return <code>-1</code>.</p>
1102 *
1103 * <pre>
1104 * StringUtils.indexOfAny(null, *) = -1
1105 * StringUtils.indexOfAny("", *) = -1
1106 * StringUtils.indexOfAny(*, null) = -1
1107 * StringUtils.indexOfAny(*, "") = -1
1108 * StringUtils.indexOfAny("zzabyycdxx", "za") = 0
1109 * StringUtils.indexOfAny("zzabyycdxx", "by") = 3
1110 * StringUtils.indexOfAny("aba","z") = -1
1111 * </pre>
1112 *
1113 * @param str the String to check, may be null
1114 * @param searchChars the chars to search for, may be null
1115 * @return the index of any of the chars, -1 if no match or null input
1116 * @since 2.0
1117 */
1118 public static int indexOfAny(String str, String searchChars) {
1119 if (isEmpty(str) || isEmpty(searchChars)) {
1120 return -1;
1121 }
1122 return indexOfAny(str, searchChars.toCharArray());
1123 }
1124
1125 // ContainsAny
1126 //-----------------------------------------------------------------------
1127 /**
1128 * <p>Checks if the String contains any character in the given
1129 * set of characters.</p>
1130 *
1131 * <p>A <code>null</code> String will return <code>false</code>.
1132 * A <code>null</code> or zero length search array will return <code>false</code>.</p>
1133 *
1134 * <pre>
1135 * StringUtils.containsAny(null, *) = false
1136 * StringUtils.containsAny("", *) = false
1137 * StringUtils.containsAny(*, null) = false
1138 * StringUtils.containsAny(*, []) = false
1139 * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
1140 * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
1141 * StringUtils.containsAny("aba", ['z']) = false
1142 * </pre>
1143 *
1144 * @param str the String to check, may be null
1145 * @param searchChars the chars to search for, may be null
1146 * @return the <code>true</code> if any of the chars are found,
1147 * <code>false</code> if no match or null input
1148 * @since 2.4
1149 */
1150 public static boolean containsAny(String str, char[] searchChars) {
1151 if (str == null || str.length() == 0 || searchChars == null || searchChars.length == 0) {
1152 return false;
1153 }
1154 for (int i = 0; i < str.length(); i++) {
1155 char ch = str.charAt(i);
1156 for (int j = 0; j < searchChars.length; j++) {
1157 if (searchChars[j] == ch) {
1158 return true;
1159 }
1160 }
1161 }
1162 return false;
1163 }
1164
1165 /**
1166 * <p>
1167 * Checks if the String contains any character in the given set of characters.
1168 * </p>
1169 *
1170 * <p>
1171 * A <code>null</code> String will return <code>false</code>. A <code>null</code> search string will return
1172 * <code>false</code>.
1173 * </p>
1174 *
1175 * <pre>
1176 * StringUtils.containsAny(null, *) = false
1177 * StringUtils.containsAny("", *) = false
1178 * StringUtils.containsAny(*, null) = false
1179 * StringUtils.containsAny(*, "") = false
1180 * StringUtils.containsAny("zzabyycdxx", "za") = true
1181 * StringUtils.containsAny("zzabyycdxx", "by") = true
1182 * StringUtils.containsAny("aba","z") = false
1183 * </pre>
1184 *
1185 * @param str
1186 * the String to check, may be null
1187 * @param searchChars
1188 * the chars to search for, may be null
1189 * @return the <code>true</code> if any of the chars are found, <code>false</code> if no match or null input
1190 * @since 2.4
1191 */
1192 public static boolean containsAny(String str, String searchChars) {
1193 if (searchChars == null) {
1194 return false;
1195 }
1196 return containsAny(str, searchChars.toCharArray());
1197 }
1198
1199 // IndexOfAnyBut chars
1200 //-----------------------------------------------------------------------
1201 /**
1202 * <p>Search a String to find the first index of any
1203 * character not in the given set of characters.</p>
1204 *
1205 * <p>A <code>null</code> String will return <code>-1</code>.
1206 * A <code>null</code> or zero length search array will return <code>-1</code>.</p>
1207 *
1208 * <pre>
1209 * StringUtils.indexOfAnyBut(null, *) = -1
1210 * StringUtils.indexOfAnyBut("", *) = -1
1211 * StringUtils.indexOfAnyBut(*, null) = -1
1212 * StringUtils.indexOfAnyBut(*, []) = -1
1213 * StringUtils.indexOfAnyBut("zzabyycdxx",'za') = 3
1214 * StringUtils.indexOfAnyBut("zzabyycdxx", '') = 0
1215 * StringUtils.indexOfAnyBut("aba", 'ab') = -1
1216 * </pre>
1217 *
1218 * @param str the String to check, may be null
1219 * @param searchChars the chars to search for, may be null
1220 * @return the index of any of the chars, -1 if no match or null input
1221 * @since 2.0
1222 */
1223 public static int indexOfAnyBut(String str, char[] searchChars) {
1224 if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
1225 return -1;
1226 }
1227 outer : for (int i = 0; i < str.length(); i++) {
1228 char ch = str.charAt(i);
1229 for (int j = 0; j < searchChars.length; j++) {
1230 if (searchChars[j] == ch) {
1231 continue outer;
1232 }
1233 }
1234 return i;
1235 }
1236 return -1;
1237 }
1238
1239 /**
1240 * <p>Search a String to find the first index of any
1241 * character not in the given set of characters.</p>
1242 *
1243 * <p>A <code>null</code> String will return <code>-1</code>.
1244 * A <code>null</code> search string will return <code>-1</code>.</p>
1245 *
1246 * <pre>
1247 * StringUtils.indexOfAnyBut(null, *) = -1
1248 * StringUtils.indexOfAnyBut("", *) = -1
1249 * StringUtils.indexOfAnyBut(*, null) = -1
1250 * StringUtils.indexOfAnyBut(*, "") = -1
1251 * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
1252 * StringUtils.indexOfAnyBut("zzabyycdxx", "") = 0
1253 * StringUtils.indexOfAnyBut("aba","ab") = -1
1254 * </pre>
1255 *
1256 * @param str the String to check, may be null
1257 * @param searchChars the chars to search for, may be null
1258 * @return the index of any of the chars, -1 if no match or null input
1259 * @since 2.0
1260 */
1261 public static int indexOfAnyBut(String str, String searchChars) {
1262 if (isEmpty(str) || isEmpty(searchChars)) {
1263 return -1;
1264 }
1265 for (int i = 0; i < str.length(); i++) {
1266 if (searchChars.indexOf(str.charAt(i)) < 0) {
1267 return i;
1268 }
1269 }
1270 return -1;
1271 }
1272
1273 // ContainsOnly
1274 //-----------------------------------------------------------------------
1275 /**
1276 * <p>Checks if the String contains only certain characters.</p>
1277 *
1278 * <p>A <code>null</code> String will return <code>false</code>.
1279 * A <code>null</code> valid character array will return <code>false</code>.
1280 * An empty String ("") always returns <code>true</code>.</p>
1281 *
1282 * <pre>
1283 * StringUtils.containsOnly(null, *) = false
1284 * StringUtils.containsOnly(*, null) = false
1285 * StringUtils.containsOnly("", *) = true
1286 * StringUtils.containsOnly("ab", '') = false
1287 * StringUtils.containsOnly("abab", 'abc') = true
1288 * StringUtils.containsOnly("ab1", 'abc') = false
1289 * StringUtils.containsOnly("abz", 'abc') = false
1290 * </pre>
1291 *
1292 * @param str the String to check, may be null
1293 * @param valid an array of valid chars, may be null
1294 * @return true if it only contains valid chars and is non-null
1295 */
1296 public static boolean containsOnly(String str, char[] valid) {
1297 // All these pre-checks are to maintain API with an older version
1298 if ((valid == null) || (str == null)) {
1299 return false;
1300 }
1301 if (str.length() == 0) {
1302 return true;
1303 }
1304 if (valid.length == 0) {
1305 return false;
1306 }
1307 return indexOfAnyBut(str, valid) == -1;
1308 }
1309
1310 /**
1311 * <p>Checks if the String contains only certain characters.</p>
1312 *
1313 * <p>A <code>null</code> String will return <code>false</code>.
1314 * A <code>null</code> valid character String will return <code>false</code>.
1315 * An empty String ("") always returns <code>true</code>.</p>
1316 *
1317 * <pre>
1318 * StringUtils.containsOnly(null, *) = false
1319 * StringUtils.containsOnly(*, null) = false
1320 * StringUtils.containsOnly("", *) = true
1321 * StringUtils.containsOnly("ab", "") = false
1322 * StringUtils.containsOnly("abab", "abc") = true
1323 * StringUtils.containsOnly("ab1", "abc") = false
1324 * StringUtils.containsOnly("abz", "abc") = false
1325 * </pre>
1326 *
1327 * @param str the String to check, may be null
1328 * @param validChars a String of valid chars, may be null
1329 * @return true if it only contains valid chars and is non-null
1330 * @since 2.0
1331 */
1332 public static boolean containsOnly(String str, String validChars) {
1333 if (str == null || validChars == null) {
1334 return false;
1335 }
1336 return containsOnly(str, validChars.toCharArray());
1337 }
1338
1339 // ContainsNone
1340 //-----------------------------------------------------------------------
1341 /**
1342 * <p>Checks that the String does not contain certain characters.</p>
1343 *
1344 * <p>A <code>null</code> String will return <code>true</code>.
1345 * A <code>null</code> invalid character array will return <code>true</code>.
1346 * An empty String ("") always returns true.</p>
1347 *
1348 * <pre>
1349 * StringUtils.containsNone(null, *) = true
1350 * StringUtils.containsNone(*, null) = true
1351 * StringUtils.containsNone("", *) = true
1352 * StringUtils.containsNone("ab", '') = true
1353 * StringUtils.containsNone("abab", 'xyz') = true
1354 * StringUtils.containsNone("ab1", 'xyz') = true
1355 * StringUtils.containsNone("abz", 'xyz') = false
1356 * </pre>
1357 *
1358 * @param str the String to check, may be null
1359 * @param invalidChars an array of invalid chars, may be null
1360 * @return true if it contains none of the invalid chars, or is null
1361 * @since 2.0
1362 */
1363 public static boolean containsNone(String str, char[] invalidChars) {
1364 if (str == null || invalidChars == null) {
1365 return true;
1366 }
1367 int strSize = str.length();
1368 int validSize = invalidChars.length;
1369 for (int i = 0; i < strSize; i++) {
1370 char ch = str.charAt(i);
1371 for (int j = 0; j < validSize; j++) {
1372 if (invalidChars[j] == ch) {
1373 return false;
1374 }
1375 }
1376 }
1377 return true;
1378 }
1379
1380 /**
1381 * <p>Checks that the String does not contain certain characters.</p>
1382 *
1383 * <p>A <code>null</code> String will return <code>true</code>.
1384 * A <code>null</code> invalid character array will return <code>true</code>.
1385 * An empty String ("") always returns true.</p>
1386 *
1387 * <pre>
1388 * StringUtils.containsNone(null, *) = true
1389 * StringUtils.containsNone(*, null) = true
1390 * StringUtils.containsNone("", *) = true
1391 * StringUtils.containsNone("ab", "") = true
1392 * StringUtils.containsNone("abab", "xyz") = true
1393 * StringUtils.containsNone("ab1", "xyz") = true
1394 * StringUtils.containsNone("abz", "xyz") = false
1395 * </pre>
1396 *
1397 * @param str the String to check, may be null
1398 * @param invalidChars a String of invalid chars, may be null
1399 * @return true if it contains none of the invalid chars, or is null
1400 * @since 2.0
1401 */
1402 public static boolean containsNone(String str, String invalidChars) {
1403 if (str == null || invalidChars == null) {
1404 return true;
1405 }
1406 return containsNone(str, invalidChars.toCharArray());
1407 }
1408
1409 // IndexOfAny strings
1410 //-----------------------------------------------------------------------
1411 /**
1412 * <p>Find the first index of any of a set of potential substrings.</p>
1413 *
1414 * <p>A <code>null</code> String will return <code>-1</code>.
1415 * A <code>null</code> or zero length search array will return <code>-1</code>.
1416 * A <code>null</code> search array entry will be ignored, but a search
1417 * array containing "" will return <code>0</code> if <code>str</code> is not
1418 * null. This method uses {@link String#indexOf(String)}.</p>
1419 *
1420 * <pre>
1421 * StringUtils.indexOfAny(null, *) = -1
1422 * StringUtils.indexOfAny(*, null) = -1
1423 * StringUtils.indexOfAny(*, []) = -1
1424 * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"]) = 2
1425 * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"]) = 2
1426 * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"]) = -1
1427 * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
1428 * StringUtils.indexOfAny("zzabyycdxx", [""]) = 0
1429 * StringUtils.indexOfAny("", [""]) = 0
1430 * StringUtils.indexOfAny("", ["a"]) = -1
1431 * </pre>
1432 *
1433 * @param str the String to check, may be null
1434 * @param searchStrs the Strings to search for, may be null
1435 * @return the first index of any of the searchStrs in str, -1 if no match
1436 */
1437 public static int indexOfAny(String str, String[] searchStrs) {
1438 if ((str == null) || (searchStrs == null)) {
1439 return -1;
1440 }
1441 int sz = searchStrs.length;
1442
1443 // String's can't have a MAX_VALUEth index.
1444 int ret = Integer.MAX_VALUE;
1445
1446 int tmp = 0;
1447 for (int i = 0; i < sz; i++) {
1448 String search = searchStrs[i];
1449 if (search == null) {
1450 continue;
1451 }
1452 tmp = str.indexOf(search);
1453 if (tmp == -1) {
1454 continue;
1455 }
1456
1457 if (tmp < ret) {
1458 ret = tmp;
1459 }
1460 }
1461
1462 return (ret == Integer.MAX_VALUE) ? -1 : ret;
1463 }
1464
1465 /**
1466 * <p>Find the latest index of any of a set of potential substrings.</p>
1467 *
1468 * <p>A <code>null</code> String will return <code>-1</code>.
1469 * A <code>null</code> search array will return <code>-1</code>.
1470 * A <code>null</code> or zero length search array entry will be ignored,
1471 * but a search array containing "" will return the length of <code>str</code>
1472 * if <code>str</code> is not null. This method uses {@link String#indexOf(String)}</p>
1473 *
1474 * <pre>
1475 * StringUtils.lastIndexOfAny(null, *) = -1
1476 * StringUtils.lastIndexOfAny(*, null) = -1
1477 * StringUtils.lastIndexOfAny(*, []) = -1
1478 * StringUtils.lastIndexOfAny(*, [null]) = -1
1479 * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
1480 * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
1481 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1482 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1483 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""]) = 10
1484 * </pre>
1485 *
1486 * @param str the String to check, may be null
1487 * @param searchStrs the Strings to search for, may be null
1488 * @return the last index of any of the Strings, -1 if no match
1489 */
1490 public static int lastIndexOfAny(String str, String[] searchStrs) {
1491 if ((str == null) || (searchStrs == null)) {
1492 return -1;
1493 }
1494 int sz = searchStrs.length;
1495 int ret = -1;
1496 int tmp = 0;
1497 for (int i = 0; i < sz; i++) {
1498 String search = searchStrs[i];
1499 if (search == null) {
1500 continue;
1501 }
1502 tmp = str.lastIndexOf(search);
1503 if (tmp > ret) {
1504 ret = tmp;
1505 }
1506 }
1507 return ret;
1508 }
1509
1510 // Substring
1511 //-----------------------------------------------------------------------
1512 /**
1513 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1514 *
1515 * <p>A negative start position can be used to start <code>n</code>
1516 * characters from the end of the String.</p>
1517 *
1518 * <p>A <code>null</code> String will return <code>null</code>.
1519 * An empty ("") String will return "".</p>
1520 *
1521 * <pre>
1522 * StringUtils.substring(null, *) = null
1523 * StringUtils.substring("", *) = ""
1524 * StringUtils.substring("abc", 0) = "abc"
1525 * StringUtils.substring("abc", 2) = "c"
1526 * StringUtils.substring("abc", 4) = ""
1527 * StringUtils.substring("abc", -2) = "bc"
1528 * StringUtils.substring("abc", -4) = "abc"
1529 * </pre>
1530 *
1531 * @param str the String to get the substring from, may be null
1532 * @param start the position to start from, negative means
1533 * count back from the end of the String by this many characters
1534 * @return substring from start position, <code>null</code> if null String input
1535 */
1536 public static String substring(String str, int start) {
1537 if (str == null) {
1538 return null;
1539 }
1540
1541 // handle negatives, which means last n characters
1542 if (start < 0) {
1543 start = str.length() + start; // remember start is negative
1544 }
1545
1546 if (start < 0) {
1547 start = 0;
1548 }
1549 if (start > str.length()) {
1550 return EMPTY;
1551 }
1552
1553 return str.substring(start);
1554 }
1555
1556 /**
1557 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1558 *
1559 * <p>A negative start position can be used to start/end <code>n</code>
1560 * characters from the end of the String.</p>
1561 *
1562 * <p>The returned substring starts with the character in the <code>start</code>
1563 * position and ends before the <code>end</code> position. All position counting is
1564 * zero-based -- i.e., to start at the beginning of the string use
1565 * <code>start = 0</code>. Negative start and end positions can be used to
1566 * specify offsets relative to the end of the String.</p>
1567 *
1568 * <p>If <code>start</code> is not strictly to the left of <code>end</code>, ""
1569 * is returned.</p>
1570 *
1571 * <pre>
1572 * StringUtils.substring(null, *, *) = null
1573 * StringUtils.substring("", * , *) = "";
1574 * StringUtils.substring("abc", 0, 2) = "ab"
1575 * StringUtils.substring("abc", 2, 0) = ""
1576 * StringUtils.substring("abc", 2, 4) = "c"
1577 * StringUtils.substring("abc", 4, 6) = ""
1578 * StringUtils.substring("abc", 2, 2) = ""
1579 * StringUtils.substring("abc", -2, -1) = "b"
1580 * StringUtils.substring("abc", -4, 2) = "ab"
1581 * </pre>
1582 *
1583 * @param str the String to get the substring from, may be null
1584 * @param start the position to start from, negative means
1585 * count back from the end of the String by this many characters
1586 * @param end the position to end at (exclusive), negative means
1587 * count back from the end of the String by this many characters
1588 * @return substring from start position to end positon,
1589 * <code>null</code> if null String input
1590 */
1591 public static String substring(String str, int start, int end) {
1592 if (str == null) {
1593 return null;
1594 }
1595
1596 // handle negatives
1597 if (end < 0) {
1598 end = str.length() + end; // remember end is negative
1599 }
1600 if (start < 0) {
1601 start = str.length() + start; // remember start is negative
1602 }
1603
1604 // check length next
1605 if (end > str.length()) {
1606 end = str.length();
1607 }
1608
1609 // if start is greater than end, return ""
1610 if (start > end) {
1611 return EMPTY;
1612 }
1613
1614 if (start < 0) {
1615 start = 0;
1616 }
1617 if (end < 0) {
1618 end = 0;
1619 }
1620
1621 return str.substring(start, end);
1622 }
1623
1624 // Left/Right/Mid
1625 //-----------------------------------------------------------------------
1626 /**
1627 * <p>Gets the leftmost <code>len</code> characters of a String.</p>
1628 *
1629 * <p>If <code>len</code> characters are not available, or the
1630 * String is <code>null</code>, the String will be returned without
1631 * an exception. An exception is thrown if len is negative.</p>
1632 *
1633 * <pre>
1634 * StringUtils.left(null, *) = null
1635 * StringUtils.left(*, -ve) = ""
1636 * StringUtils.left("", *) = ""
1637 * StringUtils.left("abc", 0) = ""
1638 * StringUtils.left("abc", 2) = "ab"
1639 * StringUtils.left("abc", 4) = "abc"
1640 * </pre>
1641 *
1642 * @param str the String to get the leftmost characters from, may be null
1643 * @param len the length of the required String, must be zero or positive
1644 * @return the leftmost characters, <code>null</code> if null String input
1645 */
1646 public static String left(String str, int len) {
1647 if (str == null) {
1648 return null;
1649 }
1650 if (len < 0) {
1651 return EMPTY;
1652 }
1653 if (str.length() <= len) {
1654 return str;
1655 }
1656 return str.substring(0, len);
1657 }
1658
1659 /**
1660 * <p>Gets the rightmost <code>len</code> characters of a String.</p>
1661 *
1662 * <p>If <code>len</code> characters are not available, or the String
1663 * is <code>null</code>, the String will be returned without an
1664 * an exception. An exception is thrown if len is negative.</p>
1665 *
1666 * <pre>
1667 * StringUtils.right(null, *) = null
1668 * StringUtils.right(*, -ve) = ""
1669 * StringUtils.right("", *) = ""
1670 * StringUtils.right("abc", 0) = ""
1671 * StringUtils.right("abc", 2) = "bc"
1672 * StringUtils.right("abc", 4) = "abc"
1673 * </pre>
1674 *
1675 * @param str the String to get the rightmost characters from, may be null
1676 * @param len the length of the required String, must be zero or positive
1677 * @return the rightmost characters, <code>null</code> if null String input
1678 */
1679 public static String right(String str, int len) {
1680 if (str == null) {
1681 return null;
1682 }
1683 if (len < 0) {
1684 return EMPTY;
1685 }
1686 if (str.length() <= len) {
1687 return str;
1688 }
1689 return str.substring(str.length() - len);
1690 }
1691
1692 /**
1693 * <p>Gets <code>len</code> characters from the middle of a String.</p>
1694 *
1695 * <p>If <code>len</code> characters are not available, the remainder
1696 * of the String will be returned without an exception. If the
1697 * String is <code>null</code>, <code>null</code> will be returned.
1698 * An exception is thrown if len is negative.</p>
1699 *
1700 * <pre>
1701 * StringUtils.mid(null, *, *) = null
1702 * StringUtils.mid(*, *, -ve) = ""
1703 * StringUtils.mid("", 0, *) = ""
1704 * StringUtils.mid("abc", 0, 2) = "ab"
1705 * StringUtils.mid("abc", 0, 4) = "abc"
1706 * StringUtils.mid("abc", 2, 4) = "c"
1707 * StringUtils.mid("abc", 4, 2) = ""
1708 * StringUtils.mid("abc", -2, 2) = "ab"
1709 * </pre>
1710 *
1711 * @param str the String to get the characters from, may be null
1712 * @param pos the position to start from, negative treated as zero
1713 * @param len the length of the required String, must be zero or positive
1714 * @return the middle characters, <code>null</code> if null String input
1715 */
1716 public static String mid(String str, int pos, int len) {
1717 if (str == null) {
1718 return null;
1719 }
1720 if (len < 0 || pos > str.length()) {
1721 return EMPTY;
1722 }
1723 if (pos < 0) {
1724 pos = 0;
1725 }
1726 if (str.length() <= (pos + len)) {
1727 return str.substring(pos);
1728 }
1729 return str.substring(pos, pos + len);
1730 }
1731
1732 // SubStringAfter/SubStringBefore
1733 //-----------------------------------------------------------------------
1734 /**
1735 * <p>Gets the substring before the first occurrence of a separator.
1736 * The separator is not returned.</p>
1737 *
1738 * <p>A <code>null</code> string input will return <code>null</code>.
1739 * An empty ("") string input will return the empty string.
1740 * A <code>null</code> separator will return the input string.</p>
1741 *
1742 * <p>If nothing is found, the string input is returned.</p>
1743 *
1744 * <pre>
1745 * StringUtils.substringBefore(null, *) = null
1746 * StringUtils.substringBefore("", *) = ""
1747 * StringUtils.substringBefore("abc", "a") = ""
1748 * StringUtils.substringBefore("abcba", "b") = "a"
1749 * StringUtils.substringBefore("abc", "c") = "ab"
1750 * StringUtils.substringBefore("abc", "d") = "abc"
1751 * StringUtils.substringBefore("abc", "") = ""
1752 * StringUtils.substringBefore("abc", null) = "abc"
1753 * </pre>
1754 *
1755 * @param str the String to get a substring from, may be null
1756 * @param separator the String to search for, may be null
1757 * @return the substring before the first occurrence of the separator,
1758 * <code>null</code> if null String input
1759 * @since 2.0
1760 */
1761 public static String substringBefore(String str, String separator) {
1762 if (isEmpty(str) || separator == null) {
1763 return str;
1764 }
1765 if (separator.length() == 0) {
1766 return EMPTY;
1767 }
1768 int pos = str.indexOf(separator);
1769 if (pos == -1) {
1770 return str;
1771 }
1772 return str.substring(0, pos);
1773 }
1774
1775 /**
1776 * <p>Gets the substring after the first occurrence of a separator.
1777 * The separator is not returned.</p>
1778 *
1779 * <p>A <code>null</code> string input will return <code>null</code>.
1780 * An empty ("") string input will return the empty string.
1781 * A <code>null</code> separator will return the empty string if the
1782 * input string is not <code>null</code>.</p>
1783 *
1784 * <p>If nothing is found, the empty string is returned.</p>
1785 *
1786 * <pre>
1787 * StringUtils.substringAfter(null, *) = null
1788 * StringUtils.substringAfter("", *) = ""
1789 * StringUtils.substringAfter(*, null) = ""
1790 * StringUtils.substringAfter("abc", "a") = "bc"
1791 * StringUtils.substringAfter("abcba", "b") = "cba"
1792 * StringUtils.substringAfter("abc", "c") = ""
1793 * StringUtils.substringAfter("abc", "d") = ""
1794 * StringUtils.substringAfter("abc", "") = "abc"
1795 * </pre>
1796 *
1797 * @param str the String to get a substring from, may be null
1798 * @param separator the String to search for, may be null
1799 * @return the substring after the first occurrence of the separator,
1800 * <code>null</code> if null String input
1801 * @since 2.0
1802 */
1803 public static String substringAfter(String str, String separator) {
1804 if (isEmpty(str)) {
1805 return str;
1806 }
1807 if (separator == null) {
1808 return EMPTY;
1809 }
1810 int pos = str.indexOf(separator);
1811 if (pos == -1) {
1812 return EMPTY;
1813 }
1814 return str.substring(pos + separator.length());
1815 }
1816
1817 /**
1818 * <p>Gets the substring before the last occurrence of a separator.
1819 * The separator is not returned.</p>
1820 *
1821 * <p>A <code>null</code> string input will return <code>null</code>.
1822 * An empty ("") string input will return the empty string.
1823 * An empty or <code>null</code> separator will return the input string.</p>
1824 *
1825 * <p>If nothing is found, the string input is returned.</p>
1826 *
1827 * <pre>
1828 * StringUtils.substringBeforeLast(null, *) = null
1829 * StringUtils.substringBeforeLast("", *) = ""
1830 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
1831 * StringUtils.substringBeforeLast("abc", "c") = "ab"
1832 * StringUtils.substringBeforeLast("a", "a") = ""
1833 * StringUtils.substringBeforeLast("a", "z") = "a"
1834 * StringUtils.substringBeforeLast("a", null) = "a"
1835 * StringUtils.substringBeforeLast("a", "") = "a"
1836 * </pre>
1837 *
1838 * @param str the String to get a substring from, may be null
1839 * @param separator the String to search for, may be null
1840 * @return the substring before the last occurrence of the separator,
1841 * <code>null</code> if null String input
1842 * @since 2.0
1843 */
1844 public static String substringBeforeLast(String str, String separator) {
1845 if (isEmpty(str) || isEmpty(separator)) {
1846 return str;
1847 }
1848 int pos = str.lastIndexOf(separator);
1849 if (pos == -1) {
1850 return str;
1851 }
1852 return str.substring(0, pos);
1853 }
1854
1855 /**
1856 * <p>Gets the substring after the last occurrence of a separator.
1857 * The separator is not returned.</p>
1858 *
1859 * <p>A <code>null</code> string input will return <code>null</code>.
1860 * An empty ("") string input will return the empty string.
1861 * An empty or <code>null</code> separator will return the empty string if
1862 * the input string is not <code>null</code>.</p>
1863 *
1864 * <p>If nothing is found, the empty string is returned.</p>
1865 *
1866 * <pre>
1867 * StringUtils.substringAfterLast(null, *) = null
1868 * StringUtils.substringAfterLast("", *) = ""
1869 * StringUtils.substringAfterLast(*, "") = ""
1870 * StringUtils.substringAfterLast(*, null) = ""
1871 * StringUtils.substringAfterLast("abc", "a") = "bc"
1872 * StringUtils.substringAfterLast("abcba", "b") = "a"
1873 * StringUtils.substringAfterLast("abc", "c") = ""
1874 * StringUtils.substringAfterLast("a", "a") = ""
1875 * StringUtils.substringAfterLast("a", "z") = ""
1876 * </pre>
1877 *
1878 * @param str the String to get a substring from, may be null
1879 * @param separator the String to search for, may be null
1880 * @return the substring after the last occurrence of the separator,
1881 * <code>null</code> if null String input
1882 * @since 2.0
1883 */
1884 public static String substringAfterLast(String str, String separator) {
1885 if (isEmpty(str)) {
1886 return str;
1887 }
1888 if (isEmpty(separator)) {
1889 return EMPTY;
1890 }
1891 int pos = str.lastIndexOf(separator);
1892 if (pos == -1 || pos == (str.length() - separator.length())) {
1893 return EMPTY;
1894 }
1895 return str.substring(pos + separator.length());
1896 }
1897
1898 // Substring between
1899 //-----------------------------------------------------------------------
1900 /**
1901 * <p>Gets the String that is nested in between two instances of the
1902 * same String.</p>
1903 *
1904 * <p>A <code>null</code> input String returns <code>null</code>.
1905 * A <code>null</code> tag returns <code>null</code>.</p>
1906 *
1907 * <pre>
1908 * StringUtils.substringBetween(null, *) = null
1909 * StringUtils.substringBetween("", "") = ""
1910 * StringUtils.substringBetween("", "tag") = null
1911 * StringUtils.substringBetween("tagabctag", null) = null
1912 * StringUtils.substringBetween("tagabctag", "") = ""
1913 * StringUtils.substringBetween("tagabctag", "tag") = "abc"
1914 * </pre>
1915 *
1916 * @param str the String containing the substring, may be null
1917 * @param tag the String before and after the substring, may be null
1918 * @return the substring, <code>null</code> if no match
1919 * @since 2.0
1920 */
1921 public static String substringBetween(String str, String tag) {
1922 return substringBetween(str, tag, tag);
1923 }
1924
1925 /**
1926 * <p>Gets the String that is nested in between two Strings.
1927 * Only the first match is returned.</p>
1928 *
1929 * <p>A <code>null</code> input String returns <code>null</code>.
1930 * A <code>null</code> open/close returns <code>null</code> (no match).
1931 * An empty ("") open and close returns an empty string.</p>
1932 *
1933 * <pre>
1934 * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
1935 * StringUtils.substringBetween(null, *, *) = null
1936 * StringUtils.substringBetween(*, null, *) = null
1937 * StringUtils.substringBetween(*, *, null) = null
1938 * StringUtils.substringBetween("", "", "") = ""
1939 * StringUtils.substringBetween("", "", "]") = null
1940 * StringUtils.substringBetween("", "[", "]") = null
1941 * StringUtils.substringBetween("yabcz", "", "") = ""
1942 * StringUtils.substringBetween("yabcz", "y", "z") = "abc"
1943 * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc"
1944 * </pre>
1945 *
1946 * @param str the String containing the substring, may be null
1947 * @param open the String before the substring, may be null
1948 * @param close the String after the substring, may be null
1949 * @return the substring, <code>null</code> if no match
1950 * @since 2.0
1951 */
1952 public static String substringBetween(String str, String open, String close) {
1953 if (str == null || open == null || close == null) {
1954 return null;
1955 }
1956 int start = str.indexOf(open);
1957 if (start != -1) {
1958 int end = str.indexOf(close, start + open.length());
1959 if (end != -1) {
1960 return str.substring(start + open.length(), end);
1961 }
1962 }
1963 return null;
1964 }
1965
1966 /**
1967 * <p>Searches a String for substrings delimited by a start and end tag,
1968 * returning all matching substrings in an array.</p>
1969 *
1970 * <p>A <code>null</code> input String returns <code>null</code>.
1971 * A <code>null</code> open/close returns <code>null</code> (no match).
1972 * An empty ("") open/close returns <code>null</code> (no match).</p>
1973 *
1974 * <pre>
1975 * StringUtils.substringsBetween("[a][b][c]", "[", "]") = ["a","b","c"]
1976 * StringUtils.substringsBetween(null, *, *) = null
1977 * StringUtils.substringsBetween(*, null, *) = null
1978 * StringUtils.substringsBetween(*, *, null) = null
1979 * StringUtils.substringsBetween("", "[", "]") = []
1980 * </pre>
1981 *
1982 * @param str the String containing the substrings, null returns null, empty returns empty
1983 * @param open the String identifying the start of the substring, empty returns null
1984 * @param close the String identifying the end of the substring, empty returns null
1985 * @return a String Array of substrings, or <code>null</code> if no match
1986 * @since 2.3
1987 */
1988 public static String[] substringsBetween(String str, String open, String close) {
1989 if (str == null || isEmpty(open) || isEmpty(close)) {
1990 return null;
1991 }
1992 int strLen = str.length();
1993 if (strLen == 0) {
1994 return ArrayUtils.EMPTY_STRING_ARRAY;
1995 }
1996 int closeLen = close.length();
1997 int openLen = open.length();
1998 List<String> list = new ArrayList<String>();
1999 int pos = 0;
2000 while (pos < (strLen - closeLen)) {
2001 int start = str.indexOf(open, pos);
2002 if (start < 0) {
2003 break;
2004 }
2005 start += openLen;
2006 int end = str.indexOf(close, start);
2007 if (end < 0) {
2008 break;
2009 }
2010 list.add(str.substring(start, end));
2011 pos = end + closeLen;
2012 }
2013 if (list.isEmpty()) {
2014 return null;
2015 }
2016 return list.toArray(new String [list.size()]);
2017 }
2018
2019 // Nested extraction
2020 //-----------------------------------------------------------------------
2021
2022 // Splitting
2023 //-----------------------------------------------------------------------
2024 /**
2025 * <p>Splits the provided text into an array, using whitespace as the
2026 * separator.
2027 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
2028 *
2029 * <p>The separator is not included in the returned String array.
2030 * Adjacent separators are treated as one separator.
2031 * For more control over the split use the StrTokenizer class.</p>
2032 *
2033 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2034 *
2035 * <pre>
2036 * StringUtils.split(null) = null
2037 * StringUtils.split("") = []
2038 * StringUtils.split("abc def") = ["abc", "def"]
2039 * StringUtils.split("abc def") = ["abc", "def"]
2040 * StringUtils.split(" abc ") = ["abc"]
2041 * </pre>
2042 *
2043 * @param str the String to parse, may be null
2044 * @return an array of parsed Strings, <code>null</code> if null String input
2045 */
2046 public static String[] split(String str) {
2047 return split(str, null, -1);
2048 }
2049
2050 /**
2051 * <p>Splits the provided text into an array, separator specified.
2052 * This is an alternative to using StringTokenizer.</p>
2053 *
2054 * <p>The separator is not included in the returned String array.
2055 * Adjacent separators are treated as one separator.
2056 * For more control over the split use the StrTokenizer class.</p>
2057 *
2058 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2059 *
2060 * <pre>
2061 * StringUtils.split(null, *) = null
2062 * StringUtils.split("", *) = []
2063 * StringUtils.split("a.b.c", '.') = ["a", "b", "c"]
2064 * StringUtils.split("a..b.c", '.') = ["a", "b", "c"]
2065 * StringUtils.split("a:b:c", '.') = ["a:b:c"]
2066 * StringUtils.split("a b c", ' ') = ["a", "b", "c"]
2067 * </pre>
2068 *
2069 * @param str the String to parse, may be null
2070 * @param separatorChar the character used as the delimiter
2071 * @return an array of parsed Strings, <code>null</code> if null String input
2072 * @since 2.0
2073 */
2074 public static String[] split(String str, char separatorChar) {
2075 return splitWorker(str, separatorChar, false);
2076 }
2077
2078 /**
2079 * <p>Splits the provided text into an array, separators specified.
2080 * This is an alternative to using StringTokenizer.</p>
2081 *
2082 * <p>The separator is not included in the returned String array.
2083 * Adjacent separators are treated as one separator.
2084 * For more control over the split use the StrTokenizer class.</p>
2085 *
2086 * <p>A <code>null</code> input String returns <code>null</code>.
2087 * A <code>null</code> separatorChars splits on whitespace.</p>
2088 *
2089 * <pre>
2090 * StringUtils.split(null, *) = null
2091 * StringUtils.split("", *) = []
2092 * StringUtils.split("abc def", null) = ["abc", "def"]
2093 * StringUtils.split("abc def", " ") = ["abc", "def"]
2094 * StringUtils.split("abc def", " ") = ["abc", "def"]
2095 * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2096 * </pre>
2097 *
2098 * @param str the String to parse, may be null
2099 * @param separatorChars the characters used as the delimiters,
2100 * <code>null</code> splits on whitespace
2101 * @return an array of parsed Strings, <code>null</code> if null String input
2102 */
2103 public static String[] split(String str, String separatorChars) {
2104 return splitWorker(str, separatorChars, -1, false);
2105 }
2106
2107 /**
2108 * <p>Splits the provided text into an array with a maximum length,
2109 * separators specified.</p>
2110 *
2111 * <p>The separator is not included in the returned String array.
2112 * Adjacent separators are treated as one separator.</p>
2113 *
2114 * <p>A <code>null</code> input String returns <code>null</code>.
2115 * A <code>null</code> separatorChars splits on whitespace.</p>
2116 *
2117 * <p>If more than <code>max</code> delimited substrings are found, the last
2118 * returned string includes all characters after the first <code>max - 1</code>
2119 * returned strings (including separator characters).</p>
2120 *
2121 * <pre>
2122 * StringUtils.split(null, *, *) = null
2123 * StringUtils.split("", *, *) = []
2124 * StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"]
2125 * StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"]
2126 * StringUtils.split("ab:cd:ef", ":", 0) = ["ab", "cd", "ef"]
2127 * StringUtils.split("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2128 * </pre>
2129 *
2130 * @param str the String to parse, may be null
2131 * @param separatorChars the characters used as the delimiters,
2132 * <code>null</code> splits on whitespace
2133 * @param max the maximum number of elements to include in the
2134 * array. A zero or negative value implies no limit
2135 * @return an array of parsed Strings, <code>null</code> if null String input
2136 */
2137 public static String[] split(String str, String separatorChars, int max) {
2138 return splitWorker(str, separatorChars, max, false);
2139 }
2140
2141 /**
2142 * <p>Splits the provided text into an array, separator string specified.</p>
2143 *
2144 * <p>The separator(s) will not be included in the returned String array.
2145 * Adjacent separators are treated as one separator.</p>
2146 *
2147 * <p>A <code>null</code> input String returns <code>null</code>.
2148 * A <code>null</code> separator splits on whitespace.</p>
2149 *
2150 * <pre>
2151 * StringUtils.splitByWholeSeparator(null, *) = null
2152 * StringUtils.splitByWholeSeparator("", *) = []
2153 * StringUtils.splitByWholeSeparator("ab de fg", null) = ["ab", "de", "fg"]
2154 * StringUtils.splitByWholeSeparator("ab de fg", null) = ["ab", "de", "fg"]
2155 * StringUtils.splitByWholeSeparator("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2156 * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
2157 * </pre>
2158 *
2159 * @param str the String to parse, may be null
2160 * @param separator String containing the String to be used as a delimiter,
2161 * <code>null</code> splits on whitespace
2162 * @return an array of parsed Strings, <code>null</code> if null String was input
2163 */
2164 public static String[] splitByWholeSeparator(String str, String separator) {
2165 return splitByWholeSeparatorWorker( str, separator, -1, false ) ;
2166 }
2167
2168 /**
2169 * <p>Splits the provided text into an array, separator string specified.
2170 * Returns a maximum of <code>max</code> substrings.</p>
2171 *
2172 * <p>The separator(s) will not be included in the returned String array.
2173 * Adjacent separators are treated as one separator.</p>
2174 *
2175 * <p>A <code>null</code> input String returns <code>null</code>.
2176 * A <code>null</code> separator splits on whitespace.</p>
2177 *
2178 * <pre>
2179 * StringUtils.splitByWholeSeparator(null, *, *) = null
2180 * StringUtils.splitByWholeSeparator("", *, *) = []
2181 * StringUtils.splitByWholeSeparator("ab de fg", null, 0) = ["ab", "de", "fg"]
2182 * StringUtils.splitByWholeSeparator("ab de fg", null, 0) = ["ab", "de", "fg"]
2183 * StringUtils.splitByWholeSeparator("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2184 * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
2185 * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
2186 * </pre>
2187 *
2188 * @param str the String to parse, may be null
2189 * @param separator String containing the String to be used as a delimiter,
2190 * <code>null</code> splits on whitespace
2191 * @param max the maximum number of elements to include in the returned
2192 * array. A zero or negative value implies no limit.
2193 * @return an array of parsed Strings, <code>null</code> if null String was input
2194 */
2195 public static String[] splitByWholeSeparator( String str, String separator, int max ) {
2196 return splitByWholeSeparatorWorker(str, separator, max, false);
2197 }
2198
2199 /**
2200 * <p>Splits the provided text into an array, separator string specified. </p>
2201 *
2202 * <p>The separator is not included in the returned String array.
2203 * Adjacent separators are treated as separators for empty tokens.
2204 * For more control over the split use the StrTokenizer class.</p>
2205 *
2206 * <p>A <code>null</code> input String returns <code>null</code>.
2207 * A <code>null</code> separator splits on whitespace.</p>
2208 *
2209 * <pre>
2210 * StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *) = null
2211 * StringUtils.splitByWholeSeparatorPreserveAllTokens("", *) = []
2212 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null) = ["ab", "de", "fg"]
2213 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null) = ["ab", "", "", "de", "fg"]
2214 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2215 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
2216 * </pre>
2217 *
2218 * @param str the String to parse, may be null
2219 * @param separator String containing the String to be used as a delimiter,
2220 * <code>null</code> splits on whitespace
2221 * @return an array of parsed Strings, <code>null</code> if null String was input
2222 * @since 2.4
2223 */
2224 public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator) {
2225 return splitByWholeSeparatorWorker(str, separator, -1, true);
2226 }
2227
2228 /**
2229 * <p>Splits the provided text into an array, separator string specified.
2230 * Returns a maximum of <code>max</code> substrings.</p>
2231 *
2232 * <p>The separator is not included in the returned String array.
2233 * Adjacent separators are treated as separators for empty tokens.
2234 * For more control over the split use the StrTokenizer class.</p>
2235 *
2236 * <p>A <code>null</code> input String returns <code>null</code>.
2237 * A <code>null</code> separator splits on whitespace.</p>
2238 *
2239 * <pre>
2240 * StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *, *) = null
2241 * StringUtils.splitByWholeSeparatorPreserveAllTokens("", *, *) = []
2242 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0) = ["ab", "de", "fg"]
2243 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0) = ["ab", "", "", "de", "fg"]
2244 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2245 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
2246 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
2247 * </pre>
2248 *
2249 * @param str the String to parse, may be null
2250 * @param separator String containing the String to be used as a delimiter,
2251 * <code>null</code> splits on whitespace
2252 * @param max the maximum number of elements to include in the returned
2253 * array. A zero or negative value implies no limit.
2254 * @return an array of parsed Strings, <code>null</code> if null String was input
2255 * @since 2.4
2256 */
2257 public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator, int max) {
2258 return splitByWholeSeparatorWorker(str, separator, max, true);
2259 }
2260
2261 /**
2262 * Performs the logic for the <code>splitByWholeSeparatorPreserveAllTokens</code> methods.
2263 *
2264 * @param str the String to parse, may be <code>null</code>
2265 * @param separator String containing the String to be used as a delimiter,
2266 * <code>null</code> splits on whitespace
2267 * @param max the maximum number of elements to include in the returned
2268 * array. A zero or negative value implies no limit.
2269 * @param preserveAllTokens if <code>true</code>, adjacent separators are
2270 * treated as empty token separators; if <code>false</code>, adjacent
2271 * separators are treated as one separator.
2272 * @return an array of parsed Strings, <code>null</code> if null String input
2273 * @since 2.4
2274 */
2275 private static String[] splitByWholeSeparatorWorker(String str, String separator, int max,
2276 boolean preserveAllTokens)
2277 {
2278 if (str == null) {
2279 return null;
2280 }
2281
2282 int len = str.length();
2283
2284 if (len == 0) {
2285 return ArrayUtils.EMPTY_STRING_ARRAY;
2286 }
2287
2288 if ((separator == null) || (EMPTY.equals(separator))) {
2289 // Split on whitespace.
2290 return splitWorker(str, null, max, preserveAllTokens);
2291 }
2292
2293 int separatorLength = separator.length();
2294
2295 ArrayList<String> substrings = new ArrayList<String>();
2296 int numberOfSubstrings = 0;
2297 int beg = 0;
2298 int end = 0;
2299 while (end < len) {
2300 end = str.indexOf(separator, beg);
2301
2302 if (end > -1) {
2303 if (end > beg) {
2304 numberOfSubstrings += 1;
2305
2306 if (numberOfSubstrings == max) {
2307 end = len;
2308 substrings.add(str.substring(beg));
2309 } else {
2310 // The following is OK, because String.substring( beg, end ) excludes
2311 // the character at the position 'end'.
2312 substrings.add(str.substring(beg, end));
2313
2314 // Set the starting point for the next search.
2315 // The following is equivalent to beg = end + (separatorLength - 1) + 1,
2316 // which is the right calculation:
2317 beg = end + separatorLength;
2318 }
2319 } else {
2320 // We found a consecutive occurrence of the separator, so skip it.
2321 if (preserveAllTokens) {
2322 numberOfSubstrings += 1;
2323 if (numberOfSubstrings == max) {
2324 end = len;
2325 substrings.add(str.substring(beg));
2326 } else {
2327 substrings.add(EMPTY);
2328 }
2329 }
2330 beg = end + separatorLength;
2331 }
2332 } else {
2333 // String.substring( beg ) goes from 'beg' to the end of the String.
2334 substrings.add(str.substring(beg));
2335 end = len;
2336 }
2337 }
2338
2339 return substrings.toArray(new String[substrings.size()]);
2340 }
2341
2342 // -----------------------------------------------------------------------
2343 /**
2344 * <p>Splits the provided text into an array, using whitespace as the
2345 * separator, preserving all tokens, including empty tokens created by
2346 * adjacent separators. This is an alternative to using StringTokenizer.
2347 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
2348 *
2349 * <p>The separator is not included in the returned String array.
2350 * Adjacent separators are treated as separators for empty tokens.
2351 * For more control over the split use the StrTokenizer class.</p>
2352 *
2353 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2354 *
2355 * <pre>
2356 * StringUtils.splitPreserveAllTokens(null) = null
2357 * StringUtils.splitPreserveAllTokens("") = []
2358 * StringUtils.splitPreserveAllTokens("abc def") = ["abc", "def"]
2359 * StringUtils.splitPreserveAllTokens("abc def") = ["abc", "", "def"]
2360 * StringUtils.splitPreserveAllTokens(" abc ") = ["", "abc", ""]
2361 * </pre>
2362 *
2363 * @param str the String to parse, may be <code>null</code>
2364 * @return an array of parsed Strings, <code>null</code> if null String input
2365 * @since 2.1
2366 */
2367 public static String[] splitPreserveAllTokens(String str) {
2368 return splitWorker(str, null, -1, true);
2369 }
2370
2371 /**
2372 * <p>Splits the provided text into an array, separator specified,
2373 * preserving all tokens, including empty tokens created by adjacent
2374 * separators. This is an alternative to using StringTokenizer.</p>
2375 *
2376 * <p>The separator is not included in the returned String array.
2377 * Adjacent separators are treated as separators for empty tokens.
2378 * For more control over the split use the StrTokenizer class.</p>
2379 *
2380 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2381 *
2382 * <pre>
2383 * StringUtils.splitPreserveAllTokens(null, *) = null
2384 * StringUtils.splitPreserveAllTokens("", *) = []
2385 * StringUtils.splitPreserveAllTokens("a.b.c", '.') = ["a", "b", "c"]
2386 * StringUtils.splitPreserveAllTokens("a..b.c", '.') = ["a", "", "b", "c"]
2387 * StringUtils.splitPreserveAllTokens("a:b:c", '.') = ["a:b:c"]
2388 * StringUtils.splitPreserveAllTokens("a\tb\nc", null) = ["a", "b", "c"]
2389 * StringUtils.splitPreserveAllTokens("a b c", ' ') = ["a", "b", "c"]
2390 * StringUtils.splitPreserveAllTokens("a b c ", ' ') = ["a", "b", "c", ""]
2391 * StringUtils.splitPreserveAllTokens("a b c ", ' ') = ["a", "b", "c", "", ""]
2392 * StringUtils.splitPreserveAllTokens(" a b c", ' ') = ["", a", "b", "c"]
2393 * StringUtils.splitPreserveAllTokens(" a b c", ' ') = ["", "", a", "b", "c"]
2394 * StringUtils.splitPreserveAllTokens(" a b c ", ' ') = ["", a", "b", "c", ""]
2395 * </pre>
2396 *
2397 * @param str the String to parse, may be <code>null</code>
2398 * @param separatorChar the character used as the delimiter,
2399 * <code>null</code> splits on whitespace
2400 * @return an array of parsed Strings, <code>null</code> if null String input
2401 * @since 2.1
2402 */
2403 public static String[] splitPreserveAllTokens(String str, char separatorChar) {
2404 return splitWorker(str, separatorChar, true);
2405 }
2406
2407 /**
2408 * Performs the logic for the <code>split</code> and
2409 * <code>splitPreserveAllTokens</code> methods that do not return a
2410 * maximum array length.
2411 *
2412 * @param str the String to parse, may be <code>null</code>
2413 * @param separatorChar the separate character
2414 * @param preserveAllTokens if <code>true</code>, adjacent separators are
2415 * treated as empty token separators; if <code>false</code>, adjacent
2416 * separators are treated as one separator.
2417 * @return an array of parsed Strings, <code>null</code> if null String input
2418 */
2419 private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
2420 // Performance tuned for 2.0 (JDK1.4)
2421
2422 if (str == null) {
2423 return null;
2424 }
2425 int len = str.length();
2426 if (len == 0) {
2427 return ArrayUtils.EMPTY_STRING_ARRAY;
2428 }
2429 List<String> list = new ArrayList<String>();
2430 int i = 0, start = 0;
2431 boolean match = false;
2432 boolean lastMatch = false;
2433 while (i < len) {
2434 if (str.charAt(i) == separatorChar) {
2435 if (match || preserveAllTokens) {
2436 list.add(str.substring(start, i));
2437 match = false;
2438 lastMatch = true;
2439 }
2440 start = ++i;
2441 continue;
2442 }
2443 lastMatch = false;
2444 match = true;
2445 i++;
2446 }
2447 if (match || (preserveAllTokens && lastMatch)) {
2448 list.add(str.substring(start, i));
2449 }
2450 return list.toArray(new String[list.size()]);
2451 }
2452
2453 /**
2454 * <p>Splits the provided text into an array, separators specified,
2455 * preserving all tokens, including empty tokens created by adjacent
2456 * separators. This is an alternative to using StringTokenizer.</p>
2457 *
2458 * <p>The separator is not included in the returned String array.
2459 * Adjacent separators are treated as separators for empty tokens.
2460 * For more control over the split use the StrTokenizer class.</p>
2461 *
2462 * <p>A <code>null</code> input String returns <code>null</code>.
2463 * A <code>null</code> separatorChars splits on whitespace.</p>
2464 *
2465 * <pre>
2466 * StringUtils.splitPreserveAllTokens(null, *) = null
2467 * StringUtils.splitPreserveAllTokens("", *) = []
2468 * StringUtils.splitPreserveAllTokens("abc def", null) = ["abc", "def"]
2469 * StringUtils.splitPreserveAllTokens("abc def", " ") = ["abc", "def"]
2470 * StringUtils.splitPreserveAllTokens("abc def", " ") = ["abc", "", def"]
2471 * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2472 * StringUtils.splitPreserveAllTokens("ab:cd:ef:", ":") = ["ab", "cd", "ef", ""]
2473 * StringUtils.splitPreserveAllTokens("ab:cd:ef::", ":") = ["ab", "cd", "ef", "", ""]
2474 * StringUtils.splitPreserveAllTokens("ab::cd:ef", ":") = ["ab", "", cd", "ef"]
2475 * StringUtils.splitPreserveAllTokens(":cd:ef", ":") = ["", cd", "ef"]
2476 * StringUtils.splitPreserveAllTokens("::cd:ef", ":") = ["", "", cd", "ef"]
2477 * StringUtils.splitPreserveAllTokens(":cd:ef:", ":") = ["", cd", "ef", ""]
2478 * </pre>
2479 *
2480 * @param str the String to parse, may be <code>null</code>
2481 * @param separatorChars the characters used as the delimiters,
2482 * <code>null</code> splits on whitespace
2483 * @return an array of parsed Strings, <code>null</code> if null String input
2484 * @since 2.1
2485 */
2486 public static String[] splitPreserveAllTokens(String str, String separatorChars) {
2487 return splitWorker(str, separatorChars, -1, true);
2488 }
2489
2490 /**
2491 * <p>Splits the provided text into an array with a maximum length,
2492 * separators specified, preserving all tokens, including empty tokens
2493 * created by adjacent separators.</p>
2494 *
2495 * <p>The separator is not included in the returned String array.
2496 * Adjacent separators are treated as separators for empty tokens.
2497 * Adjacent separators are treated as one separator.</p>
2498 *
2499 * <p>A <code>null</code> input String returns <code>null</code>.
2500 * A <code>null</code> separatorChars splits on whitespace.</p>
2501 *
2502 * <p>If more than <code>max</code> delimited substrings are found, the last
2503 * returned string includes all characters after the first <code>max - 1</code>
2504 * returned strings (including separator characters).</p>
2505 *
2506 * <pre>
2507 * StringUtils.splitPreserveAllTokens(null, *, *) = null
2508 * StringUtils.splitPreserveAllTokens("", *, *) = []
2509 * StringUtils.splitPreserveAllTokens("ab de fg", null, 0) = ["ab", "cd", "ef"]
2510 * StringUtils.splitPreserveAllTokens("ab de fg", null, 0) = ["ab", "cd", "ef"]
2511 * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 0) = ["ab", "cd", "ef"]
2512 * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2513 * StringUtils.splitPreserveAllTokens("ab de fg", null, 2) = ["ab", " de fg"]
2514 * StringUtils.splitPreserveAllTokens("ab de fg", null, 3) = ["ab", "", " de fg"]
2515 * StringUtils.splitPreserveAllTokens("ab de fg", null, 4) = ["ab", "", "", "de fg"]
2516 * </pre>
2517 *
2518 * @param str the String to parse, may be <code>null</code>
2519 * @param separatorChars the characters used as the delimiters,
2520 * <code>null</code> splits on whitespace
2521 * @param max the maximum number of elements to include in the
2522 * array. A zero or negative value implies no limit
2523 * @return an array of parsed Strings, <code>null</code> if null String input
2524 * @since 2.1
2525 */
2526 public static String[] splitPreserveAllTokens(String str, String separatorChars, int max) {
2527 return splitWorker(str, separatorChars, max, true);
2528 }
2529
2530 /**
2531 * Performs the logic for the <code>split</code> and
2532 * <code>splitPreserveAllTokens</code> methods that return a maximum array
2533 * length.
2534 *
2535 * @param str the String to parse, may be <code>null</code>
2536 * @param separatorChars the separate character
2537 * @param max the maximum number of elements to include in the
2538 * array. A zero or negative value implies no limit.
2539 * @param preserveAllTokens if <code>true</code>, adjacent separators are
2540 * treated as empty token separators; if <code>false</code>, adjacent
2541 * separators are treated as one separator.
2542 * @return an array of parsed Strings, <code>null</code> if null String input
2543 */
2544 private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
2545 // Performance tuned for 2.0 (JDK1.4)
2546 // Direct code is quicker than StringTokenizer.
2547 // Also, StringTokenizer uses isSpace() not isWhitespace()
2548
2549 if (str == null) {
2550 return null;
2551 }
2552 int len = str.length();
2553 if (len == 0) {
2554 return ArrayUtils.EMPTY_STRING_ARRAY;
2555 }
2556 List<String> list = new ArrayList<String>();
2557 int sizePlus1 = 1;
2558 int i = 0, start = 0;
2559 boolean match = false;
2560 boolean lastMatch = false;
2561 if (separatorChars == null) {
2562 // Null separator means use whitespace
2563 while (i < len) {
2564 if (Character.isWhitespace(str.charAt(i))) {
2565 if (match || preserveAllTokens) {
2566 lastMatch = true;
2567 if (sizePlus1++ == max) {
2568 i = len;
2569 lastMatch = false;
2570 }
2571 list.add(str.substring(start, i));
2572 match = false;
2573 }
2574 start = ++i;
2575 continue;
2576 }
2577 lastMatch = false;
2578 match = true;
2579 i++;
2580 }
2581 } else if (separatorChars.length() == 1) {
2582 // Optimise 1 character case
2583 char sep = separatorChars.charAt(0);
2584 while (i < len) {
2585 if (str.charAt(i) == sep) {
2586 if (match || preserveAllTokens) {
2587 lastMatch = true;
2588 if (sizePlus1++ == max) {
2589 i = len;
2590 lastMatch = false;
2591 }
2592 list.add(str.substring(start, i));
2593 match = false;
2594 }
2595 start = ++i;
2596 continue;
2597 }
2598 lastMatch = false;
2599 match = true;
2600 i++;
2601 }
2602 } else {
2603 // standard case
2604 while (i < len) {
2605 if (separatorChars.indexOf(str.charAt(i)) >= 0) {
2606 if (match || preserveAllTokens) {
2607 lastMatch = true;
2608 if (sizePlus1++ == max) {
2609 i = len;
2610 lastMatch = false;
2611 }
2612 list.add(str.substring(start, i));
2613 match = false;
2614 }
2615 start = ++i;
2616 continue;
2617 }
2618 lastMatch = false;
2619 match = true;
2620 i++;
2621 }
2622 }
2623 if (match || (preserveAllTokens && lastMatch)) {
2624 list.add(str.substring(start, i));
2625 }
2626 return list.toArray(new String[list.size()]);
2627 }
2628
2629 /**
2630 * <p>Splits a String by Character type as returned by
2631 * <code>java.lang.Character.getType(char)</code>. Groups of contiguous
2632 * characters of the same type are returned as complete tokens.
2633 * <pre>
2634 * StringUtils.splitByCharacterType(null) = null
2635 * StringUtils.splitByCharacterType("") = []
2636 * StringUtils.splitByCharacterType("ab de fg") = ["ab", " ", "de", " ", "fg"]
2637 * StringUtils.splitByCharacterType("ab de fg") = ["ab", " ", "de", " ", "fg"]
2638 * StringUtils.splitByCharacterType("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
2639 * StringUtils.splitByCharacterType("number5") = ["number", "5"]
2640 * StringUtils.splitByCharacterType("fooBar") = ["foo", "B", "ar"]
2641 * StringUtils.splitByCharacterType("foo200Bar") = ["foo", "200", "B", "ar"]
2642 * StringUtils.splitByCharacterType("ASFRules") = ["ASFR", "ules"]
2643 * </pre>
2644 * @param str the String to split, may be <code>null</code>
2645 * @return an array of parsed Strings, <code>null</code> if null String input
2646 * @since 2.4
2647 */
2648 public static String[] splitByCharacterType(String str) {
2649 return splitByCharacterType(str, false);
2650 }
2651
2652 /**
2653 * <p>Splits a String by Character type as returned by
2654 * <code>java.lang.Character.getType(char)</code>. Groups of contiguous
2655 * characters of the same type are returned as complete tokens, with the
2656 * following exception: the character of type
2657 * <code>Character.UPPERCASE_LETTER</code>, if any, immediately
2658 * preceding a token of type <code>Character.LOWERCASE_LETTER</code>
2659 * will belong to the following token rather than to the preceding, if any,
2660 * <code>Character.UPPERCASE_LETTER</code> token.
2661 * <pre>
2662 * StringUtils.splitByCharacterTypeCamelCase(null) = null
2663 * StringUtils.splitByCharacterTypeCamelCase("") = []
2664 * StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
2665 * StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
2666 * StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
2667 * StringUtils.splitByCharacterTypeCamelCase("number5") = ["number", "5"]
2668 * StringUtils.splitByCharacterTypeCamelCase("fooBar") = ["foo", "Bar"]
2669 * StringUtils.splitByCharacterTypeCamelCase("foo200Bar") = ["foo", "200", "Bar"]
2670 * StringUtils.splitByCharacterTypeCamelCase("ASFRules") = ["ASF", "Rules"]
2671 * </pre>
2672 * @param str the String to split, may be <code>null</code>
2673 * @return an array of parsed Strings, <code>null</code> if null String input
2674 * @since 2.4
2675 */
2676 public static String[] splitByCharacterTypeCamelCase(String str) {
2677 return splitByCharacterType(str, true);
2678 }
2679
2680 /**
2681 * <p>Splits a String by Character type as returned by
2682 * <code>java.lang.Character.getType(char)</code>. Groups of contiguous
2683 * characters of the same type are returned as complete tokens, with the
2684 * following exception: if <code>camelCase</code> is <code>true</code>,
2685 * the character of type <code>Character.UPPERCASE_LETTER</code>, if any,
2686 * immediately preceding a token of type <code>Character.LOWERCASE_LETTER</code>
2687 * will belong to the following token rather than to the preceding, if any,
2688 * <code>Character.UPPERCASE_LETTER</code> token.
2689 * @param str the String to split, may be <code>null</code>
2690 * @param camelCase whether to use so-called "camel-case" for letter types
2691 * @return an array of parsed Strings, <code>null</code> if null String input
2692 * @since 2.4
2693 */
2694 private static String[] splitByCharacterType(String str, boolean camelCase) {
2695 if (str == null) {
2696 return null;
2697 }
2698 if (str.length() == 0) {
2699 return ArrayUtils.EMPTY_STRING_ARRAY;
2700 }
2701 char[] c = str.toCharArray();
2702 List<String> list = new ArrayList<String>();
2703 int tokenStart = 0;
2704 int currentType = Character.getType(c[tokenStart]);
2705 for (int pos = tokenStart + 1; pos < c.length; pos++) {
2706 int type = Character.getType(c[pos]);
2707 if (type == currentType) {
2708 continue;
2709 }
2710 if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) {
2711 int newTokenStart = pos - 1;
2712 if (newTokenStart != tokenStart) {
2713 list.add(new String(c, tokenStart, newTokenStart - tokenStart));
2714 tokenStart = newTokenStart;
2715 }
2716 } else {
2717 list.add(new String(c, tokenStart, pos - tokenStart));
2718 tokenStart = pos;
2719 }
2720 currentType = type;
2721 }
2722 list.add(new String(c, tokenStart, c.length - tokenStart));
2723 return list.toArray(new String[list.size()]);
2724 }
2725
2726 // Joining
2727 //-----------------------------------------------------------------------
2728 /**
2729 * <p>Joins the elements of the provided array into a single String
2730 * containing the provided list of elements.</p>
2731 *
2732 * <p>No separator is added to the joined String.
2733 * Null objects or empty strings within the array are represented by
2734 * empty strings.</p>
2735 *
2736 * <pre>
2737 * StringUtils.join(null) = null
2738 * StringUtils.join([]) = ""
2739 * StringUtils.join([null]) = ""
2740 * StringUtils.join(["a", "b", "c"]) = "abc"
2741 * StringUtils.join([null, "", "a"]) = "a"
2742 * </pre>
2743 *
2744 * @param array the array of values to join together, may be null
2745 * @return the joined String, <code>null</code> if null array input
2746 * @since 2.0
2747 */
2748 public static String join(Object[] array) {
2749 return join(array, null);
2750 }
2751
2752 /**
2753 * <p>Joins the elements of the provided array into a single String
2754 * containing the provided list of elements.</p>
2755 *
2756 * <p>No delimiter is added before or after the list.
2757 * Null objects or empty strings within the array are represented by
2758 * empty strings.</p>
2759 *
2760 * <pre>
2761 * StringUtils.join(null, *) = null
2762 * StringUtils.join([], *) = ""
2763 * StringUtils.join([null], *) = ""
2764 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
2765 * StringUtils.join(["a", "b", "c"], null) = "abc"
2766 * StringUtils.join([null, "", "a"], ';') = ";;a"
2767 * </pre>
2768 *
2769 * @param array the array of values to join together, may be null
2770 * @param separator the separator character to use
2771 * @return the joined String, <code>null</code> if null array input
2772 * @since 2.0
2773 */
2774 public static String join(Object[] array, char separator) {
2775 if (array == null) {
2776 return null;
2777 }
2778
2779 return join(array, separator, 0, array.length);
2780 }
2781
2782 /**
2783 * <p>Joins the elements of the provided array into a single String
2784 * containing the provided list of elements.</p>
2785 *
2786 * <p>No delimiter is added before or after the list.
2787 * Null objects or empty strings within the array are represented by
2788 * empty strings.</p>
2789 *
2790 * <pre>
2791 * StringUtils.join(null, *) = null
2792 * StringUtils.join([], *) = ""
2793 * StringUtils.join([null], *) = ""
2794 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
2795 * StringUtils.join(["a", "b", "c"], null) = "abc"
2796 * StringUtils.join([null, "", "a"], ';') = ";;a"
2797 * </pre>
2798 *
2799 * @param array the array of values to join together, may be null
2800 * @param separator the separator character to use
2801 * @param startIndex the first index to start joining from. It is
2802 * an error to pass in an end index past the end of the array
2803 * @param endIndex the index to stop joining from (exclusive). It is
2804 * an error to pass in an end index past the end of the array
2805 * @return the joined String, <code>null</code> if null array input
2806 * @since 2.0
2807 */
2808 public static String join(Object[] array, char separator, int startIndex, int endIndex) {
2809 if (array == null) {
2810 return null;
2811 }
2812 int bufSize = (endIndex - startIndex);
2813 if (bufSize <= 0) {
2814 return EMPTY;
2815 }
2816
2817 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length()) + 1);
2818 StringBuilder buf = new StringBuilder(bufSize);
2819
2820 for (int i = startIndex; i < endIndex; i++) {
2821 if (i > startIndex) {
2822 buf.append(separator);
2823 }
2824 if (array[i] != null) {
2825 buf.append(array[i]);
2826 }
2827 }
2828 return buf.toString();
2829 }
2830
2831
2832 /**
2833 * <p>Joins the elements of the provided array into a single String
2834 * containing the provided list of elements.</p>
2835 *
2836 * <p>No delimiter is added before or after the list.
2837 * A <code>null</code> separator is the same as an empty String ("").
2838 * Null objects or empty strings within the array are represented by
2839 * empty strings.</p>
2840 *
2841 * <pre>
2842 * StringUtils.join(null, *) = null
2843 * StringUtils.join([], *) = ""
2844 * StringUtils.join([null], *) = ""
2845 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
2846 * StringUtils.join(["a", "b", "c"], null) = "abc"
2847 * StringUtils.join(["a", "b", "c"], "") = "abc"
2848 * StringUtils.join([null, "", "a"], ',') = ",,a"
2849 * </pre>
2850 *
2851 * @param array the array of values to join together, may be null
2852 * @param separator the separator character to use, null treated as ""
2853 * @return the joined String, <code>null</code> if null array input
2854 */
2855 public static String join(Object[] array, String separator) {
2856 if (array == null) {
2857 return null;
2858 }
2859 return join(array, separator, 0, array.length);
2860 }
2861
2862 /**
2863 * <p>Joins the elements of the provided array into a single String
2864 * containing the provided list of elements.</p>
2865 *
2866 * <p>No delimiter is added before or after the list.
2867 * A <code>null</code> separator is the same as an empty String ("").
2868 * Null objects or empty strings within the array are represented by
2869 * empty strings.</p>
2870 *
2871 * <pre>
2872 * StringUtils.join(null, *) = null
2873 * StringUtils.join([], *) = ""
2874 * StringUtils.join([null], *) = ""
2875 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
2876 * StringUtils.join(["a", "b", "c"], null) = "abc"
2877 * StringUtils.join(["a", "b", "c"], "") = "abc"
2878 * StringUtils.join([null, "", "a"], ',') = ",,a"
2879 * </pre>
2880 *
2881 * @param array the array of values to join together, may be null
2882 * @param separator the separator character to use, null treated as ""
2883 * @param startIndex the first index to start joining from. It is
2884 * an error to pass in an end index past the end of the array
2885 * @param endIndex the index to stop joining from (exclusive). It is
2886 * an error to pass in an end index past the end of the array
2887 * @return the joined String, <code>null</code> if null array input
2888 */
2889 public static String join(Object[] array, String separator, int startIndex, int endIndex) {
2890 if (array == null) {
2891 return null;
2892 }
2893 if (separator == null) {
2894 separator = EMPTY;
2895 }
2896
2897 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
2898 // (Assuming that all Strings are roughly equally long)
2899 int bufSize = (endIndex - startIndex);
2900 if (bufSize <= 0) {
2901 return EMPTY;
2902 }
2903
2904 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length())
2905 + separator.length());
2906
2907 StringBuilder buf = new StringBuilder(bufSize);
2908
2909 for (int i = startIndex; i < endIndex; i++) {
2910 if (i > startIndex) {
2911 buf.append(separator);
2912 }
2913 if (array[i] != null) {
2914 buf.append(array[i]);
2915 }
2916 }
2917 return buf.toString();
2918 }
2919
2920 /**
2921 * <p>Joins the elements of the provided <code>Iterator</code> into
2922 * a single String containing the provided elements.</p>
2923 *
2924 * <p>No delimiter is added before or after the list. Null objects or empty
2925 * strings within the iteration are represented by empty strings.</p>
2926 *
2927 * <p>See the examples here: {@link #join(Object[],char)}. </p>
2928 *
2929 * @param iterator the <code>Iterator</code> of values to join together, may be null
2930 * @param separator the separator character to use
2931 * @return the joined String, <code>null</code> if null iterator input
2932 * @since 2.0
2933 */
2934 public static String join(Iterator<?> iterator, char separator) {
2935
2936 // handle null, zero and one elements before building a buffer
2937 if (iterator == null) {
2938 return null;
2939 }
2940 if (!iterator.hasNext()) {
2941 return EMPTY;
2942 }
2943 Object first = iterator.next();
2944 if (!iterator.hasNext()) {
2945 return ObjectUtils.toString(first);
2946 }
2947
2948 // two or more elements
2949 StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small