001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.lang;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.Iterator;
022 import java.util.List;
023 import java.util.Locale;
024
025 /**
026 * <p>Operations on {@link java.lang.String} that are
027 * <code>null</code> safe.</p>
028 *
029 * <ul>
030 * <li><b>IsEmpty/IsBlank</b>
031 * - checks if a String contains text</li>
032 * <li><b>Trim/Strip</b>
033 * - removes leading and trailing whitespace</li>
034 * <li><b>Equals</b>
035 * - compares two strings null-safe</li>
036 * <li><b>startsWith</b>
037 * - check if a String starts with a prefix null-safe</li>
038 * <li><b>endsWith</b>
039 * - check if a String ends with a suffix null-safe</li>
040 * <li><b>IndexOf/LastIndexOf/Contains</b>
041 * - null-safe index-of checks
042 * <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
043 * - index-of any of a set of Strings</li>
044 * <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
045 * - does String contains only/none/any of these characters</li>
046 * <li><b>Substring/Left/Right/Mid</b>
047 * - null-safe substring extractions</li>
048 * <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
049 * - substring extraction relative to other strings</li>
050 * <li><b>Split/Join</b>
051 * - splits a String into an array of substrings and vice versa</li>
052 * <li><b>Remove/Delete</b>
053 * - removes part of a String</li>
054 * <li><b>Replace/Overlay</b>
055 * - Searches a String and replaces one String with another</li>
056 * <li><b>Chomp/Chop</b>
057 * - removes the last part of a String</li>
058 * <li><b>LeftPad/RightPad/Center/Repeat</b>
059 * - pads a String</li>
060 * <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
061 * - changes the case of a String</li>
062 * <li><b>CountMatches</b>
063 * - counts the number of occurrences of one String in another</li>
064 * <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
065 * - checks the characters in a String</li>
066 * <li><b>DefaultString</b>
067 * - protects against a null input String</li>
068 * <li><b>Reverse/ReverseDelimited</b>
069 * - reverses a String</li>
070 * <li><b>Abbreviate</b>
071 * - abbreviates a string using ellipsis</li>
072 * <li><b>Difference</b>
073 * - compares Strings and reports on their differences</li>
074 * <li><b>LevensteinDistance</b>
075 * - the number of changes needed to change one String into another</li>
076 * </ul>
077 *
078 * <p>The <code>StringUtils</code> class defines certain words related to
079 * String handling.</p>
080 *
081 * <ul>
082 * <li>null - <code>null</code></li>
083 * <li>empty - a zero-length string (<code>""</code>)</li>
084 * <li>space - the space character (<code>' '</code>, char 32)</li>
085 * <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li>
086 * <li>trim - the characters <= 32 as in {@link String#trim()}</li>
087 * </ul>
088 *
089 * <p><code>StringUtils</code> handles <code>null</code> input Strings quietly.
090 * That is to say that a <code>null</code> input will return <code>null</code>.
091 * Where a <code>boolean</code> or <code>int</code> is being returned
092 * details vary by method.</p>
093 *
094 * <p>A side effect of the <code>null</code> handling is that a
095 * <code>NullPointerException</code> should be considered a bug in
096 * <code>StringUtils</code> (except for deprecated methods).</p>
097 *
098 * <p>Methods in this class give sample code to explain their operation.
099 * The symbol <code>*</code> is used to indicate any input including <code>null</code>.</p>
100 *
101 * @see java.lang.String
102 * @author Apache Software Foundation
103 * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</a>
104 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
105 * @author Daniel L. Rall
106 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
107 * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
108 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
109 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
110 * @author Holger Krauth
111 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
112 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
113 * @author Arun Mammen Thomas
114 * @author Gary Gregory
115 * @author Phil Steitz
116 * @author Al Chou
117 * @author Michael Davey
118 * @author Reuben Sivan
119 * @author Chris Hyzer
120 * @author Scott Johnson
121 * @since 1.0
122 * @version $Id: StringUtils.java 911986 2010-02-19 21:19:05Z niallp $
123 */
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(String 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(String 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(String 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(String str) {
257 return !StringUtils.isBlank(str);
258 }
259
260 // Trim
261 //-----------------------------------------------------------------------
262 /**
263 * <p>Removes control characters (char <= 32) from both
264 * ends of this String, handling <code>null</code> by returning
265 * an empty String ("").</p>
266 *
267 * <pre>
268 * StringUtils.clean(null) = ""
269 * StringUtils.clean("") = ""
270 * StringUtils.clean("abc") = "abc"
271 * StringUtils.clean(" abc ") = "abc"
272 * StringUtils.clean(" ") = ""
273 * </pre>
274 *
275 * @see java.lang.String#trim()
276 * @param str the String to clean, may be null
277 * @return the trimmed text, never <code>null</code>
278 * @deprecated Use the clearer named {@link #trimToEmpty(String)}.
279 * Method will be removed in Commons Lang 3.0.
280 */
281 public static String clean(String str) {
282 return str == null ? EMPTY : str.trim();
283 }
284
285 /**
286 * <p>Removes control characters (char <= 32) from both
287 * ends of this String, handling <code>null</code> by returning
288 * <code>null</code>.</p>
289 *
290 * <p>The String is trimmed using {@link String#trim()}.
291 * Trim removes start and end characters <= 32.
292 * To strip whitespace use {@link #strip(String)}.</p>
293 *
294 * <p>To trim your choice of characters, use the
295 * {@link #strip(String, String)} methods.</p>
296 *
297 * <pre>
298 * StringUtils.trim(null) = null
299 * StringUtils.trim("") = ""
300 * StringUtils.trim(" ") = ""
301 * StringUtils.trim("abc") = "abc"
302 * StringUtils.trim(" abc ") = "abc"
303 * </pre>
304 *
305 * @param str the String to be trimmed, may be null
306 * @return the trimmed string, <code>null</code> if null String input
307 */
308 public static String trim(String str) {
309 return str == null ? null : str.trim();
310 }
311
312 /**
313 * <p>Removes control characters (char <= 32) from both
314 * ends of this String returning <code>null</code> if the String is
315 * empty ("") after the trim or if it is <code>null</code>.
316 *
317 * <p>The String is trimmed using {@link String#trim()}.
318 * Trim removes start and end characters <= 32.
319 * To strip whitespace use {@link #stripToNull(String)}.</p>
320 *
321 * <pre>
322 * StringUtils.trimToNull(null) = null
323 * StringUtils.trimToNull("") = null
324 * StringUtils.trimToNull(" ") = null
325 * StringUtils.trimToNull("abc") = "abc"
326 * StringUtils.trimToNull(" abc ") = "abc"
327 * </pre>
328 *
329 * @param str the String to be trimmed, may be null
330 * @return the trimmed String,
331 * <code>null</code> if only chars <= 32, empty or null String input
332 * @since 2.0
333 */
334 public static String trimToNull(String str) {
335 String ts = trim(str);
336 return isEmpty(ts) ? null : ts;
337 }
338
339 /**
340 * <p>Removes control characters (char <= 32) from both
341 * ends of this String returning an empty String ("") if the String
342 * is empty ("") after the trim or if it is <code>null</code>.
343 *
344 * <p>The String is trimmed using {@link String#trim()}.
345 * Trim removes start and end characters <= 32.
346 * To strip whitespace use {@link #stripToEmpty(String)}.</p>
347 *
348 * <pre>
349 * StringUtils.trimToEmpty(null) = ""
350 * StringUtils.trimToEmpty("") = ""
351 * StringUtils.trimToEmpty(" ") = ""
352 * StringUtils.trimToEmpty("abc") = "abc"
353 * StringUtils.trimToEmpty(" abc ") = "abc"
354 * </pre>
355 *
356 * @param str the String to be trimmed, may be null
357 * @return the trimmed String, or an empty String if <code>null</code> input
358 * @since 2.0
359 */
360 public static String trimToEmpty(String str) {
361 return str == null ? EMPTY : str.trim();
362 }
363
364 // Stripping
365 //-----------------------------------------------------------------------
366 /**
367 * <p>Strips whitespace from the start and end of a String.</p>
368 *
369 * <p>This is similar to {@link #trim(String)} but removes whitespace.
370 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
371 *
372 * <p>A <code>null</code> input String returns <code>null</code>.</p>
373 *
374 * <pre>
375 * StringUtils.strip(null) = null
376 * StringUtils.strip("") = ""
377 * StringUtils.strip(" ") = ""
378 * StringUtils.strip("abc") = "abc"
379 * StringUtils.strip(" abc") = "abc"
380 * StringUtils.strip("abc ") = "abc"
381 * StringUtils.strip(" abc ") = "abc"
382 * StringUtils.strip(" ab c ") = "ab c"
383 * </pre>
384 *
385 * @param str the String to remove whitespace from, may be null
386 * @return the stripped String, <code>null</code> if null String input
387 */
388 public static String strip(String str) {
389 return strip(str, null);
390 }
391
392 /**
393 * <p>Strips whitespace from the start and end of a String returning
394 * <code>null</code> if the String is empty ("") after the strip.</p>
395 *
396 * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.
397 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
398 *
399 * <pre>
400 * StringUtils.stripToNull(null) = null
401 * StringUtils.stripToNull("") = null
402 * StringUtils.stripToNull(" ") = null
403 * StringUtils.stripToNull("abc") = "abc"
404 * StringUtils.stripToNull(" abc") = "abc"
405 * StringUtils.stripToNull("abc ") = "abc"
406 * StringUtils.stripToNull(" abc ") = "abc"
407 * StringUtils.stripToNull(" ab c ") = "ab c"
408 * </pre>
409 *
410 * @param str the String to be stripped, may be null
411 * @return the stripped String,
412 * <code>null</code> if whitespace, empty or null String input
413 * @since 2.0
414 */
415 public static String stripToNull(String str) {
416 if (str == null) {
417 return null;
418 }
419 str = strip(str, null);
420 return str.length() == 0 ? null : str;
421 }
422
423 /**
424 * <p>Strips whitespace from the start and end of a String returning
425 * an empty String if <code>null</code> input.</p>
426 *
427 * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.
428 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
429 *
430 * <pre>
431 * StringUtils.stripToEmpty(null) = ""
432 * StringUtils.stripToEmpty("") = ""
433 * StringUtils.stripToEmpty(" ") = ""
434 * StringUtils.stripToEmpty("abc") = "abc"
435 * StringUtils.stripToEmpty(" abc") = "abc"
436 * StringUtils.stripToEmpty("abc ") = "abc"
437 * StringUtils.stripToEmpty(" abc ") = "abc"
438 * StringUtils.stripToEmpty(" ab c ") = "ab c"
439 * </pre>
440 *
441 * @param str the String to be stripped, may be null
442 * @return the trimmed String, or an empty String if <code>null</code> input
443 * @since 2.0
444 */
445 public static String stripToEmpty(String str) {
446 return str == null ? EMPTY : strip(str, null);
447 }
448
449 /**
450 * <p>Strips any of a set of characters from the start and end of a String.
451 * This is similar to {@link String#trim()} but allows the characters
452 * to be stripped to be controlled.</p>
453 *
454 * <p>A <code>null</code> input String returns <code>null</code>.
455 * An empty string ("") input returns the empty string.</p>
456 *
457 * <p>If the stripChars String is <code>null</code>, whitespace is
458 * stripped as defined by {@link Character#isWhitespace(char)}.
459 * Alternatively use {@link #strip(String)}.</p>
460 *
461 * <pre>
462 * StringUtils.strip(null, *) = null
463 * StringUtils.strip("", *) = ""
464 * StringUtils.strip("abc", null) = "abc"
465 * StringUtils.strip(" abc", null) = "abc"
466 * StringUtils.strip("abc ", null) = "abc"
467 * StringUtils.strip(" abc ", null) = "abc"
468 * StringUtils.strip(" abcyx", "xyz") = " abc"
469 * </pre>
470 *
471 * @param str the String to remove characters from, may be null
472 * @param stripChars the characters to remove, null treated as whitespace
473 * @return the stripped String, <code>null</code> if null String input
474 */
475 public static String strip(String str, String stripChars) {
476 if (isEmpty(str)) {
477 return str;
478 }
479 str = stripStart(str, stripChars);
480 return stripEnd(str, stripChars);
481 }
482
483 /**
484 * <p>Strips any of a set of characters from the start of a String.</p>
485 *
486 * <p>A <code>null</code> input String returns <code>null</code>.
487 * An empty string ("") input returns the empty string.</p>
488 *
489 * <p>If the stripChars String is <code>null</code>, whitespace is
490 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
491 *
492 * <pre>
493 * StringUtils.stripStart(null, *) = null
494 * StringUtils.stripStart("", *) = ""
495 * StringUtils.stripStart("abc", "") = "abc"
496 * StringUtils.stripStart("abc", null) = "abc"
497 * StringUtils.stripStart(" abc", null) = "abc"
498 * StringUtils.stripStart("abc ", null) = "abc "
499 * StringUtils.stripStart(" abc ", null) = "abc "
500 * StringUtils.stripStart("yxabc ", "xyz") = "abc "
501 * </pre>
502 *
503 * @param str the String to remove characters from, may be null
504 * @param stripChars the characters to remove, null treated as whitespace
505 * @return the stripped String, <code>null</code> if null String input
506 */
507 public static String stripStart(String str, String stripChars) {
508 int strLen;
509 if (str == null || (strLen = str.length()) == 0) {
510 return str;
511 }
512 int start = 0;
513 if (stripChars == null) {
514 while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {
515 start++;
516 }
517 } else if (stripChars.length() == 0) {
518 return str;
519 } else {
520 while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) {
521 start++;
522 }
523 }
524 return str.substring(start);
525 }
526
527 /**
528 * <p>Strips any of a set of characters from the end of a String.</p>
529 *
530 * <p>A <code>null</code> input String returns <code>null</code>.
531 * An empty string ("") input returns the empty string.</p>
532 *
533 * <p>If the stripChars String is <code>null</code>, whitespace is
534 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
535 *
536 * <pre>
537 * StringUtils.stripEnd(null, *) = null
538 * StringUtils.stripEnd("", *) = ""
539 * StringUtils.stripEnd("abc", "") = "abc"
540 * StringUtils.stripEnd("abc", null) = "abc"
541 * StringUtils.stripEnd(" abc", null) = " abc"
542 * StringUtils.stripEnd("abc ", null) = "abc"
543 * StringUtils.stripEnd(" abc ", null) = " abc"
544 * StringUtils.stripEnd(" abcyx", "xyz") = " abc"
545 * </pre>
546 *
547 * @param str the String to remove characters from, may be null
548 * @param stripChars the characters to remove, null treated as whitespace
549 * @return the stripped String, <code>null</code> if null String input
550 */
551 public static String stripEnd(String str, String stripChars) {
552 int end;
553 if (str == null || (end = str.length()) == 0) {
554 return str;
555 }
556
557 if (stripChars == null) {
558 while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
559 end--;
560 }
561 } else if (stripChars.length() == 0) {
562 return str;
563 } else {
564 while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
565 end--;
566 }
567 }
568 return str.substring(0, end);
569 }
570
571 // StripAll
572 //-----------------------------------------------------------------------
573 /**
574 * <p>Strips whitespace from the start and end of every String in an array.
575 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
576 *
577 * <p>A new array is returned each time, except for length zero.
578 * A <code>null</code> array will return <code>null</code>.
579 * An empty array will return itself.
580 * A <code>null</code> array entry will be ignored.</p>
581 *
582 * <pre>
583 * StringUtils.stripAll(null) = null
584 * StringUtils.stripAll([]) = []
585 * StringUtils.stripAll(["abc", " abc"]) = ["abc", "abc"]
586 * StringUtils.stripAll(["abc ", null]) = ["abc", null]
587 * </pre>
588 *
589 * @param strs the array to remove whitespace from, may be null
590 * @return the stripped Strings, <code>null</code> if null array input
591 */
592 public static String[] stripAll(String[] strs) {
593 return stripAll(strs, null);
594 }
595
596 /**
597 * <p>Strips any of a set of characters from the start and end of every
598 * String in an array.</p>
599 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
600 *
601 * <p>A new array is returned each time, except for length zero.
602 * A <code>null</code> array will return <code>null</code>.
603 * An empty array will return itself.
604 * A <code>null</code> array entry will be ignored.
605 * A <code>null</code> stripChars will strip whitespace as defined by
606 * {@link Character#isWhitespace(char)}.</p>
607 *
608 * <pre>
609 * StringUtils.stripAll(null, *) = null
610 * StringUtils.stripAll([], *) = []
611 * StringUtils.stripAll(["abc", " abc"], null) = ["abc", "abc"]
612 * StringUtils.stripAll(["abc ", null], null) = ["abc", null]
613 * StringUtils.stripAll(["abc ", null], "yz") = ["abc ", null]
614 * StringUtils.stripAll(["yabcz", null], "yz") = ["abc", null]
615 * </pre>
616 *
617 * @param strs the array to remove characters from, may be null
618 * @param stripChars the characters to remove, null treated as whitespace
619 * @return the stripped Strings, <code>null</code> if null array input
620 */
621 public static String[] stripAll(String[] strs, String stripChars) {
622 int strsLen;
623 if (strs == null || (strsLen = strs.length) == 0) {
624 return strs;
625 }
626 String[] newArr = new String[strsLen];
627 for (int i = 0; i < strsLen; i++) {
628 newArr[i] = strip(strs[i], stripChars);
629 }
630 return newArr;
631 }
632
633 // Equals
634 //-----------------------------------------------------------------------
635 /**
636 * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
637 *
638 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
639 * references are considered to be equal. The comparison is case sensitive.</p>
640 *
641 * <pre>
642 * StringUtils.equals(null, null) = true
643 * StringUtils.equals(null, "abc") = false
644 * StringUtils.equals("abc", null) = false
645 * StringUtils.equals("abc", "abc") = true
646 * StringUtils.equals("abc", "ABC") = false
647 * </pre>
648 *
649 * @see java.lang.String#equals(Object)
650 * @param str1 the first String, may be null
651 * @param str2 the second String, may be null
652 * @return <code>true</code> if the Strings are equal, case sensitive, or
653 * both <code>null</code>
654 */
655 public static boolean equals(String str1, String str2) {
656 return str1 == null ? str2 == null : str1.equals(str2);
657 }
658
659 /**
660 * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring
661 * the case.</p>
662 *
663 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
664 * references are considered equal. Comparison is case insensitive.</p>
665 *
666 * <pre>
667 * StringUtils.equalsIgnoreCase(null, null) = true
668 * StringUtils.equalsIgnoreCase(null, "abc") = false
669 * StringUtils.equalsIgnoreCase("abc", null) = false
670 * StringUtils.equalsIgnoreCase("abc", "abc") = true
671 * StringUtils.equalsIgnoreCase("abc", "ABC") = true
672 * </pre>
673 *
674 * @see java.lang.String#equalsIgnoreCase(String)
675 * @param str1 the first String, may be null
676 * @param str2 the second String, may be null
677 * @return <code>true</code> if the Strings are equal, case insensitive, or
678 * both <code>null</code>
679 */
680 public static boolean equalsIgnoreCase(String str1, String str2) {
681 return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
682 }
683
684 // IndexOf
685 //-----------------------------------------------------------------------
686 /**
687 * <p>Finds the first index within a String, handling <code>null</code>.
688 * This method uses {@link String#indexOf(int)}.</p>
689 *
690 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p>
691 *
692 * <pre>
693 * StringUtils.indexOf(null, *) = -1
694 * StringUtils.indexOf("", *) = -1
695 * StringUtils.indexOf("aabaabaa", 'a') = 0
696 * StringUtils.indexOf("aabaabaa", 'b') = 2
697 * </pre>
698 *
699 * @param str the String to check, may be null
700 * @param searchChar the character to find
701 * @return the first index of the search character,
702 * -1 if no match or <code>null</code> string input
703 * @since 2.0
704 */
705 public static int indexOf(String str, char searchChar) {
706 if (isEmpty(str)) {
707 return -1;
708 }
709 return str.indexOf(searchChar);
710 }
711
712 /**
713 * <p>Finds the first index within a String from a start position,
714 * handling <code>null</code>.
715 * This method uses {@link String#indexOf(int, int)}.</p>
716 *
717 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
718 * A negative start position is treated as zero.
719 * A start position greater than the string length returns <code>-1</code>.</p>
720 *
721 * <pre>
722 * StringUtils.indexOf(null, *, *) = -1
723 * StringUtils.indexOf("", *, *) = -1
724 * StringUtils.indexOf("aabaabaa", 'b', 0) = 2
725 * StringUtils.indexOf("aabaabaa", 'b', 3) = 5
726 * StringUtils.indexOf("aabaabaa", 'b', 9) = -1
727 * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
728 * </pre>
729 *
730 * @param str the String to check, may be null
731 * @param searchChar the character to find
732 * @param startPos the start position, negative treated as zero
733 * @return the first index of the search character,
734 * -1 if no match or <code>null</code> string input
735 * @since 2.0
736 */
737 public static int indexOf(String str, char searchChar, int startPos) {
738 if (isEmpty(str)) {
739 return -1;
740 }
741 return str.indexOf(searchChar, startPos);
742 }
743
744 /**
745 * <p>Finds the first index within a String, handling <code>null</code>.
746 * This method uses {@link String#indexOf(String)}.</p>
747 *
748 * <p>A <code>null</code> String will return <code>-1</code>.</p>
749 *
750 * <pre>
751 * StringUtils.indexOf(null, *) = -1
752 * StringUtils.indexOf(*, null) = -1
753 * StringUtils.indexOf("", "") = 0
754 * StringUtils.indexOf("aabaabaa", "a") = 0
755 * StringUtils.indexOf("aabaabaa", "b") = 2
756 * StringUtils.indexOf("aabaabaa", "ab") = 1
757 * StringUtils.indexOf("aabaabaa", "") = 0
758 * </pre>
759 *
760 * @param str the String to check, may be null
761 * @param searchStr the String to find, may be null
762 * @return the first index of the search String,
763 * -1 if no match or <code>null</code> string input
764 * @since 2.0
765 */
766 public static int indexOf(String str, String searchStr) {
767 if (str == null || searchStr == null) {
768 return -1;
769 }
770 return str.indexOf(searchStr);
771 }
772
773 /**
774 * <p>Finds the n-th index within a String, handling <code>null</code>.
775 * This method uses {@link String#indexOf(String)}.</p>
776 *
777 * <p>A <code>null</code> String will return <code>-1</code>.</p>
778 *
779 * <pre>
780 * StringUtils.ordinalIndexOf(null, *, *) = -1
781 * StringUtils.ordinalIndexOf(*, null, *) = -1
782 * StringUtils.ordinalIndexOf("", "", *) = 0
783 * StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0
784 * StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1
785 * StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2
786 * StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5
787 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
788 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
789 * StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0
790 * StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0
791 * </pre>
792 *
793 * <p>Note that 'head(String str, int n)' may be implemented as: </p>
794 *
795 * <pre>
796 * str.substring(0, lastOrdinalIndexOf(str, "\n", n))
797 * </pre>
798 *
799 * @param str the String to check, may be null
800 * @param searchStr the String to find, may be null
801 * @param ordinal the n-th <code>searchStr</code> to find
802 * @return the n-th index of the search String,
803 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input
804 * @since 2.1
805 */
806 public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
807 return ordinalIndexOf(str, searchStr, ordinal, false);
808 }
809
810 /**
811 * <p>Finds the n-th index within a String, handling <code>null</code>.
812 * This method uses {@link String#indexOf(String)}.</p>
813 *
814 * <p>A <code>null</code> String will return <code>-1</code>.</p>
815 *
816 * @param str the String to check, may be null
817 * @param searchStr the String to find, may be null
818 * @param ordinal the n-th <code>searchStr</code> to find
819 * @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf()
820 * @return the n-th index of the search String,
821 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input
822 */
823 // Shared code between ordinalIndexOf(String,String,int) and lastOrdinalIndexOf(String,String,int)
824 private static int ordinalIndexOf(String str, String searchStr, int ordinal, boolean lastIndex) {
825 if (str == null || searchStr == null || ordinal <= 0) {
826 return INDEX_NOT_FOUND;
827 }
828 if (searchStr.length() == 0) {
829 return lastIndex ? str.length() : 0;
830 }
831 int found = 0;
832 int index = lastIndex ? str.length() : INDEX_NOT_FOUND;
833 do {
834 if(lastIndex) {
835 index = str.lastIndexOf(searchStr, index - 1);
836 } else {
837 index = str.indexOf(searchStr, index + 1);
838 }
839 if (index < 0) {
840 return index;
841 }
842 found++;
843 } while (found < ordinal);
844 return index;
845 }
846
847 /**
848 * <p>Finds the first index within a String, handling <code>null</code>.
849 * This method uses {@link String#indexOf(String, int)}.</p>
850 *
851 * <p>A <code>null</code> String will return <code>-1</code>.
852 * A negative start position is treated as zero.
853 * An empty ("") search String always matches.
854 * A start position greater than the string length only matches
855 * an empty search String.</p>
856 *
857 * <pre>
858 * StringUtils.indexOf(null, *, *) = -1
859 * StringUtils.indexOf(*, null, *) = -1
860 * StringUtils.indexOf("", "", 0) = 0
861 * StringUtils.indexOf("aabaabaa", "a", 0) = 0
862 * StringUtils.indexOf("aabaabaa", "b", 0) = 2
863 * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
864 * StringUtils.indexOf("aabaabaa", "b", 3) = 5
865 * StringUtils.indexOf("aabaabaa", "b", 9) = -1
866 * StringUtils.indexOf("aabaabaa", "b", -1) = 2
867 * StringUtils.indexOf("aabaabaa", "", 2) = 2
868 * StringUtils.indexOf("abc", "", 9) = 3
869 * </pre>
870 *
871 * @param str the String to check, may be null
872 * @param searchStr the String to find, may be null
873 * @param startPos the start position, negative treated as zero
874 * @return the first index of the search String,
875 * -1 if no match or <code>null</code> string input
876 * @since 2.0
877 */
878 public static int indexOf(String str, String searchStr, int startPos) {
879 if (str == null || searchStr == null) {
880 return -1;
881 }
882 // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence
883 if (searchStr.length() == 0 && startPos >= str.length()) {
884 return str.length();
885 }
886 return str.indexOf(searchStr, startPos);
887 }
888
889 /**
890 * <p>Case in-sensitive find of the first index within a String.</p>
891 *
892 * <p>A <code>null</code> String will return <code>-1</code>.
893 * A negative start position is treated as zero.
894 * An empty ("") search String always matches.
895 * A start position greater than the string length only matches
896 * an empty search String.</p>
897 *
898 * <pre>
899 * StringUtils.indexOfIgnoreCase(null, *) = -1
900 * StringUtils.indexOfIgnoreCase(*, null) = -1
901 * StringUtils.indexOfIgnoreCase("", "") = 0
902 * StringUtils.indexOfIgnoreCase("aabaabaa", "a") = 0
903 * StringUtils.indexOfIgnoreCase("aabaabaa", "b") = 2
904 * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1
905 * </pre>
906 *
907 * @param str the String to check, may be null
908 * @param searchStr the String to find, may be null
909 * @return the first index of the search String,
910 * -1 if no match or <code>null</code> string input
911 * @since 2.5
912 */
913 public static int indexOfIgnoreCase(String str, String searchStr) {
914 return indexOfIgnoreCase(str, searchStr, 0);
915 }
916
917 /**
918 * <p>Case in-sensitive find of the first index within a String
919 * from the specified position.</p>
920 *
921 * <p>A <code>null</code> String will return <code>-1</code>.
922 * A negative start position is treated as zero.
923 * An empty ("") search String always matches.
924 * A start position greater than the string length only matches
925 * an empty search String.</p>
926 *
927 * <pre>
928 * StringUtils.indexOfIgnoreCase(null, *, *) = -1
929 * StringUtils.indexOfIgnoreCase(*, null, *) = -1
930 * StringUtils.indexOfIgnoreCase("", "", 0) = 0
931 * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
932 * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
933 * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
934 * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
935 * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
936 * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
937 * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2) = 2
938 * StringUtils.indexOfIgnoreCase("abc", "", 9) = 3
939 * </pre>
940 *
941 * @param str the String to check, may be null
942 * @param searchStr the String to find, may be null
943 * @param startPos the start position, negative treated as zero
944 * @return the first index of the search String,
945 * -1 if no match or <code>null</code> string input
946 * @since 2.5
947 */
948 public static int indexOfIgnoreCase(String str, String searchStr, int startPos) {
949 if (str == null || searchStr == null) {
950 return -1;
951 }
952 if (startPos < 0) {
953 startPos = 0;
954 }
955 int endLimit = (str.length() - searchStr.length()) + 1;
956 if (startPos > endLimit) {
957 return -1;
958 }
959 if (searchStr.length() == 0) {
960 return startPos;
961 }
962 for (int i = startPos; i < endLimit; i++) {
963 if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) {
964 return i;
965 }
966 }
967 return -1;
968 }
969
970 // LastIndexOf
971 //-----------------------------------------------------------------------
972 /**
973 * <p>Finds the last index within a String, handling <code>null</code>.
974 * This method uses {@link String#lastIndexOf(int)}.</p>
975 *
976 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p>
977 *
978 * <pre>
979 * StringUtils.lastIndexOf(null, *) = -1
980 * StringUtils.lastIndexOf("", *) = -1
981 * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
982 * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
983 * </pre>
984 *
985 * @param str the String to check, may be null
986 * @param searchChar the character to find
987 * @return the last index of the search character,
988 * -1 if no match or <code>null</code> string input
989 * @since 2.0
990 */
991 public static int lastIndexOf(String str, char searchChar) {
992 if (isEmpty(str)) {
993 return -1;
994 }
995 return str.lastIndexOf(searchChar);
996 }
997
998 /**
999 * <p>Finds the last index within a String from a start position,
1000 * handling <code>null</code>.
1001 * This method uses {@link String#lastIndexOf(int, int)}.</p>
1002 *
1003 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
1004 * A negative start position returns <code>-1</code>.
1005 * A start position greater than the string length searches the whole string.</p>
1006 *
1007 * <pre>
1008 * StringUtils.lastIndexOf(null, *, *) = -1
1009 * StringUtils.lastIndexOf("", *, *) = -1
1010 * StringUtils.lastIndexOf("aabaabaa", 'b', 8) = 5
1011 * StringUtils.lastIndexOf("aabaabaa", 'b', 4) = 2
1012 * StringUtils.lastIndexOf("aabaabaa", 'b', 0) = -1
1013 * StringUtils.lastIndexOf("aabaabaa", 'b', 9) = 5
1014 * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
1015 * StringUtils.lastIndexOf("aabaabaa", 'a', 0) = 0
1016 * </pre>
1017 *
1018 * @param str the String to check, may be null
1019 * @param searchChar the character to find
1020 * @param startPos the start position
1021 * @return the last index of the search character,
1022 * -1 if no match or <code>null</code> string input
1023 * @since 2.0
1024 */
1025 public static int lastIndexOf(String str, char searchChar, int startPos) {
1026 if (isEmpty(str)) {
1027 return -1;
1028 }
1029 return str.lastIndexOf(searchChar, startPos);
1030 }
1031
1032 /**
1033 * <p>Finds the last index within a String, handling <code>null</code>.
1034 * This method uses {@link String#lastIndexOf(String)}.</p>
1035 *
1036 * <p>A <code>null</code> String will return <code>-1</code>.</p>
1037 *
1038 * <pre>
1039 * StringUtils.lastIndexOf(null, *) = -1
1040 * StringUtils.lastIndexOf(*, null) = -1
1041 * StringUtils.lastIndexOf("", "") = 0
1042 * StringUtils.lastIndexOf("aabaabaa", "a") = 0
1043 * StringUtils.lastIndexOf("aabaabaa", "b") = 2
1044 * StringUtils.lastIndexOf("aabaabaa", "ab") = 1
1045 * StringUtils.lastIndexOf("aabaabaa", "") = 8
1046 * </pre>
1047 *
1048 * @param str the String to check, may be null
1049 * @param searchStr the String to find, may be null
1050 * @return the last index of the search String,
1051 * -1 if no match or <code>null</code> string input
1052 * @since 2.0
1053 */
1054 public static int lastIndexOf(String str, String searchStr) {
1055 if (str == null || searchStr == null) {
1056 return -1;
1057 }
1058 return str.lastIndexOf(searchStr);
1059 }
1060
1061 /**
1062 * <p>Finds the n-th last index within a String, handling <code>null</code>.
1063 * This method uses {@link String#lastIndexOf(String)}.</p>
1064 *
1065 * <p>A <code>null</code> String will return <code>-1</code>.</p>
1066 *
1067 * <pre>
1068 * StringUtils.lastOrdinalIndexOf(null, *, *) = -1
1069 * StringUtils.lastOrdinalIndexOf(*, null, *) = -1
1070 * StringUtils.lastOrdinalIndexOf("", "", *) = 0
1071 * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1) = 7
1072 * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2) = 6
1073 * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1) = 5
1074 * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2) = 2
1075 * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4
1076 * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1
1077 * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1) = 8
1078 * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2) = 8
1079 * </pre>
1080 *
1081 * <p>Note that 'tail(String str, int n)' may be implemented as: </p>
1082 *
1083 * <pre>
1084 * str.substring(lastOrdinalIndexOf(str, "\n", n) + 1)
1085 * </pre>
1086 *
1087 * @param str the String to check, may be null
1088 * @param searchStr the String to find, may be null
1089 * @param ordinal the n-th last <code>searchStr</code> to find
1090 * @return the n-th last index of the search String,
1091 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</code> string input
1092 * @since 2.5
1093 */
1094 public static int lastOrdinalIndexOf(String str, String searchStr, int ordinal) {
1095 return ordinalIndexOf(str, searchStr, ordinal, true);
1096 }
1097
1098 /**
1099 * <p>Finds the first index within a String, handling <code>null</code>.
1100 * This method uses {@link String#lastIndexOf(String, int)}.</p>
1101 *
1102 * <p>A <code>null</code> String will return <code>-1</code>.
1103 * A negative start position returns <code>-1</code>.
1104 * An empty ("") search String always matches unless the start position is negative.
1105 * A start position greater than the string length searches the whole string.</p>
1106 *
1107 * <pre>
1108 * StringUtils.lastIndexOf(null, *, *) = -1
1109 * StringUtils.lastIndexOf(*, null, *) = -1
1110 * StringUtils.lastIndexOf("aabaabaa", "a", 8) = 7
1111 * StringUtils.lastIndexOf("aabaabaa", "b", 8) = 5
1112 * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
1113 * StringUtils.lastIndexOf("aabaabaa", "b", 9) = 5
1114 * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
1115 * StringUtils.lastIndexOf("aabaabaa", "a", 0) = 0
1116 * StringUtils.lastIndexOf("aabaabaa", "b", 0) = -1
1117 * </pre>
1118 *
1119 * @param str the String to check, may be null
1120 * @param searchStr the String to find, may be null
1121 * @param startPos the start position, negative treated as zero
1122 * @return the first index of the search String,
1123 * -1 if no match or <code>null</code> string input
1124 * @since 2.0
1125 */
1126 public static int lastIndexOf(String str, String searchStr, int startPos) {
1127 if (str == null || searchStr == null) {
1128 return -1;
1129 }
1130 return str.lastIndexOf(searchStr, startPos);
1131 }
1132
1133 /**
1134 * <p>Case in-sensitive find of the last index within a String.</p>
1135 *
1136 * <p>A <code>null</code> String will return <code>-1</code>.
1137 * A negative start position returns <code>-1</code>.
1138 * An empty ("") search String always matches unless the start position is negative.
1139 * A start position greater than the string length searches the whole string.</p>
1140 *
1141 * <pre>
1142 * StringUtils.lastIndexOfIgnoreCase(null, *) = -1
1143 * StringUtils.lastIndexOfIgnoreCase(*, null) = -1
1144 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A") = 7
1145 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B") = 5
1146 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4
1147 * </pre>
1148 *
1149 * @param str the String to check, may be null
1150 * @param searchStr the String to find, may be null
1151 * @return the first index of the search String,
1152 * -1 if no match or <code>null</code> string input
1153 * @since 2.5
1154 */
1155 public static int lastIndexOfIgnoreCase(String str, String searchStr) {
1156 if (str == null || searchStr == null) {
1157 return -1;
1158 }
1159 return lastIndexOfIgnoreCase(str, searchStr, str.length());
1160 }
1161
1162 /**
1163 * <p>Case in-sensitive find of the last index within a String
1164 * from the specified position.</p>
1165 *
1166 * <p>A <code>null</code> String will return <code>-1</code>.
1167 * A negative start position returns <code>-1</code>.
1168 * An empty ("") search String always matches unless the start position is negative.
1169 * A start position greater than the string length searches the whole string.</p>
1170 *
1171 * <pre>
1172 * StringUtils.lastIndexOfIgnoreCase(null, *, *) = -1
1173 * StringUtils.lastIndexOfIgnoreCase(*, null, *) = -1
1174 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8) = 7
1175 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8) = 5
1176 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
1177 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9) = 5
1178 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
1179 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0) = 0
1180 * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0) = -1
1181 * </pre>
1182 *
1183 * @param str the String to check, may be null
1184 * @param searchStr the String to find, may be null
1185 * @param startPos the start position
1186 * @return the first index of the search String,
1187 * -1 if no match or <code>null</code> string input
1188 * @since 2.5
1189 */
1190 public static int lastIndexOfIgnoreCase(String str, String searchStr, int startPos) {
1191 if (str == null || searchStr == null) {
1192 return -1;
1193 }
1194 if (startPos > (str.length() - searchStr.length())) {
1195 startPos = str.length() - searchStr.length();
1196 }
1197 if (startPos < 0) {
1198 return -1;
1199 }
1200 if (searchStr.length() == 0) {
1201 return startPos;
1202 }
1203
1204 for (int i = startPos; i >= 0; i--) {
1205 if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) {
1206 return i;
1207 }
1208 }
1209 return -1;
1210 }
1211
1212 // Contains
1213 //-----------------------------------------------------------------------
1214 /**
1215 * <p>Checks if String contains a search character, handling <code>null</code>.
1216 * This method uses {@link String#indexOf(int)}.</p>
1217 *
1218 * <p>A <code>null</code> or empty ("") String will return <code>false</code>.</p>
1219 *
1220 * <pre>
1221 * StringUtils.contains(null, *) = false
1222 * StringUtils.contains("", *) = false
1223 * StringUtils.contains("abc", 'a') = true
1224 * StringUtils.contains("abc", 'z') = false
1225 * </pre>
1226 *
1227 * @param str the String to check, may be null
1228 * @param searchChar the character to find
1229 * @return true if the String contains the search character,
1230 * false if not or <code>null</code> string input
1231 * @since 2.0
1232 */
1233 public static boolean contains(String str, char searchChar) {
1234 if (isEmpty(str)) {
1235 return false;
1236 }
1237 return str.indexOf(searchChar) >= 0;
1238 }
1239
1240 /**
1241 * <p>Checks if String contains a search String, handling <code>null</code>.
1242 * This method uses {@link String#indexOf(String)}.</p>
1243 *
1244 * <p>A <code>null</code> String will return <code>false</code>.</p>
1245 *
1246 * <pre>
1247 * StringUtils.contains(null, *) = false
1248 * StringUtils.contains(*, null) = false
1249 * StringUtils.contains("", "") = true
1250 * StringUtils.contains("abc", "") = true
1251 * StringUtils.contains("abc", "a") = true
1252 * StringUtils.contains("abc", "z") = false
1253 * </pre>
1254 *
1255 * @param str the String to check, may be null
1256 * @param searchStr the String to find, may be null
1257 * @return true if the String contains the search String,
1258 * false if not or <code>null</code> string input
1259 * @since 2.0
1260 */
1261 public static boolean contains(String str, String searchStr) {
1262 if (str == null || searchStr == null) {
1263 return false;
1264 }
1265 return str.indexOf(searchStr) >= 0;
1266 }
1267
1268 /**
1269 * <p>Checks if String contains a search String irrespective of case,
1270 * handling <code>null</code>. Case-insensitivity is defined as by
1271 * {@link String#equalsIgnoreCase(String)}.
1272 *
1273 * <p>A <code>null</code> String will return <code>false</code>.</p>
1274 *
1275 * <pre>
1276 * StringUtils.contains(null, *) = false
1277 * StringUtils.contains(*, null) = false
1278 * StringUtils.contains("", "") = true
1279 * StringUtils.contains("abc", "") = true
1280 * StringUtils.contains("abc", "a") = true
1281 * StringUtils.contains("abc", "z") = false
1282 * StringUtils.contains("abc", "A") = true
1283 * StringUtils.contains("abc", "Z") = false
1284 * </pre>
1285 *
1286 * @param str the String to check, may be null
1287 * @param searchStr the String to find, may be null
1288 * @return true if the String contains the search String irrespective of
1289 * case or false if not or <code>null</code> string input
1290 */
1291 public static boolean containsIgnoreCase(String str, String searchStr) {
1292 if (str == null || searchStr == null) {
1293 return false;
1294 }
1295 int len = searchStr.length();
1296 int max = str.length() - len;
1297 for (int i = 0; i <= max; i++) {
1298 if (str.regionMatches(true, i, searchStr, 0, len)) {
1299 return true;
1300 }
1301 }
1302 return false;
1303 }
1304
1305 // IndexOfAny chars
1306 //-----------------------------------------------------------------------
1307 /**
1308 * <p>Search a String to find the first index of any
1309 * character in the given set of characters.</p>
1310 *
1311 * <p>A <code>null</code> String will return <code>-1</code>.
1312 * A <code>null</code> or zero length search array will return <code>-1</code>.</p>
1313 *
1314 * <pre>
1315 * StringUtils.indexOfAny(null, *) = -1
1316 * StringUtils.indexOfAny("", *) = -1
1317 * StringUtils.indexOfAny(*, null) = -1
1318 * StringUtils.indexOfAny(*, []) = -1
1319 * StringUtils.indexOfAny("zzabyycdxx",['z','a']) = 0
1320 * StringUtils.indexOfAny("zzabyycdxx",['b','y']) = 3
1321 * StringUtils.indexOfAny("aba", ['z']) = -1
1322 * </pre>
1323 *
1324 * @param str the String to check, may be null
1325 * @param searchChars the chars to search for, may be null
1326 * @return the index of any of the chars, -1 if no match or null input
1327 * @since 2.0
1328 */
1329 public static int indexOfAny(String str, char[] searchChars) {
1330 if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
1331 return -1;
1332 }
1333 for (int i = 0; i < str.length(); i++) {
1334 char ch = str.charAt(i);
1335 for (int j = 0; j < searchChars.length; j++) {
1336 if (searchChars[j] == ch) {
1337 return i;
1338 }
1339 }
1340 }
1341 return -1;
1342 }
1343
1344 /**
1345 * <p>Search a String to find the first index of any
1346 * character in the given set of characters.</p>
1347 *
1348 * <p>A <code>null</code> String will return <code>-1</code>.
1349 * A <code>null</code> search string will return <code>-1</code>.</p>
1350 *
1351 * <pre>
1352 * StringUtils.indexOfAny(null, *) = -1
1353 * StringUtils.indexOfAny("", *) = -1
1354 * StringUtils.indexOfAny(*, null) = -1
1355 * StringUtils.indexOfAny(*, "") = -1
1356 * StringUtils.indexOfAny("zzabyycdxx", "za") = 0
1357 * StringUtils.indexOfAny("zzabyycdxx", "by") = 3
1358 * StringUtils.indexOfAny("aba","z") = -1
1359 * </pre>
1360 *
1361 * @param str the String to check, may be null
1362 * @param searchChars the chars to search for, may be null
1363 * @return the index of any of the chars, -1 if no match or null input
1364 * @since 2.0
1365 */
1366 public static int indexOfAny(String str, String searchChars) {
1367 if (isEmpty(str) || isEmpty(searchChars)) {
1368 return -1;
1369 }
1370 return indexOfAny(str, searchChars.toCharArray());
1371 }
1372
1373 // ContainsAny
1374 //-----------------------------------------------------------------------
1375 /**
1376 * <p>Checks if the String contains any character in the given
1377 * set of characters.</p>
1378 *
1379 * <p>A <code>null</code> String will return <code>false</code>.
1380 * A <code>null</code> or zero length search array will return <code>false</code>.</p>
1381 *
1382 * <pre>
1383 * StringUtils.containsAny(null, *) = false
1384 * StringUtils.containsAny("", *) = false
1385 * StringUtils.containsAny(*, null) = false
1386 * StringUtils.containsAny(*, []) = false
1387 * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
1388 * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
1389 * StringUtils.containsAny("aba", ['z']) = false
1390 * </pre>
1391 *
1392 * @param str the String to check, may be null
1393 * @param searchChars the chars to search for, may be null
1394 * @return the <code>true</code> if any of the chars are found,
1395 * <code>false</code> if no match or null input
1396 * @since 2.4
1397 */
1398 public static boolean containsAny(String str, char[] searchChars) {
1399 if (str == null || str.length() == 0 || searchChars == null || searchChars.length == 0) {
1400 return false;
1401 }
1402 for (int i = 0; i < str.length(); i++) {
1403 char ch = str.charAt(i);
1404 for (int j = 0; j < searchChars.length; j++) {
1405 if (searchChars[j] == ch) {
1406 return true;
1407 }
1408 }
1409 }
1410 return false;
1411 }
1412
1413 /**
1414 * <p>
1415 * Checks if the String contains any character in the given set of characters.
1416 * </p>
1417 *
1418 * <p>
1419 * A <code>null</code> String will return <code>false</code>. A <code>null</code> search string will return
1420 * <code>false</code>.
1421 * </p>
1422 *
1423 * <pre>
1424 * StringUtils.containsAny(null, *) = false
1425 * StringUtils.containsAny("", *) = false
1426 * StringUtils.containsAny(*, null) = false
1427 * StringUtils.containsAny(*, "") = false
1428 * StringUtils.containsAny("zzabyycdxx", "za") = true
1429 * StringUtils.containsAny("zzabyycdxx", "by") = true
1430 * StringUtils.containsAny("aba","z") = false
1431 * </pre>
1432 *
1433 * @param str
1434 * the String to check, may be null
1435 * @param searchChars
1436 * the chars to search for, may be null
1437 * @return the <code>true</code> if any of the chars are found, <code>false</code> if no match or null input
1438 * @since 2.4
1439 */
1440 public static boolean containsAny(String str, String searchChars) {
1441 if (searchChars == null) {
1442 return false;
1443 }
1444 return containsAny(str, searchChars.toCharArray());
1445 }
1446
1447 // IndexOfAnyBut chars
1448 //-----------------------------------------------------------------------
1449 /**
1450 * <p>Search a String to find the first index of any
1451 * character not in the given set of characters.</p>
1452 *
1453 * <p>A <code>null</code> String will return <code>-1</code>.
1454 * A <code>null</code> or zero length search array will return <code>-1</code>.</p>
1455 *
1456 * <pre>
1457 * StringUtils.indexOfAnyBut(null, *) = -1
1458 * StringUtils.indexOfAnyBut("", *) = -1
1459 * StringUtils.indexOfAnyBut(*, null) = -1
1460 * StringUtils.indexOfAnyBut(*, []) = -1
1461 * StringUtils.indexOfAnyBut("zzabyycdxx",'za') = 3
1462 * StringUtils.indexOfAnyBut("zzabyycdxx", '') = 0
1463 * StringUtils.indexOfAnyBut("aba", 'ab') = -1
1464 * </pre>
1465 *
1466 * @param str the String to check, may be null
1467 * @param searchChars the chars to search for, may be null
1468 * @return the index of any of the chars, -1 if no match or null input
1469 * @since 2.0
1470 */
1471 public static int indexOfAnyBut(String str, char[] searchChars) {
1472 if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
1473 return -1;
1474 }
1475 outer : for (int i = 0; i < str.length(); i++) {
1476 char ch = str.charAt(i);
1477 for (int j = 0; j < searchChars.length; j++) {
1478 if (searchChars[j] == ch) {
1479 continue outer;
1480 }
1481 }
1482 return i;
1483 }
1484 return -1;
1485 }
1486
1487 /**
1488 * <p>Search a String to find the first index of any
1489 * character not in the given set of characters.</p>
1490 *
1491 * <p>A <code>null</code> String will return <code>-1</code>.
1492 * A <code>null</code> search string will return <code>-1</code>.</p>
1493 *
1494 * <pre>
1495 * StringUtils.indexOfAnyBut(null, *) = -1
1496 * StringUtils.indexOfAnyBut("", *) = -1
1497 * StringUtils.indexOfAnyBut(*, null) = -1
1498 * StringUtils.indexOfAnyBut(*, "") = -1
1499 * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
1500 * StringUtils.indexOfAnyBut("zzabyycdxx", "") = 0
1501 * StringUtils.indexOfAnyBut("aba","ab") = -1
1502 * </pre>
1503 *
1504 * @param str the String to check, may be null
1505 * @param searchChars the chars to search for, may be null
1506 * @return the index of any of the chars, -1 if no match or null input
1507 * @since 2.0
1508 */
1509 public static int indexOfAnyBut(String str, String searchChars) {
1510 if (isEmpty(str) || isEmpty(searchChars)) {
1511 return -1;
1512 }
1513 for (int i = 0; i < str.length(); i++) {
1514 if (searchChars.indexOf(str.charAt(i)) < 0) {
1515 return i;
1516 }
1517 }
1518 return -1;
1519 }
1520
1521 // ContainsOnly
1522 //-----------------------------------------------------------------------
1523 /**
1524 * <p>Checks if the String contains only certain characters.</p>
1525 *
1526 * <p>A <code>null</code> String will return <code>false</code>.
1527 * A <code>null</code> valid character array will return <code>false</code>.
1528 * An empty String ("") always returns <code>true</code>.</p>
1529 *
1530 * <pre>
1531 * StringUtils.containsOnly(null, *) = false
1532 * StringUtils.containsOnly(*, null) = false
1533 * StringUtils.containsOnly("", *) = true
1534 * StringUtils.containsOnly("ab", '') = false
1535 * StringUtils.containsOnly("abab", 'abc') = true
1536 * StringUtils.containsOnly("ab1", 'abc') = false
1537 * StringUtils.containsOnly("abz", 'abc') = false
1538 * </pre>
1539 *
1540 * @param str the String to check, may be null
1541 * @param valid an array of valid chars, may be null
1542 * @return true if it only contains valid chars and is non-null
1543 */
1544 public static boolean containsOnly(String str, char[] valid) {
1545 // All these pre-checks are to maintain API with an older version
1546 if ((valid == null) || (str == null)) {
1547 return false;
1548 }
1549 if (str.length() == 0) {
1550 return true;
1551 }
1552 if (valid.length == 0) {
1553 return false;
1554 }
1555 return indexOfAnyBut(str, valid) == -1;
1556 }
1557
1558 /**
1559 * <p>Checks if the String contains only certain characters.</p>
1560 *
1561 * <p>A <code>null</code> String will return <code>false</code>.
1562 * A <code>null</code> valid character String will return <code>false</code>.
1563 * An empty String ("") always returns <code>true</code>.</p>
1564 *
1565 * <pre>
1566 * StringUtils.containsOnly(null, *) = false
1567 * StringUtils.containsOnly(*, null) = false
1568 * StringUtils.containsOnly("", *) = true
1569 * StringUtils.containsOnly("ab", "") = false
1570 * StringUtils.containsOnly("abab", "abc") = true
1571 * StringUtils.containsOnly("ab1", "abc") = false
1572 * StringUtils.containsOnly("abz", "abc") = false
1573 * </pre>
1574 *
1575 * @param str the String to check, may be null
1576 * @param validChars a String of valid chars, may be null
1577 * @return true if it only contains valid chars and is non-null
1578 * @since 2.0
1579 */
1580 public static boolean containsOnly(String str, String validChars) {
1581 if (str == null || validChars == null) {
1582 return false;
1583 }
1584 return containsOnly(str, validChars.toCharArray());
1585 }
1586
1587 // ContainsNone
1588 //-----------------------------------------------------------------------
1589 /**
1590 * <p>Checks that the String does not contain certain characters.</p>
1591 *
1592 * <p>A <code>null</code> String will return <code>true</code>.
1593 * A <code>null</code> invalid character array will return <code>true</code>.
1594 * An empty String ("") always returns true.</p>
1595 *
1596 * <pre>
1597 * StringUtils.containsNone(null, *) = true
1598 * StringUtils.containsNone(*, null) = true
1599 * StringUtils.containsNone("", *) = true
1600 * StringUtils.containsNone("ab", '') = true
1601 * StringUtils.containsNone("abab", 'xyz') = true
1602 * StringUtils.containsNone("ab1", 'xyz') = true
1603 * StringUtils.containsNone("abz", 'xyz') = false
1604 * </pre>
1605 *
1606 * @param str the String to check, may be null
1607 * @param invalidChars an array of invalid chars, may be null
1608 * @return true if it contains none of the invalid chars, or is null
1609 * @since 2.0
1610 */
1611 public static boolean containsNone(String str, char[] invalidChars) {
1612 if (str == null || invalidChars == null) {
1613 return true;
1614 }
1615 int strSize = str.length();
1616 int validSize = invalidChars.length;
1617 for (int i = 0; i < strSize; i++) {
1618 char ch = str.charAt(i);
1619 for (int j = 0; j < validSize; j++) {
1620 if (invalidChars[j] == ch) {
1621 return false;
1622 }
1623 }
1624 }
1625 return true;
1626 }
1627
1628 /**
1629 * <p>Checks that the String does not contain certain characters.</p>
1630 *
1631 * <p>A <code>null</code> String will return <code>true</code>.
1632 * A <code>null</code> invalid character array will return <code>true</code>.
1633 * An empty String ("") always returns true.</p>
1634 *
1635 * <pre>
1636 * StringUtils.containsNone(null, *) = true
1637 * StringUtils.containsNone(*, null) = true
1638 * StringUtils.containsNone("", *) = true
1639 * StringUtils.containsNone("ab", "") = true
1640 * StringUtils.containsNone("abab", "xyz") = true
1641 * StringUtils.containsNone("ab1", "xyz") = true
1642 * StringUtils.containsNone("abz", "xyz") = false
1643 * </pre>
1644 *
1645 * @param str the String to check, may be null
1646 * @param invalidChars a String of invalid chars, may be null
1647 * @return true if it contains none of the invalid chars, or is null
1648 * @since 2.0
1649 */
1650 public static boolean containsNone(String str, String invalidChars) {
1651 if (str == null || invalidChars == null) {
1652 return true;
1653 }
1654 return containsNone(str, invalidChars.toCharArray());
1655 }
1656
1657 // IndexOfAny strings
1658 //-----------------------------------------------------------------------
1659 /**
1660 * <p>Find the first index of any of a set of potential substrings.</p>
1661 *
1662 * <p>A <code>null</code> String will return <code>-1</code>.
1663 * A <code>null</code> or zero length search array will return <code>-1</code>.
1664 * A <code>null</code> search array entry will be ignored, but a search
1665 * array containing "" will return <code>0</code> if <code>str</code> is not
1666 * null. This method uses {@link String#indexOf(String)}.</p>
1667 *
1668 * <pre>
1669 * StringUtils.indexOfAny(null, *) = -1
1670 * StringUtils.indexOfAny(*, null) = -1
1671 * StringUtils.indexOfAny(*, []) = -1
1672 * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"]) = 2
1673 * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"]) = 2
1674 * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"]) = -1
1675 * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
1676 * StringUtils.indexOfAny("zzabyycdxx", [""]) = 0
1677 * StringUtils.indexOfAny("", [""]) = 0
1678 * StringUtils.indexOfAny("", ["a"]) = -1
1679 * </pre>
1680 *
1681 * @param str the String to check, may be null
1682 * @param searchStrs the Strings to search for, may be null
1683 * @return the first index of any of the searchStrs in str, -1 if no match
1684 */
1685 public static int indexOfAny(String str, String[] searchStrs) {
1686 if ((str == null) || (searchStrs == null)) {
1687 return -1;
1688 }
1689 int sz = searchStrs.length;
1690
1691 // String's can't have a MAX_VALUEth index.
1692 int ret = Integer.MAX_VALUE;
1693
1694 int tmp = 0;
1695 for (int i = 0; i < sz; i++) {
1696 String search = searchStrs[i];
1697 if (search == null) {
1698 continue;
1699 }
1700 tmp = str.indexOf(search);
1701 if (tmp == -1) {
1702 continue;
1703 }
1704
1705 if (tmp < ret) {
1706 ret = tmp;
1707 }
1708 }
1709
1710 return (ret == Integer.MAX_VALUE) ? -1 : ret;
1711 }
1712
1713 /**
1714 * <p>Find the latest index of any of a set of potential substrings.</p>
1715 *
1716 * <p>A <code>null</code> String will return <code>-1</code>.
1717 * A <code>null</code> search array will return <code>-1</code>.
1718 * A <code>null</code> or zero length search array entry will be ignored,
1719 * but a search array containing "" will return the length of <code>str</code>
1720 * if <code>str</code> is not null. This method uses {@link String#indexOf(String)}</p>
1721 *
1722 * <pre>
1723 * StringUtils.lastIndexOfAny(null, *) = -1
1724 * StringUtils.lastIndexOfAny(*, null) = -1
1725 * StringUtils.lastIndexOfAny(*, []) = -1
1726 * StringUtils.lastIndexOfAny(*, [null]) = -1
1727 * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
1728 * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
1729 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1730 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1731 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""]) = 10
1732 * </pre>
1733 *
1734 * @param str the String to check, may be null
1735 * @param searchStrs the Strings to search for, may be null
1736 * @return the last index of any of the Strings, -1 if no match
1737 */
1738 public static int lastIndexOfAny(String str, String[] searchStrs) {
1739 if ((str == null) || (searchStrs == null)) {
1740 return -1;
1741 }
1742 int sz = searchStrs.length;
1743 int ret = -1;
1744 int tmp = 0;
1745 for (int i = 0; i < sz; i++) {
1746 String search = searchStrs[i];
1747 if (search == null) {
1748 continue;
1749 }
1750 tmp = str.lastIndexOf(search);
1751 if (tmp > ret) {
1752 ret = tmp;
1753 }
1754 }
1755 return ret;
1756 }
1757
1758 // Substring
1759 //-----------------------------------------------------------------------
1760 /**
1761 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1762 *
1763 * <p>A negative start position can be used to start <code>n</code>
1764 * characters from the end of the String.</p>
1765 *
1766 * <p>A <code>null</code> String will return <code>null</code>.
1767 * An empty ("") String will return "".</p>
1768 *
1769 * <pre>
1770 * StringUtils.substring(null, *) = null
1771 * StringUtils.substring("", *) = ""
1772 * StringUtils.substring("abc", 0) = "abc"
1773 * StringUtils.substring("abc", 2) = "c"
1774 * StringUtils.substring("abc", 4) = ""
1775 * StringUtils.substring("abc", -2) = "bc"
1776 * StringUtils.substring("abc", -4) = "abc"
1777 * </pre>
1778 *
1779 * @param str the String to get the substring from, may be null
1780 * @param start the position to start from, negative means
1781 * count back from the end of the String by this many characters
1782 * @return substring from start position, <code>null</code> if null String input
1783 */
1784 public static String substring(String str, int start) {
1785 if (str == null) {
1786 return null;
1787 }
1788
1789 // handle negatives, which means last n characters
1790 if (start < 0) {
1791 start = str.length() + start; // remember start is negative
1792 }
1793
1794 if (start < 0) {
1795 start = 0;
1796 }
1797 if (start > str.length()) {
1798 return EMPTY;
1799 }
1800
1801 return str.substring(start);
1802 }
1803
1804 /**
1805 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1806 *
1807 * <p>A negative start position can be used to start/end <code>n</code>
1808 * characters from the end of the String.</p>
1809 *
1810 * <p>The returned substring starts with the character in the <code>start</code>
1811 * position and ends before the <code>end</code> position. All position counting is
1812 * zero-based -- i.e., to start at the beginning of the string use
1813 * <code>start = 0</code>. Negative start and end positions can be used to
1814 * specify offsets relative to the end of the String.</p>
1815 *
1816 * <p>If <code>start</code> is not strictly to the left of <code>end</code>, ""
1817 * is returned.</p>
1818 *
1819 * <pre>
1820 * StringUtils.substring(null, *, *) = null
1821 * StringUtils.substring("", * , *) = "";
1822 * StringUtils.substring("abc", 0, 2) = "ab"
1823 * StringUtils.substring("abc", 2, 0) = ""
1824 * StringUtils.substring("abc", 2, 4) = "c"
1825 * StringUtils.substring("abc", 4, 6) = ""
1826 * StringUtils.substring("abc", 2, 2) = ""
1827 * StringUtils.substring("abc", -2, -1) = "b"
1828 * StringUtils.substring("abc", -4, 2) = "ab"
1829 * </pre>
1830 *
1831 * @param str the String to get the substring from, may be null
1832 * @param start the position to start from, negative means
1833 * count back from the end of the String by this many characters
1834 * @param end the position to end at (exclusive), negative means
1835 * count back from the end of the String by this many characters
1836 * @return substring from start position to end positon,
1837 * <code>null</code> if null String input
1838 */
1839 public static String substring(String str, int start, int end) {
1840 if (str == null) {
1841 return null;
1842 }
1843
1844 // handle negatives
1845 if (end < 0) {
1846 end = str.length() + end; // remember end is negative
1847 }
1848 if (start < 0) {
1849 start = str.length() + start; // remember start is negative
1850 }
1851
1852 // check length next
1853 if (end > str.length()) {
1854 end = str.length();
1855 }
1856
1857 // if start is greater than end, return ""
1858 if (start > end) {
1859 return EMPTY;
1860 }
1861
1862 if (start < 0) {
1863 start = 0;
1864 }
1865 if (end < 0) {
1866 end = 0;
1867 }
1868
1869 return str.substring(start, end);
1870 }
1871
1872 // Left/Right/Mid
1873 //-----------------------------------------------------------------------
1874 /**
1875 * <p>Gets the leftmost <code>len</code> characters of a String.</p>
1876 *
1877 * <p>If <code>len</code> characters are not available, or the
1878 * String is <code>null</code>, the String will be returned without
1879 * an exception. An exception is thrown if len is negative.</p>
1880 *
1881 * <pre>
1882 * StringUtils.left(null, *) = null
1883 * StringUtils.left(*, -ve) = ""
1884 * StringUtils.left("", *) = ""
1885 * StringUtils.left("abc", 0) = ""
1886 * StringUtils.left("abc", 2) = "ab"
1887 * StringUtils.left("abc", 4) = "abc"
1888 * </pre>
1889 *
1890 * @param str the String to get the leftmost characters from, may be null
1891 * @param len the length of the required String, must be zero or positive
1892 * @return the leftmost characters, <code>null</code> if null String input
1893 */
1894 public static String left(String str, int len) {
1895 if (str == null) {
1896 return null;
1897 }
1898 if (len < 0) {
1899 return EMPTY;
1900 }
1901 if (str.length() <= len) {
1902 return str;
1903 }
1904 return str.substring(0, len);
1905 }
1906
1907 /**
1908 * <p>Gets the rightmost <code>len</code> characters of a String.</p>
1909 *
1910 * <p>If <code>len</code> characters are not available, or the String
1911 * is <code>null</code>, the String will be returned without an
1912 * an exception. An exception is thrown if len is negative.</p>
1913 *
1914 * <pre>
1915 * StringUtils.right(null, *) = null
1916 * StringUtils.right(*, -ve) = ""
1917 * StringUtils.right("", *) = ""
1918 * StringUtils.right("abc", 0) = ""
1919 * StringUtils.right("abc", 2) = "bc"
1920 * StringUtils.right("abc", 4) = "abc"
1921 * </pre>
1922 *
1923 * @param str the String to get the rightmost characters from, may be null
1924 * @param len the length of the required String, must be zero or positive
1925 * @return the rightmost characters, <code>null</code> if null String input
1926 */
1927 public static String right(String str, int len) {
1928 if (str == null) {
1929 return null;
1930 }
1931 if (len < 0) {
1932 return EMPTY;
1933 }
1934 if (str.length() <= len) {
1935 return str;
1936 }
1937 return str.substring(str.length() - len);
1938 }
1939
1940 /**
1941 * <p>Gets <code>len</code> characters from the middle of a String.</p>
1942 *
1943 * <p>If <code>len</code> characters are not available, the remainder
1944 * of the String will be returned without an exception. If the
1945 * String is <code>null</code>, <code>null</code> will be returned.
1946 * An exception is thrown if len is negative.</p>
1947 *
1948 * <pre>
1949 * StringUtils.mid(null, *, *) = null
1950 * StringUtils.mid(*, *, -ve) = ""
1951 * StringUtils.mid("", 0, *) = ""
1952 * StringUtils.mid("abc", 0, 2) = "ab"
1953 * StringUtils.mid("abc", 0, 4) = "abc"
1954 * StringUtils.mid("abc", 2, 4) = "c"
1955 * StringUtils.mid("abc", 4, 2) = ""
1956 * StringUtils.mid("abc", -2, 2) = "ab"
1957 * </pre>
1958 *
1959 * @param str the String to get the characters from, may be null
1960 * @param pos the position to start from, negative treated as zero
1961 * @param len the length of the required String, must be zero or positive
1962 * @return the middle characters, <code>null</code> if null String input
1963 */
1964 public static String mid(String str, int pos, int len) {
1965 if (str == null) {
1966 return null;
1967 }
1968 if (len < 0 || pos > str.length()) {
1969 return EMPTY;
1970 }
1971 if (pos < 0) {
1972 pos = 0;
1973 }
1974 if (str.length() <= (pos + len)) {
1975 return str.substring(pos);
1976 }
1977 return str.substring(pos, pos + len);
1978 }
1979
1980 // SubStringAfter/SubStringBefore
1981 //-----------------------------------------------------------------------
1982 /**
1983 * <p>Gets the substring before the first occurrence of a separator.
1984 * The separator is not returned.</p>
1985 *
1986 * <p>A <code>null</code> string input will return <code>null</code>.
1987 * An empty ("") string input will return the empty string.
1988 * A <code>null</code> separator will return the input string.</p>
1989 *
1990 * <p>If nothing is found, the string input is returned.</p>
1991 *
1992 * <pre>
1993 * StringUtils.substringBefore(null, *) = null
1994 * StringUtils.substringBefore("", *) = ""
1995 * StringUtils.substringBefore("abc", "a") = ""
1996 * StringUtils.substringBefore("abcba", "b") = "a"
1997 * StringUtils.substringBefore("abc", "c") = "ab"
1998 * StringUtils.substringBefore("abc", "d") = "abc"
1999 * StringUtils.substringBefore("abc", "") = ""
2000 * StringUtils.substringBefore("abc", null) = "abc"
2001 * </pre>
2002 *
2003 * @param str the String to get a substring from, may be null
2004 * @param separator the String to search for, may be null
2005 * @return the substring before the first occurrence of the separator,
2006 * <code>null</code> if null String input
2007 * @since 2.0
2008 */
2009 public static String substringBefore(String str, String separator) {
2010 if (isEmpty(str) || separator == null) {
2011 return str;
2012 }
2013 if (separator.length() == 0) {
2014 return EMPTY;
2015 }
2016 int pos = str.indexOf(separator);
2017 if (pos == -1) {
2018 return str;
2019 }
2020 return str.substring(0, pos);
2021 }
2022
2023 /**
2024 * <p>Gets the substring after the first occurrence of a separator.
2025 * The separator is not returned.</p>
2026 *
2027 * <p>A <code>null</code> string input will return <code>null</code>.
2028 * An empty ("") string input will return the empty string.
2029 * A <code>null</code> separator will return the empty string if the
2030 * input string is not <code>null</code>.</p>
2031 *
2032 * <p>If nothing is found, the empty string is returned.</p>
2033 *
2034 * <pre>
2035 * StringUtils.substringAfter(null, *) = null
2036 * StringUtils.substringAfter("", *) = ""
2037 * StringUtils.substringAfter(*, null) = ""
2038 * StringUtils.substringAfter("abc", "a") = "bc"
2039 * StringUtils.substringAfter("abcba", "b") = "cba"
2040 * StringUtils.substringAfter("abc", "c") = ""
2041 * StringUtils.substringAfter("abc", "d") = ""
2042 * StringUtils.substringAfter("abc", "") = "abc"
2043 * </pre>
2044 *
2045 * @param str the String to get a substring from, may be null
2046 * @param separator the String to search for, may be null
2047 * @return the substring after the first occurrence of the separator,
2048 * <code>null</code> if null String input
2049 * @since 2.0
2050 */
2051 public static String substringAfter(String str, String separator) {
2052 if (isEmpty(str)) {
2053 return str;
2054 }
2055 if (separator == null) {
2056 return EMPTY;
2057 }
2058 int pos = str.indexOf(separator);
2059 if (pos == -1) {
2060 return EMPTY;
2061 }
2062 return str.substring(pos + separator.length());
2063 }
2064
2065 /**
2066 * <p>Gets the substring before the last occurrence of a separator.
2067 * The separator is not returned.</p>
2068 *
2069 * <p>A <code>null</code> string input will return <code>null</code>.
2070 * An empty ("") string input will return the empty string.
2071 * An empty or <code>null</code> separator will return the input string.</p>
2072 *
2073 * <p>If nothing is found, the string input is returned.</p>
2074 *
2075 * <pre>
2076 * StringUtils.substringBeforeLast(null, *) = null
2077 * StringUtils.substringBeforeLast("", *) = ""
2078 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
2079 * StringUtils.substringBeforeLast("abc", "c") = "ab"
2080 * StringUtils.substringBeforeLast("a", "a") = ""
2081 * StringUtils.substringBeforeLast("a", "z") = "a"
2082 * StringUtils.substringBeforeLast("a", null) = "a"
2083 * StringUtils.substringBeforeLast("a", "") = "a"
2084 * </pre>
2085 *
2086 * @param str the String to get a substring from, may be null
2087 * @param separator the String to search for, may be null
2088 * @return the substring before the last occurrence of the separator,
2089 * <code>null</code> if null String input
2090 * @since 2.0
2091 */
2092 public static String substringBeforeLast(String str, String separator) {
2093 if (isEmpty(str) || isEmpty(separator)) {
2094 return str;
2095 }
2096 int pos = str.lastIndexOf(separator);
2097 if (pos == -1) {
2098 return str;
2099 }
2100 return str.substring(0, pos);
2101 }
2102
2103 /**
2104 * <p>Gets the substring after the last occurrence of a separator.
2105 * The separator is not returned.</p>
2106 *
2107 * <p>A <code>null</code> string input will return <code>null</code>.
2108 * An empty ("") string input will return the empty string.
2109 * An empty or <code>null</code> separator will return the empty string if
2110 * the input string is not <code>null</code>.</p>
2111 *
2112 * <p>If nothing is found, the empty string is returned.</p>
2113 *
2114 * <pre>
2115 * StringUtils.substringAfterLast(null, *) = null
2116 * StringUtils.substringAfterLast("", *) = ""
2117 * StringUtils.substringAfterLast(*, "") = ""
2118 * StringUtils.substringAfterLast(*, null) = ""
2119 * StringUtils.substringAfterLast("abc", "a") = "bc"
2120 * StringUtils.substringAfterLast("abcba", "b") = "a"
2121 * StringUtils.substringAfterLast("abc", "c") = ""
2122 * StringUtils.substringAfterLast("a", "a") = ""
2123 * StringUtils.substringAfterLast("a", "z") = ""
2124 * </pre>
2125 *
2126 * @param str the String to get a substring from, may be null
2127 * @param separator the String to search for, may be null
2128 * @return the substring after the last occurrence of the separator,
2129 * <code>null</code> if null String input
2130 * @since 2.0
2131 */
2132 public static String substringAfterLast(String str, String separator) {
2133 if (isEmpty(str)) {
2134 return str;
2135 }
2136 if (isEmpty(separator)) {
2137 return EMPTY;
2138 }
2139 int pos = str.lastIndexOf(separator);
2140 if (pos == -1 || pos == (str.length() - separator.length())) {
2141 return EMPTY;
2142 }
2143 return str.substring(pos + separator.length());
2144 }
2145
2146 // Substring between
2147 //-----------------------------------------------------------------------
2148 /**
2149 * <p>Gets the String that is nested in between two instances of the
2150 * same String.</p>
2151 *
2152 * <p>A <code>null</code> input String returns <code>null</code>.
2153 * A <code>null</code> tag returns <code>null</code>.</p>
2154 *
2155 * <pre>
2156 * StringUtils.substringBetween(null, *) = null
2157 * StringUtils.substringBetween("", "") = ""
2158 * StringUtils.substringBetween("", "tag") = null
2159 * StringUtils.substringBetween("tagabctag", null) = null
2160 * StringUtils.substringBetween("tagabctag", "") = ""
2161 * StringUtils.substringBetween("tagabctag", "tag") = "abc"
2162 * </pre>
2163 *
2164 * @param str the String containing the substring, may be null
2165 * @param tag the String before and after the substring, may be null
2166 * @return the substring, <code>null</code> if no match
2167 * @since 2.0
2168 */
2169 public static String substringBetween(String str, String tag) {
2170 return substringBetween(str, tag, tag);
2171 }
2172
2173 /**
2174 * <p>Gets the String that is nested in between two Strings.
2175 * Only the first match is returned.</p>
2176 *
2177 * <p>A <code>null</code> input String returns <code>null</code>.
2178 * A <code>null</code> open/close returns <code>null</code> (no match).
2179 * An empty ("") open and close returns an empty string.</p>
2180 *
2181 * <pre>
2182 * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
2183 * StringUtils.substringBetween(null, *, *) = null
2184 * StringUtils.substringBetween(*, null, *) = null
2185 * StringUtils.substringBetween(*, *, null) = null
2186 * StringUtils.substringBetween("", "", "") = ""
2187 * StringUtils.substringBetween("", "", "]") = null
2188 * StringUtils.substringBetween("", "[", "]") = null
2189 * StringUtils.substringBetween("yabcz", "", "") = ""
2190 * StringUtils.substringBetween("yabcz", "y", "z") = "abc"
2191 * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc"
2192 * </pre>
2193 *
2194 * @param str the String containing the substring, may be null
2195 * @param open the String before the substring, may be null
2196 * @param close the String after the substring, may be null
2197 * @return the substring, <code>null</code> if no match
2198 * @since 2.0
2199 */
2200 public static String substringBetween(String str, String open, String close) {
2201 if (str == null || open == null || close == null) {
2202 return null;
2203 }
2204 int start = str.indexOf(open);
2205 if (start != -1) {
2206 int end = str.indexOf(close, start + open.length());
2207 if (end != -1) {
2208 return str.substring(start + open.length(), end);
2209 }
2210 }
2211 return null;
2212 }
2213
2214 /**
2215 * <p>Searches a String for substrings delimited by a start and end tag,
2216 * returning all matching substrings in an array.</p>
2217 *
2218 * <p>A <code>null</code> input String returns <code>null</code>.
2219 * A <code>null</code> open/close returns <code>null</code> (no match).
2220 * An empty ("") open/close returns <code>null</code> (no match).</p>
2221 *
2222 * <pre>
2223 * StringUtils.substringsBetween("[a][b][c]", "[", "]") = ["a","b","c"]
2224 * StringUtils.substringsBetween(null, *, *) = null
2225 * StringUtils.substringsBetween(*, null, *) = null
2226 * StringUtils.substringsBetween(*, *, null) = null
2227 * StringUtils.substringsBetween("", "[", "]") = []
2228 * </pre>
2229 *
2230 * @param str the String containing the substrings, null returns null, empty returns empty
2231 * @param open the String identifying the start of the substring, empty returns null
2232 * @param close the String identifying the end of the substring, empty returns null
2233 * @return a String Array of substrings, or <code>null</code> if no match
2234 * @since 2.3
2235 */
2236 public static String[] substringsBetween(String str, String open, String close) {
2237 if (str == null || isEmpty(open) || isEmpty(close)) {
2238 return null;
2239 }
2240 int strLen = str.length();
2241 if (strLen == 0) {
2242 return ArrayUtils.EMPTY_STRING_ARRAY;
2243 }
2244 int closeLen = close.length();
2245 int openLen = open.length();
2246 List list = new ArrayList();
2247 int pos = 0;
2248 while (pos < (strLen - closeLen)) {
2249 int start = str.indexOf(open, pos);
2250 if (start < 0) {
2251 break;
2252 }
2253 start += openLen;
2254 int end = str.indexOf(close, start);
2255 if (end < 0) {
2256 break;
2257 }
2258 list.add(str.substring(start, end));
2259 pos = end + closeLen;
2260 }
2261 if (list.isEmpty()) {
2262 return null;
2263 }
2264 return (String[]) list.toArray(new String [list.size()]);
2265 }
2266
2267 // Nested extraction
2268 //-----------------------------------------------------------------------
2269 /**
2270 * <p>Gets the String that is nested in between two instances of the
2271 * same String.</p>
2272 *
2273 * <p>A <code>null</code> input String returns <code>null</code>.
2274 * A <code>null</code> tag returns <code>null</code>.</p>
2275 *
2276 * <pre>
2277 * StringUtils.getNestedString(null, *) = null
2278 * StringUtils.getNestedString("", "") = ""
2279 * StringUtils.getNestedString("", "tag") = null
2280 * StringUtils.getNestedString("tagabctag", null) = null
2281 * StringUtils.getNestedString("tagabctag", "") = ""
2282 * StringUtils.getNestedString("tagabctag", "tag") = "abc"
2283 * </pre>
2284 *
2285 * @param str the String containing nested-string, may be null
2286 * @param tag the String before and after nested-string, may be null
2287 * @return the nested String, <code>null</code> if no match
2288 * @deprecated Use the better named {@link #substringBetween(String, String)}.
2289 * Method will be removed in Commons Lang 3.0.
2290 */
2291 public static String getNestedString(String str, String tag) {
2292 return substringBetween(str, tag, tag);
2293 }
2294
2295 /**
2296 * <p>Gets the String that is nested in between two Strings.
2297 * Only the first match is returned.</p>
2298 *
2299 * <p>A <code>null</code> input String returns <code>null</code>.
2300 * A <code>null</code> open/close returns <code>null</code> (no match).
2301 * An empty ("") open/close returns an empty string.</p>
2302 *
2303 * <pre>
2304 * StringUtils.getNestedString(null, *, *) = null
2305 * StringUtils.getNestedString("", "", "") = ""
2306 * StringUtils.getNestedString("", "", "tag") = null
2307 * StringUtils.getNestedString("", "tag", "tag") = null
2308 * StringUtils.getNestedString("yabcz", null, null) = null
2309 * StringUtils.getNestedString("yabcz", "", "") = ""
2310 * StringUtils.getNestedString("yabcz", "y", "z") = "abc"
2311 * StringUtils.getNestedString("yabczyabcz", "y", "z") = "abc"
2312 * </pre>
2313 *
2314 * @param str the String containing nested-string, may be null
2315 * @param open the String before nested-string, may be null
2316 * @param close the String after nested-string, may be null
2317 * @return the nested String, <code>null</code> if no match
2318 * @deprecated Use the better named {@link #substringBetween(String, String, String)}.
2319 * Method will be removed in Commons Lang 3.0.
2320 */
2321 public static String getNestedString(String str, String open, String close) {
2322 return substringBetween(str, open, close);
2323 }
2324
2325 // Splitting
2326 //-----------------------------------------------------------------------
2327 /**
2328 * <p>Splits the provided text into an array, using whitespace as the
2329 * separator.
2330 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
2331 *
2332 * <p>The separator is not included in the returned String array.
2333 * Adjacent separators are treated as one separator.
2334 * For more control over the split use the StrTokenizer class.</p>
2335 *
2336 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2337 *
2338 * <pre>
2339 * StringUtils.split(null) = null
2340 * StringUtils.split("") = []
2341 * StringUtils.split("abc def") = ["abc", "def"]
2342 * StringUtils.split("abc def") = ["abc", "def"]
2343 * StringUtils.split(" abc ") = ["abc"]
2344 * </pre>
2345 *
2346 * @param str the String to parse, may be null
2347 * @return an array of parsed Strings, <code>null</code> if null String input
2348 */
2349 public static String[] split(String str) {
2350 return split(str, null, -1);
2351 }
2352
2353 /**
2354 * <p>Splits the provided text into an array, separator specified.
2355 * This is an alternative to using StringTokenizer.</p>
2356 *
2357 * <p>The separator is not included in the returned String array.
2358 * Adjacent separators are treated as one separator.
2359 * For more control over the split use the StrTokenizer class.</p>
2360 *
2361 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2362 *
2363 * <pre>
2364 * StringUtils.split(null, *) = null
2365 * StringUtils.split("", *) = []
2366 * StringUtils.split("a.b.c", '.') = ["a", "b", "c"]
2367 * StringUtils.split("a..b.c", '.') = ["a", "b", "c"]
2368 * StringUtils.split("a:b:c", '.') = ["a:b:c"]
2369 * StringUtils.split("a b c", ' ') = ["a", "b", "c"]
2370 * </pre>
2371 *
2372 * @param str the String to parse, may be null
2373 * @param separatorChar the character used as the delimiter
2374 * @return an array of parsed Strings, <code>null</code> if null String input
2375 * @since 2.0
2376 */
2377 public static String[] split(String str, char separatorChar) {
2378 return splitWorker(str, separatorChar, false);
2379 }
2380
2381 /**
2382 * <p>Splits the provided text into an array, separators specified.
2383 * This is an alternative to using StringTokenizer.</p>
2384 *
2385 * <p>The separator is not included in the returned String array.
2386 * Adjacent separators are treated as one separator.
2387 * For more control over the split use the StrTokenizer class.</p>
2388 *
2389 * <p>A <code>null</code> input String returns <code>null</code>.
2390 * A <code>null</code> separatorChars splits on whitespace.</p>
2391 *
2392 * <pre>
2393 * StringUtils.split(null, *) = null
2394 * StringUtils.split("", *) = []
2395 * StringUtils.split("abc def", null) = ["abc", "def"]
2396 * StringUtils.split("abc def", " ") = ["abc", "def"]
2397 * StringUtils.split("abc def", " ") = ["abc", "def"]
2398 * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2399 * </pre>
2400 *
2401 * @param str the String to parse, may be null
2402 * @param separatorChars the characters used as the delimiters,
2403 * <code>null</code> splits on whitespace
2404 * @return an array of parsed Strings, <code>null</code> if null String input
2405 */
2406 public static String[] split(String str, String separatorChars) {
2407 return splitWorker(str, separatorChars, -1, false);
2408 }
2409
2410 /**
2411 * <p>Splits the provided text into an array with a maximum length,
2412 * separators specified.</p>
2413 *
2414 * <p>The separator is not included in the returned String array.
2415 * Adjacent separators are treated as one separator.</p>
2416 *
2417 * <p>A <code>null</code> input String returns <code>null</code>.
2418 * A <code>null</code> separatorChars splits on whitespace.</p>
2419 *
2420 * <p>If more than <code>max</code> delimited substrings are found, the last
2421 * returned string includes all characters after the first <code>max - 1</code>
2422 * returned strings (including separator characters).</p>
2423 *
2424 * <pre>
2425 * StringUtils.split(null, *, *) = null
2426 * StringUtils.split("", *, *) = []
2427 * StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"]
2428 * StringUtils.split("ab de fg", null, 0) = ["ab", "cd", "ef"]
2429 * StringUtils.split("ab:cd:ef", ":", 0) = ["ab", "cd", "ef"]
2430 * StringUtils.split("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2431 * </pre>
2432 *
2433 * @param str the String to parse, may be null
2434 * @param separatorChars the characters used as the delimiters,
2435 * <code>null</code> splits on whitespace
2436 * @param max the maximum number of elements to include in the
2437 * array. A zero or negative value implies no limit
2438 * @return an array of parsed Strings, <code>null</code> if null String input
2439 */
2440 public static String[] split(String str, String separatorChars, int max) {
2441 return splitWorker(str, separatorChars, max, false);
2442 }
2443
2444 /**
2445 * <p>Splits the provided text into an array, separator string specified.</p>
2446 *
2447 * <p>The separator(s) will not be included in the returned String array.
2448 * Adjacent separators are treated as one separator.</p>
2449 *
2450 * <p>A <code>null</code> input String returns <code>null</code>.
2451 * A <code>null</code> separator splits on whitespace.</p>
2452 *
2453 * <pre>
2454 * StringUtils.splitByWholeSeparator(null, *) = null
2455 * StringUtils.splitByWholeSeparator("", *) = []
2456 * StringUtils.splitByWholeSeparator("ab de fg", null) = ["ab", "de", "fg"]
2457 * StringUtils.splitByWholeSeparator("ab de fg", null) = ["ab", "de", "fg"]
2458 * StringUtils.splitByWholeSeparator("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2459 * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
2460 * </pre>
2461 *
2462 * @param str the String to parse, may be null
2463 * @param separator String containing the String to be used as a delimiter,
2464 * <code>null</code> splits on whitespace
2465 * @return an array of parsed Strings, <code>null</code> if null String was input
2466 */
2467 public static String[] splitByWholeSeparator(String str, String separator) {
2468 return splitByWholeSeparatorWorker( str, separator, -1, false ) ;
2469 }
2470
2471 /**
2472 * <p>Splits the provided text into an array, separator string specified.
2473 * Returns a maximum of <code>max</code> substrings.</p>
2474 *
2475 * <p>The separator(s) will not be included in the returned String array.
2476 * Adjacent separators are treated as one separator.</p>
2477 *
2478 * <p>A <code>null</code> input String returns <code>null</code>.
2479 * A <code>null</code> separator splits on whitespace.</p>
2480 *
2481 * <pre>
2482 * StringUtils.splitByWholeSeparator(null, *, *) = null
2483 * StringUtils.splitByWholeSeparator("", *, *) = []
2484 * StringUtils.splitByWholeSeparator("ab de fg", null, 0) = ["ab", "de", "fg"]
2485 * StringUtils.splitByWholeSeparator("ab de fg", null, 0) = ["ab", "de", "fg"]
2486 * StringUtils.splitByWholeSeparator("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2487 * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
2488 * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
2489 * </pre>
2490 *
2491 * @param str the String to parse, may be null
2492 * @param separator String containing the String to be used as a delimiter,
2493 * <code>null</code> splits on whitespace
2494 * @param max the maximum number of elements to include in the returned
2495 * array. A zero or negative value implies no limit.
2496 * @return an array of parsed Strings, <code>null</code> if null String was input
2497 */
2498 public static String[] splitByWholeSeparator( String str, String separator, int max ) {
2499 return splitByWholeSeparatorWorker(str, separator, max, false);
2500 }
2501
2502 /**
2503 * <p>Splits the provided text into an array, separator string specified. </p>
2504 *
2505 * <p>The separator is not included in the returned String array.
2506 * Adjacent separators are treated as separators for empty tokens.
2507 * For more control over the split use the StrTokenizer class.</p>
2508 *
2509 * <p>A <code>null</code> input String returns <code>null</code>.
2510 * A <code>null</code> separator splits on whitespace.</p>
2511 *
2512 * <pre>
2513 * StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *) = null
2514 * StringUtils.splitByWholeSeparatorPreserveAllTokens("", *) = []
2515 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null) = ["ab", "de", "fg"]
2516 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null) = ["ab", "", "", "de", "fg"]
2517 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2518 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
2519 * </pre>
2520 *
2521 * @param str the String to parse, may be null
2522 * @param separator String containing the String to be used as a delimiter,
2523 * <code>null</code> splits on whitespace
2524 * @return an array of parsed Strings, <code>null</code> if null String was input
2525 * @since 2.4
2526 */
2527 public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator) {
2528 return splitByWholeSeparatorWorker(str, separator, -1, true);
2529 }
2530
2531 /**
2532 * <p>Splits the provided text into an array, separator string specified.
2533 * Returns a maximum of <code>max</code> substrings.</p>
2534 *
2535 * <p>The separator is not included in the returned String array.
2536 * Adjacent separators are treated as separators for empty tokens.
2537 * For more control over the split use the StrTokenizer class.</p>
2538 *
2539 * <p>A <code>null</code> input String returns <code>null</code>.
2540 * A <code>null</code> separator splits on whitespace.</p>
2541 *
2542 * <pre>
2543 * StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *, *) = null
2544 * StringUtils.splitByWholeSeparatorPreserveAllTokens("", *, *) = []
2545 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0) = ["ab", "de", "fg"]
2546 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0) = ["ab", "", "", "de", "fg"]
2547 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2548 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
2549 * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
2550 * </pre>
2551 *
2552 * @param str the String to parse, may be null
2553 * @param separator String containing the String to be used as a delimiter,
2554 * <code>null</code> splits on whitespace
2555 * @param max the maximum number of elements to include in the returned
2556 * array. A zero or negative value implies no limit.
2557 * @return an array of parsed Strings, <code>null</code> if null String was input
2558 * @since 2.4
2559 */
2560 public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator, int max) {
2561 return splitByWholeSeparatorWorker(str, separator, max, true);
2562 }
2563
2564 /**
2565 * Performs the logic for the <code>splitByWholeSeparatorPreserveAllTokens</code> methods.
2566 *
2567 * @param str the String to parse, may be <code>null</code>
2568 * @param separator String containing the String to be used as a delimiter,
2569 * <code>null</code> splits on whitespace
2570 * @param max the maximum number of elements to include in the returned
2571 * array. A zero or negative value implies no limit.
2572 * @param preserveAllTokens if <code>true</code>, adjacent separators are
2573 * treated as empty token separators; if <code>false</code>, adjacent
2574 * separators are treated as one separator.
2575 * @return an array of parsed Strings, <code>null</code> if null String input
2576 * @since 2.4
2577 */
2578 private static String[] splitByWholeSeparatorWorker(String str, String separator, int max,
2579 boolean preserveAllTokens)
2580 {
2581 if (str == null) {
2582 return null;
2583 }
2584
2585 int len = str.length();
2586
2587 if (len == 0) {
2588 return ArrayUtils.EMPTY_STRING_ARRAY;
2589 }
2590
2591 if ((separator == null) || (EMPTY.equals(separator))) {
2592 // Split on whitespace.
2593 return splitWorker(str, null, max, preserveAllTokens);
2594 }
2595
2596 int separatorLength = separator.length();
2597
2598 ArrayList substrings = new ArrayList();
2599 int numberOfSubstrings = 0;
2600 int beg = 0;
2601 int end = 0;
2602 while (end < len) {
2603 end = str.indexOf(separator, beg);
2604
2605 if (end > -1) {
2606 if (end > beg) {
2607 numberOfSubstrings += 1;
2608
2609 if (numberOfSubstrings == max) {
2610 end = len;
2611 substrings.add(str.substring(beg));
2612 } else {
2613 // The following is OK, because String.substring( beg, end ) excludes
2614 // the character at the position 'end'.
2615 substrings.add(str.substring(beg, end));
2616
2617 // Set the starting point for the next search.
2618 // The following is equivalent to beg = end + (separatorLength - 1) + 1,
2619 // which is the right calculation:
2620 beg = end + separatorLength;
2621 }
2622 } else {
2623 // We found a consecutive occurrence of the separator, so skip it.
2624 if (preserveAllTokens) {
2625 numberOfSubstrings += 1;
2626 if (numberOfSubstrings == max) {
2627 end = len;
2628 substrings.add(str.substring(beg));
2629 } else {
2630 substrings.add(EMPTY);
2631 }
2632 }
2633 beg = end + separatorLength;
2634 }
2635 } else {
2636 // String.substring( beg ) goes from 'beg' to the end of the String.
2637 substrings.add(str.substring(beg));
2638 end = len;
2639 }
2640 }
2641
2642 return (String[]) substrings.toArray(new String[substrings.size()]);
2643 }
2644
2645 // -----------------------------------------------------------------------
2646 /**
2647 * <p>Splits the provided text into an array, using whitespace as the
2648 * separator, preserving all tokens, including empty tokens created by
2649 * adjacent separators. This is an alternative to using StringTokenizer.
2650 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
2651 *
2652 * <p>The separator is not included in the returned String array.
2653 * Adjacent separators are treated as separators for empty tokens.
2654 * For more control over the split use the StrTokenizer class.</p>
2655 *
2656 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2657 *
2658 * <pre>
2659 * StringUtils.splitPreserveAllTokens(null) = null
2660 * StringUtils.splitPreserveAllTokens("") = []
2661 * StringUtils.splitPreserveAllTokens("abc def") = ["abc", "def"]
2662 * StringUtils.splitPreserveAllTokens("abc def") = ["abc", "", "def"]
2663 * StringUtils.splitPreserveAllTokens(" abc ") = ["", "abc", ""]
2664 * </pre>
2665 *
2666 * @param str the String to parse, may be <code>null</code>
2667 * @return an array of parsed Strings, <code>null</code> if null String input
2668 * @since 2.1
2669 */
2670 public static String[] splitPreserveAllTokens(String str) {
2671 return splitWorker(str, null, -1, true);
2672 }
2673
2674 /**
2675 * <p>Splits the provided text into an array, separator specified,
2676 * preserving all tokens, including empty tokens created by adjacent
2677 * separators. This is an alternative to using StringTokenizer.</p>
2678 *
2679 * <p>The separator is not included in the returned String array.
2680 * Adjacent separators are treated as separators for empty tokens.
2681 * For more control over the split use the StrTokenizer class.</p>
2682 *
2683 * <p>A <code>null</code> input String returns <code>null</code>.</p>
2684 *
2685 * <pre>
2686 * StringUtils.splitPreserveAllTokens(null, *) = null
2687 * StringUtils.splitPreserveAllTokens("", *) = []
2688 * StringUtils.splitPreserveAllTokens("a.b.c", '.') = ["a", "b", "c"]
2689 * StringUtils.splitPreserveAllTokens("a..b.c", '.') = ["a", "", "b", "c"]
2690 * StringUtils.splitPreserveAllTokens("a:b:c", '.') = ["a:b:c"]
2691 * StringUtils.splitPreserveAllTokens("a\tb\nc", null) = ["a", "b", "c"]
2692 * StringUtils.splitPreserveAllTokens("a b c", ' ') = ["a", "b", "c"]
2693 * StringUtils.splitPreserveAllTokens("a b c ", ' ') = ["a", "b", "c", ""]
2694 * StringUtils.splitPreserveAllTokens("a b c ", ' ') = ["a", "b", "c", "", ""]
2695 * StringUtils.splitPreserveAllTokens(" a b c", ' ') = ["", a", "b", "c"]
2696 * StringUtils.splitPreserveAllTokens(" a b c", ' ') = ["", "", a", "b", "c"]
2697 * StringUtils.splitPreserveAllTokens(" a b c ", ' ') = ["", a", "b", "c", ""]
2698 * </pre>
2699 *
2700 * @param str the String to parse, may be <code>null</code>
2701 * @param separatorChar the character used as the delimiter,
2702 * <code>null</code> splits on whitespace
2703 * @return an array of parsed Strings, <code>null</code> if null String input
2704 * @since 2.1
2705 */
2706 public static String[] splitPreserveAllTokens(String str, char separatorChar) {
2707 return splitWorker(str, separatorChar, true);
2708 }
2709
2710 /**
2711 * Performs the logic for the <code>split</code> and
2712 * <code>splitPreserveAllTokens</code> methods that do not return a
2713 * maximum array length.
2714 *
2715 * @param str the String to parse, may be <code>null</code>
2716 * @param separatorChar the separate character
2717 * @param preserveAllTokens if <code>true</code>, adjacent separators are
2718 * treated as empty token separators; if <code>false</code>, adjacent
2719 * separators are treated as one separator.
2720 * @return an array of parsed Strings, <code>null</code> if null String input
2721 */
2722 private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
2723 // Performance tuned for 2.0 (JDK1.4)
2724
2725 if (str == null) {
2726 return null;
2727 }
2728 int len = str.length();
2729 if (len == 0) {
2730 return ArrayUtils.EMPTY_STRING_ARRAY;
2731 }
2732 List list = new ArrayList();
2733 int i = 0, start = 0;
2734 boolean match = false;
2735 boolean lastMatch = false;
2736 while (i < len) {
2737 if (str.charAt(i) == separatorChar) {
2738 if (match || preserveAllTokens) {
2739 list.add(str.substring(start, i));
2740 match = false;
2741 lastMatch = true;
2742 }
2743 start = ++i;
2744 continue;
2745 }
2746 lastMatch = false;
2747 match = true;
2748 i++;
2749 }
2750 if (match || (preserveAllTokens && lastMatch)) {
2751 list.add(str.substring(start, i));
2752 }
2753 return (String[]) list.toArray(new String[list.size()]);
2754 }
2755
2756 /**
2757 * <p>Splits the provided text into an array, separators specified,
2758 * preserving all tokens, including empty tokens created by adjacent
2759 * separators. This is an alternative to using StringTokenizer.</p>
2760 *
2761 * <p>The separator is not included in the returned String array.
2762 * Adjacent separators are treated as separators for empty tokens.
2763 * For more control over the split use the StrTokenizer class.</p>
2764 *
2765 * <p>A <code>null</code> input String returns <code>null</code>.
2766 * A <code>null</code> separatorChars splits on whitespace.</p>
2767 *
2768 * <pre>
2769 * StringUtils.splitPreserveAllTokens(null, *) = null
2770 * StringUtils.splitPreserveAllTokens("", *) = []
2771 * StringUtils.splitPreserveAllTokens("abc def", null) = ["abc", "def"]
2772 * StringUtils.splitPreserveAllTokens("abc def", " ") = ["abc", "def"]
2773 * StringUtils.splitPreserveAllTokens("abc def", " ") = ["abc", "", def"]
2774 * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":") = ["ab", "cd", "ef"]
2775 * StringUtils.splitPreserveAllTokens("ab:cd:ef:", ":") = ["ab", "cd", "ef", ""]
2776 * StringUtils.splitPreserveAllTokens("ab:cd:ef::", ":") = ["ab", "cd", "ef", "", ""]
2777 * StringUtils.splitPreserveAllTokens("ab::cd:ef", ":") = ["ab", "", cd", "ef"]
2778 * StringUtils.splitPreserveAllTokens(":cd:ef", ":") = ["", cd", "ef"]
2779 * StringUtils.splitPreserveAllTokens("::cd:ef", ":") = ["", "", cd", "ef"]
2780 * StringUtils.splitPreserveAllTokens(":cd:ef:", ":") = ["", cd", "ef", ""]
2781 * </pre>
2782 *
2783 * @param str the String to parse, may be <code>null</code>
2784 * @param separatorChars the characters used as the delimiters,
2785 * <code>null</code> splits on whitespace
2786 * @return an array of parsed Strings, <code>null</code> if null String input
2787 * @since 2.1
2788 */
2789 public static String[] splitPreserveAllTokens(String str, String separatorChars) {
2790 return splitWorker(str, separatorChars, -1, true);
2791 }
2792
2793 /**
2794 * <p>Splits the provided text into an array with a maximum length,
2795 * separators specified, preserving all tokens, including empty tokens
2796 * created by adjacent separators.</p>
2797 *
2798 * <p>The separator is not included in the returned String array.
2799 * Adjacent separators are treated as separators for empty tokens.
2800 * Adjacent separators are treated as one separator.</p>
2801 *
2802 * <p>A <code>null</code> input String returns <code>null</code>.
2803 * A <code>null</code> separatorChars splits on whitespace.</p>
2804 *
2805 * <p>If more than <code>max</code> delimited substrings are found, the last
2806 * returned string includes all characters after the first <code>max - 1</code>
2807 * returned strings (including separator characters).</p>
2808 *
2809 * <pre>
2810 * StringUtils.splitPreserveAllTokens(null, *, *) = null
2811 * StringUtils.splitPreserveAllTokens("", *, *) = []
2812 * StringUtils.splitPreserveAllTokens("ab de fg", null, 0) = ["ab", "cd", "ef"]
2813 * StringUtils.splitPreserveAllTokens("ab de fg", null, 0) = ["ab", "cd", "ef"]
2814 * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 0) = ["ab", "cd", "ef"]
2815 * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 2) = ["ab", "cd:ef"]
2816 * StringUtils.splitPreserveAllTokens("ab de fg", null, 2) = ["ab", " de fg"]
2817 * StringUtils.splitPreserveAllTokens("ab de fg", null, 3) = ["ab", "", " de fg"]
2818 * StringUtils.splitPreserveAllTokens("ab de fg", null, 4) = ["ab", "", "", "de fg"]
2819 * </pre>
2820 *
2821 * @param str the String to parse, may be <code>null</code>
2822 * @param separatorChars the characters used as the delimiters,
2823 * <code>null</code> splits on whitespace
2824 * @param max the maximum number of elements to include in the
2825 * array. A zero or negative value implies no limit
2826 * @return an array of parsed Strings, <code>null</code> if null String input
2827 * @since 2.1
2828 */
2829 public static String[] splitPreserveAllTokens(String str, String separatorChars, int max) {
2830 return splitWorker(str, separatorChars, max, true);
2831 }
2832
2833 /**
2834 * Performs the logic for the <code>split</code> and
2835 * <code>splitPreserveAllTokens</code> methods that return a maximum array
2836 * length.
2837 *
2838 * @param str the String to parse, may be <code>null</code>
2839 * @param separatorChars the separate character
2840 * @param max the maximum number of elements to include in the
2841 * array. A zero or negative value implies no limit.
2842 * @param preserveAllTokens if <code>true</code>, adjacent separators are
2843 * treated as empty token separators; if <code>false</code>, adjacent
2844 * separators are treated as one separator.
2845 * @return an array of parsed Strings, <code>null</code> if null String input
2846 */
2847 private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
2848 // Performance tuned for 2.0 (JDK1.4)
2849 // Direct code is quicker than StringTokenizer.
2850 // Also, StringTokenizer uses isSpace() not isWhitespace()
2851
2852 if (str == null) {
2853 return null;
2854 }
2855 int len = str.length();
2856 if (len == 0) {
2857 return ArrayUtils.EMPTY_STRING_ARRAY;
2858 }
2859 List list = new ArrayList();
2860 int sizePlus1 = 1;
2861 int i = 0, start = 0;
2862 boolean match = false;
2863 boolean lastMatch = false;
2864 if (separatorChars == null) {
2865 // Null separator means use whitespace
2866 while (i < len) {
2867 if (Character.isWhitespace(str.charAt(i))) {
2868 if (match || preserveAllTokens) {
2869 lastMatch = true;
2870 if (sizePlus1++ == max) {
2871 i = len;
2872 lastMatch = false;
2873 }
2874 list.add(str.substring(start, i));
2875 match = false;
2876 }
2877 start = ++i;
2878 continue;
2879 }
2880 lastMatch = false;
2881 match = true;
2882 i++;
2883 }
2884 } else if (separatorChars.length() == 1) {
2885 // Optimise 1 character case
2886 char sep = separatorChars.charAt(0);
2887 while (i < len) {
2888 if (str.charAt(i) == sep) {
2889 if (match || preserveAllTokens) {
2890 lastMatch = true;
2891 if (sizePlus1++ == max) {
2892 i = len;
2893 lastMatch = false;
2894 }
2895 list.add(str.substring(start, i));
2896 match = false;
2897 }
2898 start = ++i;
2899 continue;
2900 }
2901 lastMatch = false;
2902 match = true;
2903 i++;
2904 }
2905 } else {
2906 // standard case
2907 while (i < len) {
2908 if (separatorChars.indexOf(str.charAt(i)) >= 0) {
2909 if (match || preserveAllTokens) {
2910 lastMatch = true;
2911 if (sizePlus1++ == max) {
2912 i = len;
2913 lastMatch = false;
2914 }
2915 list.add(str.substring(start, i));
2916 match = false;
2917 }
2918 start = ++i;
2919 continue;
2920 }
2921 lastMatch = false;
2922 match = true;
2923 i++;
2924 }
2925 }
2926 if (match || (preserveAllTokens && lastMatch)) {
2927 list.add(str.substring(start, i));
2928 }
2929 return (String[]) list.toArray(new String[list.size()]);
2930 }
2931
2932 /**
2933 * <p>Splits a String by Character type as returned by
2934 * <code>java.lang.Character.getType(char)</code>. Groups of contiguous
2935 * characters of the same type are returned as complete tokens.
2936 * <pre>
2937 * StringUtils.splitByCharacterType(null) = null
2938 * StringUtils.splitByCharacterType("") = []
2939 * StringUtils.splitByCharacterType("ab de fg") = ["ab", " ", "de", " ", "fg"]
2940 * StringUtils.splitByCharacterType("ab de fg") = ["ab", " ", "de", " ", "fg"]
2941 * StringUtils.splitByCharacterType("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
2942 * StringUtils.splitByCharacterType("number5") = ["number", "5"]
2943 * StringUtils.splitByCharacterType("fooBar") = ["foo", "B", "ar"]
2944 * StringUtils.splitByCharacterType("foo200Bar") = ["foo", "200", "B", "ar"]
2945 * StringUtils.splitByCharacterType("ASFRules") = ["ASFR", "ules"]
2946 * </pre>
2947 * @param str the String to split, may be <code>null</code>
2948 * @return an array of parsed Strings, <code>null</code> if null String input
2949 * @since 2.4
2950 */
2951 public static String[] splitByCharacterType(String str) {
2952 return splitByCharacterType(str, false);
2953 }
2954
2955 /**
2956 * <p>Splits a String by Character type as returned by
2957 * <code>java.lang.Character.getType(char)</code>. Groups of contiguous
2958 * characters of the same type are returned as complete tokens, with the
2959 * following exception: the character of type
2960 * <code>Character.UPPERCASE_LETTER</code>, if any, immediately
2961 * preceding a token of type <code>Character.LOWERCASE_LETTER</code>
2962 * will belong to the following token rather than to the preceding, if any,
2963 * <code>Character.UPPERCASE_LETTER</code> token.
2964 * <pre>
2965 * StringUtils.splitByCharacterTypeCamelCase(null) = null
2966 * StringUtils.splitByCharacterTypeCamelCase("") = []
2967 * StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
2968 * StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
2969 * StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
2970 * StringUtils.splitByCharacterTypeCamelCase("number5") = ["number", "5"]
2971 * StringUtils.splitByCharacterTypeCamelCase("fooBar") = ["foo", "Bar"]
2972 * StringUtils.splitByCharacterTypeCamelCase("foo200Bar") = ["foo", "200", "Bar"]
2973 * StringUtils.splitByCharacterTypeCamelCase("ASFRules") = ["ASF", "Rules"]
2974 * </pre>
2975 * @param str the String to split, may be <code>null</code>
2976 * @return an array of parsed Strings, <code>null</code> if null String input
2977 * @since 2.4
2978 */
2979 public static String[] splitByCharacterTypeCamelCase(String str) {
2980 return splitByCharacterType(str, true);
2981 }
2982
2983 /**
2984 * <p>Splits a String by Character type as returned by
2985 * <code>java.lang.Character.getType(char)</code>. Groups of contiguous
2986 * characters of the same type are returned as complete tokens, with the
2987 * following exception: if <code>camelCase</code> is <code>true</code>,
2988 * the character of type <code>Character.UPPERCASE_LETTER</code>, if any,
2989 * immediately preceding a token of type <code>Character.LOWERCASE_LETTER</code>
2990 * will belong to the following token rather than to the preceding, if any,
2991 * <code>Character.UPPERCASE_LETTER</code> token.
2992 * @param str the String to split, may be <code>null</code>
2993 * @param camelCase whether to use so-called "camel-case" for letter types
2994 * @return an array of parsed Strings, <code>null</code> if null String input
2995 * @since 2.4
2996 */
2997 private static String[] splitByCharacterType(String str, boolean camelCase) {
2998 if (str == null) {
2999 return null;
3000 }
3001 if (str.length() == 0) {
3002 return ArrayUtils.EMPTY_STRING_ARRAY;
3003 }
3004 char[] c = str.toCharArray();
3005 List list = new ArrayList();
3006 int tokenStart = 0;
3007 int currentType = Character.getType(c[tokenStart]);
3008 for (int pos = tokenStart + 1; pos < c.length; pos++) {
3009 int type = Character.getType(c[pos]);
3010 if (type == currentType) {
3011 continue;
3012 }
3013 if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) {
3014 int newTokenStart = pos - 1;
3015 if (newTokenStart != tokenStart) {
3016 list.add(new String(c, tokenStart, newTokenStart - tokenStart));
3017 tokenStart = newTokenStart;
3018 }
3019 } else {
3020 list.add(new String(c, tokenStart, pos - tokenStart));
3021 tokenStart = pos;
3022 }
3023 currentType = type;
3024 }
3025 list.add(new String(c, tokenStart, c.length - tokenStart));
3026 return (String[]) list.toArray(new String[list.size()]);
3027 }
3028
3029 // Joining
3030 //-----------------------------------------------------------------------
3031 /**
3032 * <p>Concatenates elements of an array into a single String.
3033 * Null objects or empty strings within the array are represented by
3034 * empty strings.</p>
3035 *
3036 * <pre>
3037 * StringUtils.concatenate(null) = null
3038 * StringUtils.concatenate([]) = ""
3039 * StringUtils.concatenate([null]) = ""
3040 * StringUtils.concatenate(["a", "b", "c"]) = "abc"
3041 * StringUtils.concatenate([null, "", "a"]) = "a"
3042 * </pre>
3043 *
3044 * @param array the array of values to concatenate, may be null
3045 * @return the concatenated String, <code>null</code> if null array input
3046 * @deprecated Use the better named {@link #join(Object[])} instead.
3047 * Method will be removed in Commons Lang 3.0.
3048 */
3049 public static String concatenate(Object[] array) {
3050 return join(array, null);
3051 }
3052
3053 /**
3054 * <p>Joins the elements of the provided array into a single String
3055 * containing the provided list of elements.</p>
3056 *
3057 * <p>No separator is added to the joined String.
3058 * Null objects or empty strings within the array are represented by
3059 * empty strings.</p>
3060 *
3061 * <pre>
3062 * StringUtils.join(null) = null
3063 * StringUtils.join([]) = ""
3064 * StringUtils.join([null]) = ""
3065 * StringUtils.join(["a", "b", "c"]) = "abc"
3066 * StringUtils.join([null, "", "a"]) = "a"
3067 * </pre>
3068 *
3069 * @param array the array of values to join together, may be null
3070 * @return the joined String, <code>null</code> if null array input
3071 * @since 2.0
3072 */
3073 public static String join(Object[] array) {
3074 return join(array, null);
3075 }
3076
3077 /**
3078 * <p>Joins the elements of the provided array into a single String
3079 * containing the provided list of elements.</p>
3080 *
3081 * <p>No delimiter is added before or after the list.
3082 * Null objects or empty strings within the array are represented by
3083 * empty strings.</p>
3084 *
3085 * <pre>
3086 * StringUtils.join(null, *) = null
3087 * StringUtils.join([], *) = ""
3088 * StringUtils.join([null], *) = ""
3089 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
3090 * StringUtils.join(["a", "b", "c"], null) = "abc"
3091 * StringUtils.join([null, "", "a"], ';') = ";;a"
3092 * </pre>
3093 *
3094 * @param array the array of values to join together, may be null
3095 * @param separator the separator character to use
3096 * @return the joined String, <code>null</code> if null array input
3097 * @since 2.0
3098 */
3099 public static String join(Object[] array, char separator) {
3100 if (array == null) {
3101 return null;
3102 }
3103
3104 return join(array, separator, 0, array.length);
3105 }
3106
3107 /**
3108 * <p>Joins the elements of the provided array into a single String
3109 * containing the provided list of elements.</p>
3110 *
3111 * <p>No delimiter is added before or after the list.
3112 * Null objects or empty strings within the array are represented by
3113 * empty strings.</p>
3114 *
3115 * <pre>
3116 * StringUtils.join(null, *) = null
3117 * StringUtils.join([], *) = ""
3118 * StringUtils.join([null], *) = ""
3119 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
3120 * StringUtils.join(["a", "b", "c"], null) = "abc"
3121 * StringUtils.join([null, "", "a"], ';') = ";;a"
3122 * </pre>
3123 *
3124 * @param array the array of values to join together, may be null
3125 * @param separator the separator character to use
3126 * @param startIndex the first index to start joining from. It is
3127 * an error to pass in an end index past the end of the array
3128 * @param endIndex the index to stop joining from (exclusive). It is
3129 * an error to pass in an end index past the end of the array
3130 * @return the joined String, <code>null</code> if null array input
3131 * @since 2.0
3132 */
3133 public static String join(Object[] array, char separator, int startIndex, int endIndex) {
3134 if (array == null) {
3135 return null;
3136 }
3137 int bufSize = (endIndex - startIndex);
3138 if (bufSize <= 0) {
3139 return EMPTY;
3140 }
3141
3142 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length()) + 1);
3143 StringBuffer buf = new StringBuffer(bufSize);
3144
3145 for (int i = startIndex; i < endIndex; i++) {
3146 if (i > startIndex) {
3147 buf.append(separator);
3148 }
3149 if (array[i] != null) {
3150 buf.append(array[i]);
3151 }
3152 }
3153 return buf.toString();
3154 }
3155
3156
3157 /**
3158 * <p>Joins the elements of the provided array into a single String
3159 * containing the provided list of elements.</p>
3160 *
3161 * <p>No delimiter is added before or after the list.
3162 * A <code>null</code> separator is the same as an empty String ("").
3163 * Null objects or empty strings within the array are represented by
3164 * empty strings.</p>
3165 *
3166 * <pre>
3167 * StringUtils.join(null, *) = null
3168 * StringUtils.join([], *) = ""
3169 * StringUtils.join([null], *) = ""
3170 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
3171 * StringUtils.join(["a", "b", "c"], null) = "abc"
3172 * StringUtils.join(["a", "b", "c"], "") = "abc"
3173 * StringUtils.join([null, "", "a"], ',') = ",,a"
3174 * </pre>
3175 *
3176 * @param array the array of values to join together, may be null
3177 * @param separator the separator character to use, null treated as ""
3178 * @return the joined String, <code>null</code> if null array input
3179 */
3180 public static String join(Object[] array, String separator) {
3181 if (array == null) {
3182 return null;
3183 }
3184 return join(array, separator, 0, array.length);
3185 }
3186
3187 /**
3188 * <p>Joins the elements of the provided array into a single String
3189 * containing the provided list of elements.</p>
3190 *
3191 * <p>No delimiter is added before or after the list.
3192 * A <code>null</code> separator is the same as an empty String ("").
3193 * Null objects or empty strings within the array are represented by
3194 * empty strings.</p>
3195 *
3196 * <pre>
3197 * StringUtils.join(null, *) = null
3198 * StringUtils.join([], *) = ""
3199 * StringUtils.join([null], *) = ""
3200 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
3201 * StringUtils.join(["a", "b", "c"], null) = "abc"
3202 * StringUtils.join(["a", "b", "c"], "") = "abc"
3203 * StringUtils.join([null, "", "a"], ',') = ",,a"
3204 * </pre>
3205 *
3206 * @param array the array of values to join together, may be null
3207 * @param separator the separator character to use, null treated as ""
3208 * @param startIndex the first index to start joining from. It is
3209 * an error to pass in an end index past the end of the array
3210 * @param endIndex the index to stop joining from (exclusive). It is
3211 * an error to pass in an end index past the end of the array
3212 * @return the joined String, <code>null</code> if null array input
3213 */
3214 public static String join(Object[] array, String separator, int startIndex, int endIndex) {
3215 if (array == null) {
3216 return null;
3217 }
3218 if (separator == null) {
3219 separator = EMPTY;
3220 }
3221
3222 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
3223 // (Assuming that all Strings are roughly equally long)
3224 int bufSize = (endIndex - startIndex);
3225 if (bufSize <= 0) {
3226 return EMPTY;
3227 }
3228
3229 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length())
3230 + separator.length());
3231
3232 StringBuffer buf = new StringBuffer(bufSize);
3233
3234 for (int i = startIndex; i < endIndex; i++) {
3235 if (i > startIndex) {
3236 buf.append(separator);
3237 }
3238 if (array[i] != null) {
3239 buf.append(array[i]);
3240 }
3241 }
3242 return buf.toString();
3243 }
3244
3245 /**
3246 * <p>Joins the elements of the provided <code>Iterator</code> into
3247 * a single String containing the provided elements.</p>
3248 *
3249 * <p>No delimiter is added before or after the list. Null objects or empty
3250 * strings within the iteration are represented by empty strings.</p>
3251 *
3252 * <p>See the examples here: {@link #join(Object[],char)}. </p>
3253 *
3254 * @param iterator the <code>Iterator</code> of values to join together, may be null
3255 * @param separator the separator character to use
3256 * @return the joined String, <code>null</code> if null iterator input
3257 * @since 2.0
3258 */
3259 public static String join(Iterator iterator, char separator) {
3260
3261 // handle null, zero and one elements before building a buffer
3262 if (iterator == null) {
3263 return null;
3264 }
3265 if (!iterator.hasNext()) {
3266 return EMPTY;
3267 }
3268 Object first = iterator.next();
3269 if (!iterator.hasNext()) {
3270 return ObjectUtils.toString(first);
3271 }
3272
3273 // two or more elements
3274 StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small
3275 if (first != null) {
3276 buf.append(first);
3277 }
3278
3279 while (iterator.hasNext()) {
3280 buf.append(separator);
3281 Object obj = iterator.next();
3282 if (obj != null) {
3283 buf.append(obj);
3284 }
3285 }
3286
3287 return buf.toString();
3288 }
3289
3290 /**
3291 * <p>Joins the elements of the provided <code>Iterator</code> into
3292 * a single String containing the provided elements.</p>
3293 *
3294 * <p>No delimiter is added before or after the list.
3295 * A <code>null</code> separator is the same as an empty String ("").</p>
3296 *
3297 * <p>See the examples here: {@link #join(Object[],String)}. </p>
3298 *
3299 * @param iterator the <code>Iterator</code> of values to join together, may be null
3300 * @param separator the separator character to use, null treated as ""
3301 * @return the joined String, <code>null</code> if null iterator input
3302 */
3303 public static String join(Iterator iterator, String separator) {
3304
3305 // handle null, zero and one elements before building a buffer
3306 if (iterator == null) {
3307 return null;
3308 }
3309 if (!iterator.hasNext()) {
3310 return EMPTY;
3311 }
3312 Object first = iterator.next();
3313 if (!iterator.hasNext()) {
3314 return ObjectUtils.toString(first);
3315 }
3316
3317 // two or more elements
3318 StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small
3319 if (first != null) {
3320 buf.append(first);
3321 }
3322
3323 while (iterator.hasNext()) {
3324 if (separator != null) {
3325 buf.append(separator);
3326 }
3327 Object obj = iterator.next();
3328 if (obj != null) {
3329 buf.append(obj);
3330 }
3331 }
3332 return buf.toString();
3333 }
3334
3335 /**
3336 * <p>Joins the elements of the provided <code>Collection</code> into
3337 * a single String containing the provided elements.</p>
3338 *
3339 * <p>No delimiter is added before or after the list. Null objects or empty
3340 * strings within the iteration are represented by empty strings.</p>
3341 *
3342 * <p>See the examples here: {@link #join(Object[],char)}. </p>
3343 *
3344 * @param collection the <code>Collection</code> of values to join together, may be null
3345 * @param separator the separator character to use
3346 * @return the joined String, <code>null</code> if null iterator input
3347 * @since 2.3
3348 */
3349 public static String join(Collection collection, char separator) {
3350 if (collection == null) {
3351 return null;
3352 }
3353 return join(collection.iterator(), separator);
3354 }
3355
3356 /**
3357 * <p>Joins the elements of the provided <code>Collection</code> into
3358 * a single String containing the provided elements.</p>
3359 *
3360 * <p>No delimiter is added before or after the list.
3361 * A <code>null</code> separator is the same as an empty String ("").</p>
3362 *
3363 * <p>See the examples here: {@link #join(Object[],String)}. </p>
3364 *
3365 * @param collection the <code>Collection</code> of values to join together, may be null
3366 * @param separator the separator character to use, null treated as ""
3367 * @return the joined String, <code>null</code> if null iterator input
3368 * @since 2.3
3369 */
3370 public static String join(Collection collection, String separator) {
3371 if (collection == null) {
3372 return null;
3373 }
3374 return join(collection.iterator(), separator);
3375 }
3376
3377 // Delete
3378 //-----------------------------------------------------------------------
3379 /**
3380 * <p>Deletes all 'space' characters from a String as defined by
3381 * {@link Character#isSpace(char)}.</p>
3382 *
3383 * <p>This is the only StringUtils method that uses the
3384 * <code>isSpace</code> definition. You are advised to use
3385 * {@link #deleteWhitespace(String)} instead as whitespace is much
3386 * better localized.</p>
3387 *
3388 * <pre>
3389 * StringUtils.deleteSpaces(null) = null
3390 * StringUtils.deleteSpaces("") = ""
3391 * StringUtils.deleteSpaces("abc") = "abc"
3392 * StringUtils.deleteSpaces(" \t abc \n ") = "abc"
3393 * StringUtils.deleteSpaces("ab c") = "abc"
3394 * StringUtils.deleteSpaces("a\nb\tc ") = "abc"
3395 * </pre>
3396 *
3397 * <p>Spaces are defined as <code>{' ', '\t', '\r', '\n', '\b'}</code>
3398 * in line with the deprecated <code>isSpace</code> method.</p>
3399 *
3400 * @param str the String to delete spaces from, may be null
3401 * @return the String without 'spaces', <code>null</code> if null String input
3402 * @deprecated Use the better localized {@link #deleteWhitespace(String)}.
3403 * Method will be removed in Commons Lang 3.0.
3404 */
3405 public static String deleteSpaces(String str) {
3406 if (str == null) {
3407 return null;
3408 }
3409 return CharSetUtils.delete(str, " \t\r\n\b");
3410 }
3411
3412 /**
3413 * <p>Deletes all whitespaces from a String as defined by
3414 * {@link Character#isWhitespace(char)}.</p>
3415 *
3416 * <pre>
3417 * StringUtils.deleteWhitespace(null) = null
3418 * StringUtils.deleteWhitespace("") = ""
3419 * StringUtils.deleteWhitespace("abc") = "abc"
3420 * StringUtils.deleteWhitespace(" ab c ") = "abc"
3421 * </pre>
3422 *
3423 * @param str the String to delete whitespace from, may be null
3424 * @return the String without whitespaces, <code>null</code> if null String input
3425 */
3426 public static String deleteWhitespace(String str) {
3427 if (isEmpty(str)) {
3428 return str;
3429 }
3430 int sz = str.length();
3431 char[] chs = new char[sz];
3432 int count = 0;
3433 for (int i = 0; i < sz; i++) {
3434 if (!Character.isWhitespace(str.charAt(i))) {
3435 chs[count++] = str.charAt(i);
3436 }
3437 }
3438 if (count == sz) {
3439 return str;
3440 }
3441 return new String(chs, 0, count);
3442 }
3443
3444 // Remove
3445 //-----------------------------------------------------------------------
3446 /**
3447 * <p>Removes a substring only if it is at the begining of a source string,
3448 * otherwise returns the source string.</p>
3449 *
3450 * <p>A <code>null</code> source string will return <code>null</code>.
3451 * An empty ("") source string will return the empty string.
3452 * A <code>null</code> search string will return the source string.</p>
3453 *
3454 * <pre>
3455 * StringUtils.removeStart(null, *) = null
3456 * StringUtils.removeStart("", *) = ""
3457 * StringUtils.removeStart(*, null) = *
3458 * StringUtils.removeStart("www.domain.com", "www.") = "domain.com"
3459 * StringUtils.removeStart("domain.com", "www.") = "domain.com"
3460 * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
3461 * StringUtils.removeStart("abc", "") = "abc"
3462 * </pre>
3463 *
3464 * @param str the source String to search, may be null
3465 * @param remove the String to search for and remove, may be null
3466 * @return the substring with the string removed if found,
3467 * <code>null</code> if null String input
3468 * @since 2.1
3469 */
3470 public static String removeStart(String str, String remove) {
3471 if (isEmpty(str) || isEmpty(remove)) {
3472 return str;
3473 }
3474 if (str.startsWith(remove)){
3475 return str.substring(remove.length());
3476 }
3477 return str;
3478 }
3479
3480 /**
3481 * <p>Case insensitive removal of a substring if it is at the begining of a source string,
3482 * otherwise returns the source string.</p>
3483 *
3484 * <p>A <code>null</code> source string will return <code>null</code>.
3485 * An empty ("") source string will return the empty string.
3486 * A <code>null</code> search string will return the source string.</p>
3487 *
3488 * <pre>
3489 * StringUtils.removeStartIgnoreCase(null, *) = null
3490 * StringUtils.removeStartIgnoreCase("", *) = ""
3491 * StringUtils.removeStartIgnoreCase(*, null) = *
3492 * StringUtils.removeStartIgnoreCase("www.domain.com", "www.") = "domain.com"
3493 * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.") = "domain.com"
3494 * StringUtils.removeStartIgnoreCase("domain.com", "www.") = "domain.com"
3495 * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain.com"
3496 * StringUtils.removeStartIgnoreCase("abc", "") = "abc"
3497 * </pre>
3498 *
3499 * @param str the source String to search, may be null
3500 * @param remove the String to search for (case insensitive) and remove, may be null
3501 * @return the substring with the string removed if found,
3502 * <code>null</code> if null String input
3503 * @since 2.4
3504 */
3505 public static String removeStartIgnoreCase(String str, String remove) {
3506 if (isEmpty(str) || isEmpty(remove)) {
3507 return str;
3508 }
3509 if (startsWithIgnoreCase(str, remove)) {
3510 return str.substring(remove.length());
3511 }
3512 return str;
3513 }
3514
3515 /**
3516 * <p>Removes a substring only if it is at the end of a source string,
3517 * otherwise returns the source string.</p>
3518 *
3519 * <p>A <code>null</code> source string will return <code>null</code>.
3520 * An empty ("") source string will return the empty string.
3521 * A <code>null</code> search string will return the source string.</p>
3522 *
3523 * <pre>
3524 * StringUtils.removeEnd(null, *) = null
3525 * StringUtils.removeEnd("", *) = ""
3526 * StringUtils.removeEnd(*, null) = *
3527 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com"
3528 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
3529 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
3530 * StringUtils.removeEnd("abc", "") = "abc"
3531 * </pre>
3532 *
3533 * @param str the source String to search, may be null
3534 * @param remove the String to search for and remove, may be null
3535 * @return the substring with the string removed if found,
3536 * <code>null</code> if null String input
3537 * @since 2.1
3538 */
3539 public static String removeEnd(String str, String remove) {
3540 if (isEmpty(str) || isEmpty(remove)) {
3541 return str;
3542 }
3543 if (str.endsWith(remove)) {
3544 return str.substring(0, str.length() - remove.length());
3545 }
3546 return str;
3547 }
3548
3549 /**
3550 * <p>Case insensitive removal of a substring if it is at the end of a source string,
3551 * otherwise returns the source string.</p>
3552 *
3553 * <p>A <code>null</code> source string will return <code>null</code>.
3554 * An empty ("") source string will return the empty string.
3555 * A <code>null</code> search string will return the source string.</p>
3556 *
3557 * <pre>
3558 * StringUtils.removeEndIgnoreCase(null, *) = null
3559 * StringUtils.removeEndIgnoreCase("", *) = ""
3560 * StringUtils.removeEndIgnoreCase(*, null) = *
3561 * StringUtils.removeEndIgnoreCase("www.domain.com", ".com.") = "www.domain.com"
3562 * StringUtils.removeEndIgnoreCase("www.domain.com", ".com") = "www.domain"
3563 * StringUtils.removeEndIgnoreCase("www.domain.com", "domain") = "www.domain.com"
3564 * StringUtils.removeEndIgnoreCase("abc", "") = "abc"
3565 * StringUtils.removeEndIgnoreCase("www.domain.com", ".COM") = "www.domain")
3566 * StringUtils.removeEndIgnoreCase("www.domain.COM", ".com") = "www.domain")
3567 * </pre>
3568 *
3569 * @param str the source String to search, may be null
3570 * @param remove the String to search for (case insensitive) and remove, may be null
3571 * @return the substring with the string removed if found,
3572 * <code>null</code> if null String input
3573 * @since 2.4
3574 */
3575 public static String removeEndIgnoreCase(String str, String remove) {
3576 if (isEmpty(str) || isEmpty(remove)) {
3577 return str;
3578 }
3579 if (endsWithIgnoreCase(str, remove)) {
3580 return str.substring(0, str.length() - remove.length());
3581 }
3582 return str;
3583 }
3584
3585 /**
3586 * <p>Removes all occurrences of a substring from within the source string.</p>
3587 *
3588 * <p>A <code>null</code> source string will return <code>null</code>.
3589 * An empty ("") source string will return the empty string.
3590 * A <code>null</code> remove string will return the source string.
3591 * An empty ("") remove string will return the source string.</p>
3592 *
3593 * <pre>
3594 * StringUtils.remove(null, *) = null
3595 * StringUtils.remove("", *) = ""
3596 * StringUtils.remove(*, null) = *
3597 * StringUtils.remove(*, "") = *
3598 * StringUtils.remove("queued", "ue") = "qd"
3599 * StringUtils.remove("queued", "zz") = "queued"
3600 * </pre>
3601 *
3602 * @param str the source String to search, may be null
3603 * @param remove the String to search for and remove, may be null
3604 * @return the substring with the string removed if found,
3605 * <code>null</code> if null String input
3606 * @since 2.1
3607 */
3608 public static String remove(String str, String remove) {
3609 if (isEmpty(str) || isEmpty(remove)) {
3610 return str;
3611 }
3612 return replace(str, remove, EMPTY, -1);
3613 }
3614
3615 /**
3616 * <p>Removes all occurrences of a character from within the source string.</p>
3617 *
3618 * <p>A <code>null</code> source string will return <code>null</code>.
3619 * An empty ("") source string will return the empty string.</p>
3620 *
3621 * <pre>
3622 * StringUtils.remove(null, *) = null
3623 * StringUtils.remove("", *) = ""
3624 * StringUtils.remove("queued", 'u') = "qeed"
3625 * StringUtils.remove("queued", 'z') = "queued"
3626 * </pre>
3627 *
3628 * @param str the source String to search, may be null
3629 * @param remove the char to search for and remove, may be null
3630 * @return the substring with the char removed if found,
3631 * <code>null</code> if null String input
3632 * @since 2.1
3633 */
3634 public static String remove(String str, char remove) {
3635 if (isEmpty(str) || str.indexOf(remove) == -1) {
3636 return str;
3637 }
3638 char[] chars = str.toCharArray();
3639 int pos = 0;
3640 for (int i = 0; i < chars.length; i++) {
3641 if (chars[i] != remove) {
3642 chars[pos++] = chars[i];
3643 }
3644 }
3645 return new String(chars, 0, pos);
3646 }
3647
3648 // Replacing
3649 //-----------------------------------------------------------------------
3650 /**
3651 * <p>Replaces a String with another String inside a larger String, once.</p>
3652 *
3653 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
3654 *
3655 * <pre>
3656 * StringUtils.replaceOnce(null, *, *) = null
3657 * StringUtils.replaceOnce("", *, *) = ""
3658 * StringUtils.replaceOnce("any", null, *) = "any"
3659 * StringUtils.replaceOnce("any", *, null) = "any"
3660 * StringUtils.replaceOnce("any", "", *) = "any"
3661 * StringUtils.replaceOnce("aba", "a", null) = "aba"
3662 * StringUtils.replaceOnce("aba", "a", "") = "ba"
3663 * StringUtils.replaceOnce("aba", "a", "z") = "zba"
3664 * </pre>
3665 *
3666 * @see #replace(String text, String searchString, String replacement, int max)
3667 * @param text text to search and replace in, may be null
3668 * @param searchString the String to search for, may be null
3669 * @param replacement the String to replace with, may be null
3670 * @return the text with any replacements processed,
3671 * <code>null</code> if null String input
3672 */
3673 public static String replaceOnce(String text, String searchString, String replacement) {
3674 return replace(text, searchString, replacement, 1);
3675 }
3676
3677 /**
3678 * <p>Replaces all occurrences of a String within another String.</p>
3679 *
3680 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
3681 *
3682 * <pre>
3683 * StringUtils.replace(null, *, *) = null
3684 * StringUtils.replace("", *, *) = ""
3685 * StringUtils.replace("any", null, *) = "any"
3686 * StringUtils.replace("any", *, null) = "any"
3687 * StringUtils.replace("any", "", *) = "any"
3688 * StringUtils.replace("aba", "a", null) = "aba"
3689 * StringUtils.replace("aba", "a", "") = "b"
3690 * StringUtils.replace("aba", "a", "z") = "zbz"
3691 * </pre>
3692 *
3693 * @see #replace(String text, String searchString, String replacement, int max)
3694 * @param text text to search and replace in, may be null
3695 * @param searchString the String to search for, may be null
3696 * @param replacement the String to replace it with, may be null
3697 * @return the text with any replacements processed,
3698 * <code>null</code> if null String input
3699 */
3700 public static String replace(String text, String searchString, String replacement) {
3701 return replace(text, searchString, replacement, -1);
3702 }
3703
3704 /**
3705 * <p>Replaces a String with another String inside a larger String,
3706 * for the first <code>max</code> values of the search String.</p>
3707 *
3708 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
3709 *
3710 * <pre>
3711 * StringUtils.replace(null, *, *, *) = null
3712 * StringUtils.replace("", *, *, *) = ""
3713 * StringUtils.replace("any", null, *, *) = "any"
3714 * StringUtils.replace("any", *, null, *) = "any"
3715 * StringUtils.replace("any", "", *, *) = "any"
3716 * StringUtils.replace("any", *, *, 0) = "any"
3717 * StringUtils.replace("abaa", "a", null, -1) = "abaa"
3718 * StringUtils.replace("abaa", "a", "", -1) = "b"
3719 * StringUtils.replace("abaa", "a", "z", 0) = "abaa"
3720 * StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
3721 * StringUtils.replace("abaa", "a", "z", 2) = "zbza"
3722 * StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
3723 * </pre>
3724 *
3725 * @param text text to search and replace in, may be null
3726 * @param searchString the String to search for, may be null
3727 * @param replacement the String to replace it with, may be null
3728 * @param max maximum number of values to replace, or <code>-1</code> if no maximum
3729 * @return the text with any replacements processed,
3730 * <code>null</code> if null String input
3731 */
3732 public static String replace(String text, String searchString, String replacement, int max) {
3733 if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
3734 return text;
3735 }
3736 int start = 0;
3737 int end = text.indexOf(searchString, start);
3738 if (end == -1) {
3739 return text;
3740 }
3741 int replLength = searchString.length();
3742 int increase = replacement.length() - replLength;
3743 increase = (increase < 0 ? 0 : increase);
3744 increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
3745 StringBuffer buf = new StringBuffer(text.length() + increase);
3746 while (end != -1) {
3747 buf.append(text.substring(start, end)).append(replacement);
3748 start = end + replLength;
3749 if (--max == 0) {
3750 break;
3751 }
3752 end = text.indexOf(searchString, start);
3753 }
3754 buf.append(text.substring(start));
3755 return buf.toString();
3756 }
3757
3758 /**
3759 * <p>
3760 * Replaces all occurrences of Strings within another String.
3761 * </p>
3762 *
3763 * <p>
3764 * A <code>null</code> reference passed to this method is a no-op, or if
3765 * any "search string" or "string to replace" is null, that replace will be
3766 * ignored. This will not repeat. For repeating replaces, call the
3767 * overloaded method.
3768 * </p>
3769 *
3770 * <pre>
3771 * StringUtils.replaceEach(null, *, *) = null
3772 * StringUtils.replaceEach("", *, *) = ""
3773 * StringUtils.replaceEach("aba", null, null) = "aba"
3774 * StringUtils.replaceEach("aba", new String[0], null) = "aba"
3775 * StringUtils.replaceEach("aba", null, new String[0]) = "aba"
3776 * StringUtils.replaceEach("aba", new String[]{"a"}, null) = "aba"
3777 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}) = "b"
3778 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}) = "aba"
3779 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}) = "wcte"
3780 * (example of how it does not repeat)
3781 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}) = "dcte"
3782 * </pre>
3783 *
3784 * @param text
3785 * text to search and replace in, no-op if null
3786 * @param searchList
3787 * the Strings to search for, no-op if null
3788 * @param replacementList
3789 * the Strings to replace them with, no-op if null
3790 * @return the text with any replacements processed, <code>null</code> if
3791 * null String input
3792 * @throws IndexOutOfBoundsException
3793 * if the lengths of the arrays are not the same (null is ok,
3794 * and/or size 0)
3795 * @since 2.4
3796 */
3797 public static String replaceEach(String text, String[] searchList, String[] replacementList) {
3798 return replaceEach(text, searchList, replacementList, false, 0);
3799 }
3800
3801 /**
3802 * <p>
3803 * Replaces all occurrences of Strings within another String.
3804 * </p>
3805 *
3806 * <p>
3807 * A <code>null</code> reference passed to this method is a no-op, or if
3808 * any "search string" or "string to replace" is null, that replace will be
3809 * ignored. This will not repeat. For repeating replaces, call the
3810 * overloaded method.
3811 * </p>
3812 *
3813 * <pre>
3814 * StringUtils.replaceEach(null, *, *, *) = null
3815 * StringUtils.replaceEach("", *, *, *) = ""
3816 * StringUtils.replaceEach("aba", null, null, *) = "aba"
3817 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
3818 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
3819 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
3820 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
3821 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
3822 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
3823 * (example of how it repeats)
3824 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
3825 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
3826 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, true) = IllegalArgumentException
3827 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, false) = "dcabe"
3828 * </pre>
3829 *
3830 * @param text
3831 * text to search and replace in, no-op if null
3832 * @param searchList
3833 * the Strings to search for, no-op if null
3834 * @param replacementList
3835 * the Strings to replace them with, no-op if null
3836 * @return the text with any replacements processed, <code>null</code> if
3837 * null String input
3838 * @throws IllegalArgumentException
3839 * if the search is repeating and there is an endless loop due
3840 * to outputs of one being inputs to another
3841 * @throws IndexOutOfBoundsException
3842 * if the lengths of the arrays are not the same (null is ok,
3843 * and/or size 0)
3844 * @since 2.4
3845 */
3846 public static String replaceEachRepeatedly(String text, String[] searchList, String[] replacementList) {
3847 // timeToLive should be 0 if not used or nothing to replace, else it's
3848 // the length of the replace array
3849 int timeToLive = searchList == null ? 0 : searchList.length;
3850 return replaceEach(text, searchList, replacementList, true, timeToLive);
3851 }
3852
3853 /**
3854 * <p>
3855 * Replaces all occurrences of Strings within another String.
3856 * </p>
3857 *
3858 * <p>
3859 * A <code>null</code> reference passed to this method is a no-op, or if
3860 * any "search string" or "string to replace" is null, that replace will be
3861 * ignored.
3862 * </p>
3863 *
3864 * <pre>
3865 * StringUtils.replaceEach(null, *, *, *) = null
3866 * StringUtils.replaceEach("", *, *, *) = ""
3867 * StringUtils.replaceEach("aba", null, null, *) = "aba"
3868 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
3869 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
3870 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
3871 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
3872 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
3873 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
3874 * (example of how it repeats)
3875 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
3876 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
3877 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, *) = IllegalArgumentException
3878 * </pre>
3879 *
3880 * @param text
3881 * text to search and replace in, no-op if null
3882 * @param searchList
3883 * the Strings to search for, no-op if null
3884 * @param replacementList
3885 * the Strings to replace them with, no-op if null
3886 * @param repeat if true, then replace repeatedly
3887 * until there are no more possible replacements or timeToLive < 0
3888 * @param timeToLive
3889 * if less than 0 then there is a circular reference and endless
3890 * loop
3891 * @return the text with any replacements processed, <code>null</code> if
3892 * null String input
3893 * @throws IllegalArgumentException
3894 * if the search is repeating and there is an endless loop due
3895 * to outputs of one being inputs to another
3896 * @throws IndexOutOfBoundsException
3897 * if the lengths of the arrays are not the same (null is ok,
3898 * and/or size 0)
3899 * @since 2.4
3900 */
3901 private static String replaceEach(String text, String[] searchList, String[] replacementList,
3902 boolean repeat, int timeToLive)
3903 {
3904
3905 // mchyzer Performance note: This creates very few new objects (one major goal)
3906 // let me know if there are performance requests, we can create a harness to measure
3907
3908 if (text == null || text.length() == 0 || searchList == null ||
3909 searchList.length == 0 || replacementList == null || replacementList.length == 0)
3910 {
3911 return text;
3912 }
3913
3914 // if recursing, this shouldnt be less than 0
3915 if (timeToLive < 0) {
3916 throw new IllegalStateException("TimeToLive of " + timeToLive + " is less than 0: " + text);
3917 }
3918
3919 int searchLength = searchList.length;
3920 int replacementLength = replacementList.length;
3921
3922 // make sure lengths are ok, these need to be equal
3923 if (searchLength != replacementLength) {
3924 throw new IllegalArgumentException("Search and Replace array lengths don't match: "
3925 + searchLength
3926 + " vs "
3927 + replacementLength);
3928 }
3929
3930 // keep track of which still have matches
3931 boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
3932
3933 // index on index that the match was found
3934 int textIndex = -1;
3935 int replaceIndex = -1;
3936 int tempIndex = -1;
3937
3938 // index of replace array that will replace the search string found
3939 // NOTE: logic duplicated below START
3940 for (int i = 0; i < searchLength; i++) {
3941 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
3942 searchList[i].length() == 0 || replacementList[i] == null)
3943 {
3944 continue;
3945 }
3946 tempIndex = text.indexOf(searchList[i]);
3947
3948 // see if we need to keep searching for this
3949 if (tempIndex == -1) {
3950 noMoreMatchesForReplIndex[i] = true;
3951 } else {
3952 if (textIndex == -1 || tempIndex < textIndex) {
3953 textIndex = tempIndex;
3954 replaceIndex = i;
3955 }
3956 }
3957 }
3958 // NOTE: logic mostly below END
3959
3960 // no search strings found, we are done
3961 if (textIndex == -1) {
3962 return text;
3963 }
3964
3965 int start = 0;
3966
3967 // get a good guess on the size of the result buffer so it doesnt have to double if it goes over a bit
3968 int increase = 0;
3969
3970 // count the replacement text elements that are larger than their corresponding text being replaced
3971 for (int i = 0; i < searchList.length; i++) {
3972 if (searchList[i] == null || replacementList[i] == null) {
3973 continue;
3974 }
3975 int greater = replacementList[i].length() - searchList[i].length();
3976 if (greater > 0) {
3977 increase += 3 * greater; // assume 3 matches
3978 }
3979 }
3980 // have upper-bound at 20% increase, then let Java take over
3981 increase = Math.min(increase, text.length() / 5);
3982
3983 StringBuffer buf = new StringBuffer(text.length() + increase);
3984
3985 while (textIndex != -1) {
3986
3987 for (int i = start; i < textIndex; i++) {
3988 buf.append(text.charAt(i));
3989 }
3990 buf.append(replacementList[replaceIndex]);
3991
3992 start = textIndex + searchList[replaceIndex].length();
3993
3994 textIndex = -1;
3995 replaceIndex = -1;
3996 tempIndex = -1;
3997 // find the next earliest match
3998 // NOTE: logic mostly duplicated above START
3999 for (int i = 0; i < searchLength; i++) {
4000 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
4001 searchList[i].length() == 0 || replacementList[i] == null)
4002 {
4003 continue;
4004 }
4005 tempIndex = text.indexOf(searchList[i], start);
4006
4007 // see if we need to keep searching for this
4008 if (tempIndex == -1) {
4009 noMoreMatchesForReplIndex[i] = true;
4010 } else {
4011 if (textIndex == -1 || tempIndex < textIndex) {
4012 textIndex = tempIndex;
4013 replaceIndex = i;
4014 }
4015 }
4016 }
4017 // NOTE: logic duplicated above END
4018
4019 }
4020 int textLength = text.length();
4021 for (int i = start; i < textLength; i++) {
4022 buf.append(text.charAt(i));
4023 }
4024 String result = buf.toString();
4025 if (!repeat) {
4026 return result;
4027 }
4028
4029 return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
4030 }
4031
4032 // Replace, character based
4033 //-----------------------------------------------------------------------
4034 /**
4035 * <p>Replaces all occurrences of a character in a String with another.
4036 * This is a null-safe version of {@link String#replace(char, char)}.</p>
4037 *
4038 * <p>A <code>null</code> string input returns <code>null</code>.
4039 * An empty ("") string input returns an empty string.</p>
4040 *
4041 * <pre>
4042 * StringUtils.replaceChars(null, *, *) = null
4043 * StringUtils.replaceChars("", *, *) = ""
4044 * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
4045 * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
4046 * </pre>
4047 *
4048 * @param str String to replace characters in, may be null
4049 * @param searchChar the character to search for, may be null
4050 * @param replaceChar the character to replace, may be null
4051 * @return modified String, <code>null</code> if null string input
4052 * @since 2.0
4053 */
4054 public static String replaceChars(String str, char searchChar, char replaceChar) {
4055 if (str == null) {
4056 return null;
4057 }
4058 return str.replace(searchChar, replaceChar);
4059 }
4060
4061 /**
4062 * <p>Replaces multiple characters in a String in one go.
4063 * This method can also be used to delete characters.</p>
4064 *
4065 * <p>For example:<br />
4066 * <code>replaceChars("hello", "ho", "jy") = jelly</code>.</p>
4067 *
4068 * <p>A <code>null</code> string input returns <code>null</code>.
4069 * An empty ("") string input returns an empty string.
4070 * A null or empty set of search characters returns the input string.</p>
4071 *
4072 * <p>The length of the search characters should normally equal the length
4073 * of the replace characters.
4074 * If the search characters is longer, then the extra search characters
4075 * are deleted.
4076 * If the search characters is shorter, then the extra replace characters
4077 * are ignored.</p>
4078 *
4079 * <pre>
4080 * StringUtils.replaceChars(null, *, *) = null
4081 * StringUtils.replaceChars("", *, *) = ""
4082 * StringUtils.replaceChars("abc", null, *) = "abc"
4083 * StringUtils.replaceChars("abc", "", *) = "abc"
4084 * StringUtils.replaceChars("abc", "b", null) = "ac"
4085 * StringUtils.replaceChars("abc", "b", "") = "ac"
4086 * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya"
4087 * StringUtils.replaceChars("abcba", "bc", "y") = "ayya"
4088 * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
4089 * </pre>
4090 *
4091 * @param str String to replace characters in, may be null
4092 * @param searchChars a set of characters to search for, may be null
4093 * @param replaceChars a set of characters to replace, may be null
4094 * @return modified String, <code>null</code> if null string input
4095 * @since 2.0
4096 */
4097 public static String replaceChars(String str, String searchChars, String replaceChars) {
4098 if (isEmpty(str) || isEmpty(searchChars)) {
4099 return str;
4100 }
4101 if (replaceChars == null) {
4102 replaceChars = EMPTY;
4103 }
4104 boolean modified = false;
4105 int replaceCharsLength = replaceChars.length();
4106 int strLength = str.length();
4107 StringBuffer buf = new StringBuffer(strLength);
4108 for (int i = 0; i < strLength; i++) {
4109 char ch = str.charAt(i);
4110 int index = searchChars.indexOf(ch);
4111 if (index >= 0) {
4112 modified = true;
4113 if (index < replaceCharsLength) {
4114 buf.append(replaceChars.charAt(index));
4115 }
4116 } else {
4117 buf.append(ch);
4118 }
4119 }
4120 if (modified) {
4121 return buf.toString();
4122 }
4123 return str;
4124 }
4125
4126 // Overlay
4127 //-----------------------------------------------------------------------
4128 /**
4129 * <p>Overlays part of a String with another String.</p>
4130 *
4131 * <pre>
4132 * StringUtils.overlayString(null, *, *, *) = NullPointerException
4133 * StringUtils.overlayString(*, null, *, *) = NullPointerException
4134 * StringUtils.overlayString("", "abc", 0, 0) = "abc"
4135 * StringUtils.overlayString("abcdef", null, 2, 4) = "abef"
4136 * StringUtils.overlayString("abcdef", "", 2, 4) = "abef"
4137 * StringUtils.overlayString("abcdef", "zzzz", 2, 4) = "abzzzzef"
4138 * StringUtils.overlayString("abcdef", "zzzz", 4, 2) = "abcdzzzzcdef"
4139 * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsException
4140 * StringUtils.overlayString("abcdef", "zzzz", 2, 8) = IndexOutOfBoundsException
4141 * </pre>
4142 *
4143 * @param text the String to do overlaying in, may be null
4144 * @param overlay the String to overlay, may be null
4145 * @param start the position to start overlaying at, must be valid
4146 * @param end the position to stop overlaying before, must be valid
4147 * @return overlayed String, <code>null</code> if null String input
4148 * @throws NullPointerException if text or overlay is null
4149 * @throws IndexOutOfBoundsException if either position is invalid
4150 * @deprecated Use better named {@link #overlay(String, String, int, int)} instead.
4151 * Method will be removed in Commons Lang 3.0.
4152 */
4153 public static String overlayString(String text, String overlay, int start, int end) {
4154 return new StringBuffer(start + overlay.length() + text.length() - end + 1)
4155 .append(text.substring(0, start))
4156 .append(overlay)
4157 .append(text.substring(end))
4158 .toString();
4159 }
4160
4161 /**
4162 * <p>Overlays part of a String with another String.</p>
4163 *
4164 * <p>A <code>null</code> string input returns <code>null</code>.
4165 * A negative index is treated as zero.
4166 * An index greater than the string length is treated as the string length.
4167 * The start index is always the smaller of the two indices.</p>
4168 *
4169 * <pre>
4170 * StringUtils.overlay(null, *, *, *) = null
4171 * StringUtils.overlay("", "abc", 0, 0) = "abc"
4172 * StringUtils.overlay("abcdef", null, 2, 4) = "abef"
4173 * StringUtils.overlay("abcdef", "", 2, 4) = "abef"
4174 * StringUtils.overlay("abcdef", "", 4, 2) = "abef"
4175 * StringUtils.overlay("abcdef", "zzzz", 2, 4) = "abzzzzef"
4176 * StringUtils.overlay("abcdef", "zzzz", 4, 2) = "abzzzzef"
4177 * StringUtils.overlay("abcdef", "zzzz", -1, 4) = "zzzzef"
4178 * StringUtils.overlay("abcdef", "zzzz", 2, 8) = "abzzzz"
4179 * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
4180 * StringUtils.overlay("abcdef", "zzzz", 8, 10) = "abcdefzzzz"
4181 * </pre>
4182 *
4183 * @param str the String to do overlaying in, may be null
4184 * @param overlay the String to overlay, may be null
4185 * @param start the position to start overlaying at
4186 * @param end the position to stop overlaying before
4187 * @return overlayed String, <code>null</code> if null String input
4188 * @since 2.0
4189 */
4190 public static String overlay(String str, String overlay, int start, int end) {
4191 if (str == null) {
4192 return null;
4193 }
4194 if (overlay == null) {
4195 overlay = EMPTY;
4196 }
4197 int len = str.length();
4198 if (start < 0) {
4199 start = 0;
4200 }
4201 if (start > len) {
4202 start = len;
4203 }
4204 if (end < 0) {
4205 end = 0;
4206 }
4207 if (end > len) {
4208 end = len;
4209 }
4210 if (start > end) {
4211 int temp = start;
4212 start = end;
4213 end = temp;
4214 }
4215 return new StringBuffer(len + start - end + overlay.length() + 1)
4216 .append(str.substring(0, start))
4217 .append(overlay)
4218 .append(str.substring(end))
4219 .toString();
4220 }
4221
4222 // Chomping
4223 //-----------------------------------------------------------------------
4224 /**
4225 * <p>Removes one newline from end of a String if it's there,
4226 * otherwise leave it alone. A newline is "<code>\n</code>",
4227 * "<code>\r</code>", or "<code>\r\n</code>".</p>
4228 *
4229 * <p>NOTE: This method changed in 2.0.
4230 * It now more closely matches Perl chomp.</p>
4231 *
4232 * <pre>
4233 * StringUtils.chomp(null) = null
4234 * StringUtils.chomp("") = ""
4235 * StringUtils.chomp("abc \r") = "abc "
4236 * StringUtils.chomp("abc\n") = "abc"
4237 * StringUtils.chomp("abc\r\n") = "abc"
4238 * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
4239 * StringUtils.chomp("abc\n\r") = "abc\n"
4240 * StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
4241 * StringUtils.chomp("\r") = ""
4242 * StringUtils.chomp("\n") = ""
4243 * StringUtils.chomp("\r\n") = ""
4244 * </pre>
4245 *
4246 * @param str the String to chomp a newline from, may be null
4247 * @return String without newline, <code>null</code> if null String input
4248 */
4249 public static String chomp(String str) {
4250 if (isEmpty(str)) {
4251 return str;
4252 }
4253
4254 if (str.length() == 1) {
4255 char ch = str.charAt(0);
4256 if (ch == CharUtils.CR || ch == CharUtils.LF) {
4257 return EMPTY;
4258 }
4259 return str;
4260 }
4261
4262 int lastIdx = str.length() - 1;
4263 char last = str.charAt(lastIdx);
4264
4265 if (last == CharUtils.LF) {
4266 if (str.charAt(lastIdx - 1) == CharUtils.CR) {
4267 lastIdx--;
4268 }
4269 } else if (last != CharUtils.CR) {
4270 lastIdx++;
4271 }
4272 return str.substring(0, lastIdx);
4273 }
4274
4275 /**
4276 * <p>Removes <code>separator</code> from the end of
4277 * <code>str</code> if it's there, otherwise leave it alone.</p>
4278 *
4279 * <p>NOTE: This method changed in version 2.0.
4280 * It now more closely matches Perl chomp.
4281 * For the previous behavior, use {@link #substringBeforeLast(String, String)}.
4282 * This method uses {@link String#endsWith(String)}.</p>
4283 *
4284 * <pre>
4285 * StringUtils.chomp(null, *) = null
4286 * StringUtils.chomp("", *) = ""
4287 * StringUtils.chomp("foobar", "bar") = "foo"
4288 * StringUtils.chomp("foobar", "baz") = "foobar"
4289 * StringUtils.chomp("foo", "foo") = ""
4290 * StringUtils.chomp("foo ", "foo") = "foo "
4291 * StringUtils.chomp(" foo", "foo") = " "
4292 * StringUtils.chomp("foo", "foooo") = "foo"
4293 * StringUtils.chomp("foo", "") = "foo"
4294 * StringUtils.chomp("foo", null) = "foo"
4295 * </pre>
4296 *
4297 * @param str the String to chomp from, may be null
4298 * @param separator separator String, may be null
4299 * @return String without trailing separator, <code>null</code> if null String input
4300 */
4301 public static String chomp(String str, String separator) {
4302 if (isEmpty(str) || separator == null) {
4303 return str;
4304 }
4305 if (str.endsWith(separator)) {
4306 return str.substring(0, str.length() - separator.length());
4307 }
4308 return str;
4309 }
4310
4311 /**
4312 * <p>Remove any "\n" if and only if it is at the end
4313 * of the supplied String.</p>
4314 *
4315 * @param str the String to chomp from, must not be null
4316 * @return String without chomped ending
4317 * @throws NullPointerException if str is <code>null</code>
4318 * @deprecated Use {@link #chomp(String)} instead.
4319 * Method will be removed in Commons Lang 3.0.
4320 */
4321 public static String chompLast(String str) {
4322 return chompLast(str, "\n");
4323 }
4324
4325 /**
4326 * <p>Remove a value if and only if the String ends with that value.</p>
4327 *
4328 * @param str the String to chomp from, must not be null
4329 * @param sep the String to chomp, must not be null
4330 * @return String without chomped ending
4331 * @throws NullPointerException if str or sep is <code>null</code>
4332 * @deprecated Use {@link #chomp(String,String)} instead.
4333 * Method will be removed in Commons Lang 3.0.
4334 */
4335 public static String chompLast(String str, String sep) {
4336 if (str.length() == 0) {
4337 return str;
4338 }
4339 String sub = str.substring(str.length() - sep.length());
4340 if (sep.equals(sub)) {
4341 return str.substring(0, str.length() - sep.length());
4342 }
4343 return str;
4344 }
4345
4346 /**
4347 * <p>Remove everything and return the last value of a supplied String, and
4348 * everything after it from a String.</p>
4349 *
4350 * @param str the String to chomp from, must not be null
4351 * @param sep the String to chomp, must not be null
4352 * @return String chomped
4353 * @throws NullPointerException if str or sep is <code>null</code>
4354 * @deprecated Use {@link #substringAfterLast(String, String)} instead
4355 * (although this doesn't include the separator)
4356 * Method will be removed in Commons Lang 3.0.
4357 */
4358 public static String getChomp(String str, String sep) {
4359 int idx = str.lastIndexOf(sep);
4360 if (idx == str.length() - sep.length()) {
4361 return sep;
4362 } else if (idx != -1) {
4363 return str.substring(idx);
4364 } else {
4365 return EMPTY;
4366 }
4367 }
4368
4369 /**
4370 * <p>Remove the first value of a supplied String, and everything before it
4371 * from a String.</p>
4372 *
4373 * @param str the String to chomp from, must not be null
4374 * @param sep the String to chomp, must not be null
4375 * @return String without chomped beginning
4376 * @throws NullPointerException if str or sep is <code>null</code>
4377 * @deprecated Use {@link #substringAfter(String,String)} instead.
4378 * Method will be removed in Commons Lang 3.0.
4379 */
4380 public static String prechomp(String str, String sep) {
4381 int idx = str.indexOf(sep);
4382 if (idx == -1) {
4383 return str;
4384 }
4385 return str.substring(idx + sep.length());
4386 }
4387
4388 /**
4389 * <p>Remove and return everything before the first value of a
4390 * supplied String from another String.</p>
4391 *
4392 * @param str the String to chomp from, must not be null
4393 * @param sep the String to chomp, must not be null
4394 * @return String prechomped
4395 * @throws NullPointerException if str or sep is <code>null</code>
4396 * @deprecated Use {@link #substringBefore(String,String)} instead
4397 * (although this doesn't include the separator).
4398 * Method will be removed in Commons Lang 3.0.
4399 */
4400 public static String getPrechomp(String str, String sep) {
4401 int idx = str.indexOf(sep);
4402 if (idx == -1) {
4403 return EMPTY;
4404 }
4405 return str.substring(0, idx + sep.length());
4406 }
4407
4408 // Chopping
4409 //-----------------------------------------------------------------------
4410 /**
4411 * <p>Remove the last character from a String.</p>
4412 *
4413 * <p>If the String ends in <code>\r\n</code>, then remove both
4414 * of them.</p>
4415 *
4416 * <pre>
4417 * StringUtils.chop(null) = null
4418 * StringUtils.chop("") = ""
4419 * StringUtils.chop("abc \r") = "abc "
4420 * StringUtils.chop("abc\n") = "abc"
4421 * StringUtils.chop("abc\r\n") = "abc"
4422 * StringUtils.chop("abc") = "ab"
4423 * StringUtils.chop("abc\nabc") = "abc\nab"
4424 * StringUtils.chop("a") = ""
4425 * StringUtils.chop("\r") = ""
4426 * StringUtils.chop("\n") = ""
4427 * StringUtils.chop("\r\n") = ""
4428 * </pre>
4429 *
4430 * @param str the String to chop last character from, may be null
4431 * @return String without last character, <code>null</code> if null String input
4432 */
4433 public static String chop(String str) {
4434 if (str == null) {
4435 return null;
4436 }
4437 int strLen = str.length();
4438 if (strLen < 2) {
4439 return EMPTY;
4440 }
4441 int lastIdx = strLen - 1;
4442 String ret = str.substring(0, lastIdx);
4443 char last = str.charAt(lastIdx);
4444 if (last == CharUtils.LF) {
4445 if (ret.charAt(lastIdx - 1) == CharUtils.CR) {
4446 return ret.substring(0, lastIdx - 1);
4447 }
4448 }
4449 return ret;
4450 }
4451
4452 /**
4453 * <p>Removes <code>\n</code> from end of a String if it's there.
4454 * If a <code>\r</code> precedes it, then remove that too.</p>
4455 *
4456 * @param str the String to chop a newline from, must not be null
4457 * @return String without newline
4458 * @throws NullPointerException if str is <code>null</code>
4459 * @deprecated Use {@link #chomp(String)} instead.
4460 * Method will be removed in Commons Lang 3.0.
4461 */
4462 public static String chopNewline(String str) {
4463 int lastIdx = str.length() - 1;
4464 if (lastIdx <= 0) {
4465 return EMPTY;
4466 }
4467 char last = str.charAt(lastIdx);
4468 if (last == CharUtils.LF) {
4469 if (str.charAt(lastIdx - 1) == CharUtils.CR) {
4470 lastIdx--;
4471 }
4472 } else {
4473 lastIdx++;
4474 }
4475 return str.substring(0, lastIdx);
4476 }
4477
4478 // Conversion
4479 //-----------------------------------------------------------------------
4480 /**
4481 * <p>Escapes any values it finds into their String form.</p>
4482 *
4483 * <p>So a tab becomes the characters <code>'\\'</code> and
4484 * <code>'t'</code>.</p>
4485 *
4486 * <p>As of Lang 2.0, this calls {@link StringEscapeUtils#escapeJava(String)}
4487 * behind the scenes.
4488 * </p>
4489 * @see StringEscapeUtils#escapeJava(java.lang.String)
4490 * @param str String to escape values in
4491 * @return String with escaped values
4492 * @throws NullPointerException if str is <code>null</code>
4493 * @deprecated Use {@link StringEscapeUtils#escapeJava(String)}
4494 * This method will be removed in Commons Lang 3.0
4495 */
4496 public static String escape(String str) {
4497 return StringEscapeUtils.escapeJava(str);
4498 }
4499
4500 // Padding
4501 //-----------------------------------------------------------------------
4502 /**
4503 * <p>Repeat a String <code>repeat</code> times to form a
4504 * new String.</p>
4505 *
4506 * <pre>
4507 * StringUtils.repeat(null, 2) = null
4508 * StringUtils.repeat("", 0) = ""
4509 * StringUtils.repeat("", 2) = ""
4510 * StringUtils.repeat("a", 3) = "aaa"
4511 * StringUtils.repeat("ab", 2) = "abab"
4512 * StringUtils.repeat("a", -2) = ""
4513 * </pre>
4514 *
4515 * @param str the String to repeat, may be null
4516 * @param repeat number of times to repeat str, negative treated as zero
4517 * @return a new String consisting of the original String repeated,
4518 * <code>null</code> if null String input
4519 * @since 2.5
4520 */
4521 public static String repeat(String str, int repeat) {
4522 // Performance tuned for 2.0 (JDK1.4)
4523
4524 if (str == null) {
4525 return null;
4526 }
4527 if (repeat <= 0) {
4528 return EMPTY;
4529 }
4530 int inputLength = str.length();
4531 if (repeat == 1 || inputLength == 0) {
4532 return str;
4533 }
4534 if (inputLength == 1 && repeat <= PAD_LIMIT) {
4535 return padding(repeat, str.charAt(0));
4536 }
4537
4538 int outputLength = inputLength * repeat;
4539 switch (inputLength) {
4540 case 1 :
4541 char ch = str.charAt(0);
4542 char[] output1 = new char[outputLength];
4543 for (int i = repeat - 1; i >= 0; i--) {
4544 output1[i] = ch;
4545 }
4546 return new String(output1);
4547 case 2 :
4548 char ch0 = str.charAt(0);
4549 char ch1 = str.charAt(1);
4550 char[] output2 = new char[outputLength];
4551 for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
4552 output2[i] = ch0;
4553 output2[i + 1] = ch1;
4554 }
4555 return new String(output2);
4556 default :
4557 StringBuffer buf = new StringBuffer(outputLength);
4558 for (int i = 0; i < repeat; i++) {
4559 buf.append(str);
4560 }
4561 return buf.toString();
4562 }
4563 }
4564
4565 /**
4566 * <p>Repeat a String <code>repeat</code> times to form a
4567 * new String, with a String separator injected each time. </p>
4568 *
4569 * <pre>
4570 * StringUtils.repeat(null, null, 2) = null
4571 * StringUtils.repeat(null, "x", 2) = null
4572 * StringUtils.repeat("", null, 0) = ""
4573 * StringUtils.repeat("", "", 2) = ""
4574 * StringUtils.repeat("", "x", 3) = "xxx"
4575 * StringUtils.repeat("?", ", ", 3) = "?, ?, ?"
4576 * </pre>
4577 *
4578 * @param str the String to repeat, may be null
4579 * @param separator the String to inject, may be null
4580 * @param repeat number of times to repeat str, negative treated as zero
4581 * @return a new String consisting of the original String repeated,
4582 * <code>null</code> if null String input
4583 */
4584 public static String repeat(String str, String separator, int repeat) {
4585 if(str == null || separator == null) {
4586 return repeat(str, repeat);
4587 } else {
4588 // given that repeat(String, int) is quite optimized, better to rely on it than try and splice this into it
4589 String result = repeat(str + separator, repeat);
4590 return removeEnd(result, separator);
4591 }
4592 }
4593
4594 /**
4595 * <p>Returns padding using the specified delimiter repeated
4596 * to a given length.</p>
4597 *
4598 * <pre>
4599 * StringUtils.padding(0, 'e') = ""
4600 * StringUtils.padding(3, 'e') = "eee"
4601 * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
4602 * </pre>
4603 *
4604 * <p>Note: this method doesn't not support padding with
4605 * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicode Supplementary Characters</a>
4606 * as they require a pair of <code>char</code>s to be represented.
4607 * If you are needing to support full I18N of your applications
4608 * consider using {@link #repeat(String, int)} instead.
4609 * </p>
4610 *
4611 * @param repeat number of times to repeat delim
4612 * @param padChar character to repeat
4613 * @return String with repeated character
4614 * @throws IndexOutOfBoundsException if <code>repeat < 0</code>
4615 * @see #repeat(String, int)
4616 */
4617 private static String padding(int repeat, char padChar) throws IndexOutOfBoundsException {
4618 if (repeat < 0) {
4619 throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + repeat);
4620 }
4621 final char[] buf = new char[repeat];
4622 for (int i = 0; i < buf.length; i++) {
4623 buf[i] = padChar;
4624 }
4625 return new String(buf);
4626 }
4627
4628 /**
4629 * <p>Right pad a String with spaces (' ').</p>
4630 *
4631 * <p>The String is padded to the size of <code>size</code>.</p>
4632 *
4633 * <pre>
4634 * StringUtils.rightPad(null, *) = null
4635 * StringUtils.rightPad("", 3) = " "
4636 * StringUtils.rightPad("bat", 3) = "bat"
4637 * StringUtils.rightPad("bat", 5) = "bat "
4638 * StringUtils.rightPad("bat", 1) = "bat"
4639 * StringUtils.rightPad("bat", -1) = "bat"
4640 * </pre>
4641 *
4642 * @param str the String to pad out, may be null
4643 * @param size the size to pad to
4644 * @return right padded String or original String if no padding is necessary,
4645 * <code>null</code> if null String input
4646 */
4647 public static String rightPad(String str, int size) {
4648 return rightPad(str, size, ' ');
4649 }
4650
4651 /**
4652 * <p>Right pad a String with a specified character.</p>
4653 *
4654 * <p>The String is padded to the size of <code>size</code>.</p>
4655 *
4656 * <pre>
4657 * StringUtils.rightPad(null, *, *) = null
4658 * StringUtils.rightPad("", 3, 'z') = "zzz"
4659 * StringUtils.rightPad("bat", 3, 'z') = "bat"
4660 * StringUtils.rightPad("bat", 5, 'z') = "batzz"
4661 * StringUtils.rightPad("bat", 1, 'z') = "bat"
4662 * StringUtils.rightPad("bat", -1, 'z') = "bat"
4663 * </pre>
4664 *
4665 * @param str the String to pad out, may be null
4666 * @param size the size to pad to
4667 * @param padChar the character to pad with
4668 * @return right padded String or original String if no padding is necessary,
4669 * <code>null</code> if null String input
4670 * @since 2.0
4671 */
4672 public static String rightPad(String str, int size, char padChar) {
4673 if (str == null) {
4674 return null;
4675 }
4676 int pads = size - str.length();
4677 if (pads <= 0) {
4678 return str; // returns original String when possible
4679 }
4680 if (pads > PAD_LIMIT) {
4681 return rightPad(str, size, String.valueOf(padChar));
4682 }
4683 return str.concat(padding(pads, padChar));
4684 }
4685
4686 /**
4687 * <p>Right pad a String with a specified String.</p>
4688 *
4689 * <p>The String is padded to the size of <code>size</code>.</p>
4690 *
4691 * <pre>
4692 * StringUtils.rightPad(null, *, *) = null
4693 * StringUtils.rightPad("", 3, "z") = "zzz"
4694 * StringUtils.rightPad("bat", 3, "yz") = "bat"
4695 * StringUtils.rightPad("bat", 5, "yz") = "batyz"
4696 * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy"
4697 * StringUtils.rightPad("bat", 1, "yz") = "bat"
4698 * StringUtils.rightPad("bat", -1, "yz") = "bat"
4699 * StringUtils.rightPad("bat", 5, null) = "bat "
4700 * StringUtils.rightPad("bat", 5, "") = "bat "
4701 * </pre>
4702 *
4703 * @param str the String to pad out, may be null
4704 * @param size the size to pad to
4705 * @param padStr the String to pad with, null or empty treated as single space
4706 * @return right padded String or original String if no padding is necessary,
4707 * <code>null</code> if null String input
4708 */
4709 public static String rightPad(String str, int size, String padStr) {
4710 if (str == null) {
4711 return null;
4712 }
4713 if (isEmpty(padStr)) {
4714 padStr = " ";
4715 }
4716 int padLen = padStr.length();
4717 int strLen = str.length();
4718 int pads = size - strLen;
4719 if (pads <= 0) {
4720 return str; // returns original String when possible
4721 }
4722 if (padLen == 1 && pads <= PAD_LIMIT) {
4723 return rightPad(str, size, padStr.charAt(0));
4724 }
4725
4726 if (pads == padLen) {
4727 return str.concat(padStr);
4728 } else if (pads < padLen) {
4729 return str.concat(padStr.substring(0, pads));
4730 } else {
4731 char[] padding = new char[pads];
4732 char[] padChars = padStr.toCharArray();
4733 for (int i = 0; i < pads; i++) {
4734 padding[i] = padChars[i % padLen];
4735 }
4736 return str.concat(new String(padding));
4737 }
4738 }
4739
4740 /**
4741 * <p>Left pad a String with spaces (' ').</p>
4742 *
4743 * <p>The String is padded to the size of <code>size</code>.</p>
4744 *
4745 * <pre>
4746 * StringUtils.leftPad(null, *) = null
4747 * StringUtils.leftPad("", 3) = " "
4748 * StringUtils.leftPad("bat", 3) = "bat"
4749 * StringUtils.leftPad("bat", 5) = " bat"
4750 * StringUtils.leftPad("bat", 1) = "bat"
4751 * StringUtils.leftPad("bat", -1) = "bat"
4752 * </pre>
4753 *
4754 * @param str the String to pad out, may be null
4755 * @param size the size to pad to
4756 * @return left padded String or original String if no padding is necessary,
4757 * <code>null</code> if null String input
4758 */
4759 public static String leftPad(String str, int size) {
4760 return leftPad(str, size, ' ');
4761 }
4762
4763 /**
4764 * <p>Left pad a String with a specified character.</p>
4765 *
4766 * <p>Pad to a size of <code>size</code>.</p>
4767 *
4768 * <pre>
4769 * StringUtils.leftPad(null, *, *) = null
4770 * StringUtils.leftPad("", 3, 'z') = "zzz"
4771 * StringUtils.leftPad("bat", 3, 'z') = "bat"
4772 * StringUtils.leftPad("bat", 5, 'z') = "zzbat"
4773 * StringUtils.leftPad("bat", 1, 'z') = "bat"
4774 * StringUtils.leftPad("bat", -1, 'z') = "bat"
4775 * </pre>
4776 *
4777 * @param str the String to pad out, may be null
4778 * @param size the size to pad to
4779 * @param padChar the character to pad with
4780 * @return left padded String or original String if no padding is necessary,
4781 * <code>null</code> if null String input
4782 * @since 2.0
4783 */
4784 public static String leftPad(String str, int size, char padChar) {
4785 if (str == null) {
4786 return null;
4787 }
4788 int pads = size - str.length();
4789 if (pads <= 0) {
4790 return str; // returns original String when possible
4791 }
4792 if (pads > PAD_LIMIT) {
4793 return leftPad(str, size, String.valueOf(padChar));
4794 }
4795 return padding(pads, padChar).concat(str);
4796 }
4797
4798 /**
4799 * <p>Left pad a String with a specified String.</p>
4800 *
4801 * <p>Pad to a size of <code>size</code>.</p>
4802 *
4803 * <pre>
4804 * StringUtils.leftPad(null, *, *) = null
4805 * StringUtils.leftPad("", 3, "z") = "zzz"
4806 * StringUtils.leftPad("bat", 3, "yz") = "bat"
4807 * StringUtils.leftPad("bat", 5, "yz") = "yzbat"
4808 * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
4809 * StringUtils.leftPad("bat", 1, "yz") = "bat"
4810 * StringUtils.leftPad("bat", -1, "yz") = "bat"
4811 * StringUtils.leftPad("bat", 5, null) = " bat"
4812 * StringUtils.leftPad("bat", 5, "") = " bat"
4813 * </pre>
4814 *
4815 * @param str the String to pad out, may be null
4816 * @param size the size to pad to
4817 * @param padStr the String to pad with, null or empty treated as single space
4818 * @return left padded String or original String if no padding is necessary,
4819 * <code>null</code> if null String input
4820 */
4821 public static String leftPad(String str, int size, String padStr) {
4822 if (str == null) {
4823 return null;
4824 }
4825 if (isEmpty(padStr)) {
4826 padStr = " ";
4827 }
4828 int padLen = padStr.length();
4829 int strLen = str.length();
4830 int pads = size - strLen;
4831 if (pads <= 0) {
4832 return str; // returns original String when possible
4833 }
4834 if (padLen == 1 && pads <= PAD_LIMIT) {
4835 return leftPad(str, size, padStr.charAt(0));
4836 }
4837
4838 if (pads == padLen) {
4839 return padStr.concat(str);
4840 } else if (pads < padLen) {
4841 return padStr.substring(0, pads).concat(str);
4842 } else {
4843 char[] padding = new char[pads];
4844 char[] padChars = padStr.toCharArray();
4845 for (int i = 0; i < pads; i++) {
4846 padding[i] = padChars[i % padLen];
4847 }
4848 return new String(padding).concat(str);
4849 }
4850 }
4851
4852 /**
4853 * Gets a String's length or <code>0</code> if the String is <code>null</code>.
4854 *
4855 * @param str
4856 * a String or <code>null</code>
4857 * @return String length or <code>0</code> if the String is <code>null</code>.
4858 * @since 2.4
4859 */
4860 public static int length(String str) {
4861 return str == null ? 0 : str.length();
4862 }
4863
4864 // Centering
4865 //-----------------------------------------------------------------------
4866 /**
4867 * <p>Centers a String in a larger String of size <code>size</code>
4868 * using the space character (' ').<p>
4869 *
4870 * <p>If the size is less than the String length, the String is returned.
4871 * A <code>null</code> String returns <code>null</code>.
4872 * A negative size is treated as zero.</p>
4873 *
4874 * <p>Equivalent to <code>center(str, size, " ")</code>.</p>
4875 *
4876 * <pre>
4877 * StringUtils.center(null, *) = null
4878 * StringUtils.center("", 4) = " "
4879 * StringUtils.center("ab", -1) = "ab"
4880 * StringUtils.center("ab", 4) = " ab "
4881 * StringUtils.center("abcd", 2) = "abcd"
4882 * StringUtils.center("a", 4) = " a "
4883 * </pre>
4884 *
4885 * @param str the String to center, may be null
4886 * @param size the int size of new String, negative treated as zero
4887 * @return centered String, <code>null</code> if null String input
4888 */
4889 public static String center(String str, int size) {
4890 return center(str, size, ' ');
4891 }
4892
4893 /**
4894 * <p>Centers a String in a larger String of size <code>size</code>.
4895 * Uses a supplied character as the value to pad the String with.</p>
4896 *
4897 * <p>If the size is less than the String length, the String is returned.
4898 * A <code>null</code> String returns <code>null</code>.
4899 * A negative size is treated as zero.</p>
4900 *
4901 * <pre>
4902 * StringUtils.center(null, *, *) = null
4903 * StringUtils.center("", 4, ' ') = " "
4904 * StringUtils.center("ab", -1, ' ') = "ab"
4905 * StringUtils.center("ab", 4, ' ') = " ab"
4906 * StringUtils.center("abcd", 2, ' ') = "abcd"
4907 * StringUtils.center("a", 4, ' ') = " a "
4908 * StringUtils.center("a", 4, 'y') = "yayy"
4909 * </pre>
4910 *
4911 * @param str the String to center, may be null
4912 * @param size the int size of new String, negative treated as zero
4913 * @param padChar the character to pad the new String with
4914 * @return centered String, <code>null</code> if null String input
4915 * @since 2.0
4916 */
4917 public static String center(String str, int size, char padChar) {
4918 if (str == null || size <= 0) {
4919 return str;
4920 }
4921 int strLen = str.length();
4922 int pads = size - strLen;
4923 if (pads <= 0) {
4924 return str;
4925 }
4926 str = leftPad(str, strLen + pads / 2, padChar);
4927 str = rightPad(str, size, padChar);
4928 return str;
4929 }
4930
4931 /**
4932 * <p>Centers a String in a larger String of size <code>size</code>.
4933 * Uses a supplied String as the value to pad the String with.</p>
4934 *
4935 * <p>If the size is less than the String length, the String is returned.
4936 * A <code>null</code> String returns <code>null</code>.
4937 * A negative size is treated as zero.</p>
4938 *
4939 * <pre>
4940 * StringUtils.center(null, *, *) = null
4941 * StringUtils.center("", 4, " ") = " "
4942 * StringUtils.center("ab", -1, " ") = "ab"
4943 * StringUtils.center("ab", 4, " ") = " ab"
4944 * StringUtils.center("abcd", 2, " ") = "abcd"
4945 * StringUtils.center("a", 4, " ") = " a "
4946 * StringUtils.center("a", 4, "yz") = "yayz"
4947 * StringUtils.center("abc", 7, null) = " abc "
4948 * StringUtils.center("abc", 7, "") = " abc "
4949 * </pre>
4950 *
4951 * @param str the String to center, may be null
4952 * @param size the int size of new String, negative treated as zero
4953 * @param padStr the String to pad the new String with, must not be null or empty
4954 * @return centered String, <code>null</code> if null String input
4955 * @throws IllegalArgumentException if padStr is <code>null</code> or empty
4956 */
4957 public static String center(String str, int size, String padStr) {
4958 if (str == null || size <= 0) {
4959 return str;
4960 }
4961 if (isEmpty(padStr)) {
4962 padStr = " ";
4963 }
4964 int strLen = str.length();
4965 int pads = size - strLen;
4966 if (pads <= 0) {
4967 return str;
4968 }
4969 str = leftPad(str, strLen + pads / 2, padStr);
4970 str = rightPad(str, size, padStr);
4971 return str;
4972 }
4973
4974 // Case conversion
4975 //-----------------------------------------------------------------------
4976 /**
4977 * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
4978 *
4979 * <p>A <code>null</code> input String returns <code>null</code>.</p>
4980 *
4981 * <pre>
4982 * StringUtils.upperCase(null) = null
4983 * StringUtils.upperCase("") = ""
4984 * StringUtils.upperCase("aBc") = "ABC"
4985 * </pre>
4986 *
4987 * <p><strong>Note:</strong> As described in the documentation for {@link String#toUpperCase()},
4988 * the result of this method is affected by the current locale.
4989 * For platform-independent case transformations, the method {@link #lowerCase(String, Locale)}
4990 * should be used with a specific locale (e.g. {@link Locale#ENGLISH}).</p>
4991 *
4992 * @param str the String to upper case, may be null
4993 * @return the upper cased String, <code>null</code> if null String input
4994 */
4995 public static String upperCase(String str) {
4996 if (str == null) {
4997 return null;
4998 }
4999 return str.toUpperCase();
5000 }
5001
5002 /**
5003 * <p>Converts a String to upper case as per {@link String#toUpperCase(Locale)}.</p>
5004 *
5005 * <p>A <code>null</code> input String returns <code>null</code>.</p>
5006 *
5007 * <pre>
5008 * StringUtils.upperCase(null, Locale.ENGLISH) = null
5009 * StringUtils.upperCase("", Locale.ENGLISH) = ""
5010 * StringUtils.upperCase("aBc", Locale.ENGLISH) = "ABC"
5011 * </pre>
5012 *
5013 * @param str the String to upper case, may be null
5014 * @param locale the locale that defines the case transformation rules, must not be null
5015 * @return the upper cased String, <code>null</code> if null String input
5016 * @since 2.5
5017 */
5018 public static String upperCase(String str, Locale locale) {
5019 if (str == null) {
5020 return null;
5021 }
5022 return str.toUpperCase(locale);
5023 }
5024
5025 /**
5026 * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>
5027 *
5028 * <p>A <code>null</code> input String returns <code>null</code>.</p>
5029 *
5030 * <pre>
5031 * StringUtils.lowerCase(null) = null
5032 * StringUtils.lowerCase("") = ""
5033 * StringUtils.lowerCase("aBc") = "abc"
5034 * </pre>
5035 *
5036 * <p><strong>Note:</strong> As described in the documentation for {@link String#toLowerCase()},
5037 * the result of this method is affected by the current locale.
5038 * For platform-independent case transformations, the method {@link #lowerCase(String, Locale)}
5039 * should be used with a specific locale (e.g. {@link Locale#ENGLISH}).</p>
5040 *
5041 * @param str the String to lower case, may be null
5042 * @return the lower cased String, <code>null</code> if null String input
5043 */
5044 public static String lowerCase(String str) {
5045 if (str == null) {
5046 return null;
5047 }
5048 return str.toLowerCase();
5049 }
5050
5051 /**
5052 * <p>Converts a String to lower case as per {@link String#toLowerCase(Locale)}.</p>
5053 *
5054 * <p>A <code>null</code> input String returns <code>null</code>.</p>
5055 *
5056 * <pre>
5057 * StringUtils.lowerCase(null, Locale.ENGLISH) = null
5058 * StringUtils.lowerCase("", Locale.ENGLISH) = ""
5059 * StringUtils.lowerCase("aBc", Locale.ENGLISH) = "abc"
5060 * </pre>
5061 *
5062 * @param str the String to lower case, may be null
5063 * @param locale the locale that defines the case transformation rules, must not be null
5064 * @return the lower cased String, <code>null</code> if null String input
5065 * @since 2.5
5066 */
5067 public static String lowerCase(String str, Locale locale) {
5068 if (str == null) {
5069 return null;
5070 }
5071 return str.toLowerCase(locale);
5072 }
5073
5074 /**
5075 * <p>Capitalizes a String changing the first letter to title case as
5076 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
5077 *
5078 * <p>For a word based algorithm, see {@link WordUtils#capitalize(String)}.
5079 * A <code>null</code> input String returns <code>null</code>.</p>
5080 *
5081 * <pre>
5082 * StringUtils.capitalize(null) = null
5083 * StringUtils.capitalize("") = ""
5084 * StringUtils.capitalize("cat") = "Cat"
5085 * StringUtils.capitalize("cAt") = "CAt"
5086 * </pre>
5087 *
5088 * @param str the String to capitalize, may be null
5089 * @return the capitalized String, <code>null</code> if null String input
5090 * @see WordUtils#capitalize(String)
5091 * @see #uncapitalize(String)
5092 * @since 2.0
5093 */
5094 public static String capitalize(String str) {
5095 int strLen;
5096 if (str == null || (strLen = str.length()) == 0) {
5097 return str;
5098 }
5099 return new StringBuffer(strLen)
5100 .append(Character.toTitleCase(str.charAt(0)))
5101 .append(str.substring(1))
5102 .toString();
5103 }
5104
5105 /**
5106 * <p>Capitalizes a String changing the first letter to title case as
5107 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
5108 *
5109 * @param str the String to capitalize, may be null
5110 * @return the capitalized String, <code>null</code> if null String input
5111 * @deprecated Use the standardly named {@link #capitalize(String)}.
5112 * Method will be removed in Commons Lang 3.0.
5113 */
5114 public static String capitalise(String str) {
5115 return capitalize(str);
5116 }
5117
5118 /**
5119 * <p>Uncapitalizes a String changing the first letter to title case as
5120 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
5121 *
5122 * <p>For a word based algorithm, see {@link WordUtils#uncapitalize(String)}.
5123 * A <code>null</code> input String returns <code>null</code>.</p>
5124 *
5125 * <pre>
5126 * StringUtils.uncapitalize(null) = null
5127 * StringUtils.uncapitalize("") = ""
5128 * StringUtils.uncapitalize("Cat") = "cat"
5129 * StringUtils.uncapitalize("CAT") = "cAT"
5130 * </pre>
5131 *
5132 * @param str the String to uncapitalize, may be null
5133 * @return the uncapitalized String, <code>null</code> if null String input
5134 * @see WordUtils#uncapitalize(String)
5135 * @see #capitalize(String)
5136 * @since 2.0
5137 */
5138 public static String uncapitalize(String str) {
5139 int strLen;
5140 if (str == null || (strLen = str.length()) == 0) {
5141 return str;
5142 }
5143 return new StringBuffer(strLen)
5144 .append(Character.toLowerCase(str.charAt(0)))
5145 .append(str.substring(1))
5146 .toString();
5147 }
5148
5149 /**
5150 * <p>Uncapitalizes a String changing the first letter to title case as
5151 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
5152 *
5153 * @param str the String to uncapitalize, may be null
5154 * @return the uncapitalized String, <code>null</code> if null String input
5155 * @deprecated Use the standardly named {@link #uncapitalize(String)}.
5156 * Method will be removed in Commons Lang 3.0.
5157 */
5158 public static String uncapitalise(String str) {
5159 return uncapitalize(str);
5160 }
5161
5162 /**
5163 * <p>Swaps the case of a String changing upper and title case to
5164 * lower case, and lower case to upper case.</p>
5165 *
5166 * <ul>
5167 * <li>Upper case character converts to Lower case</li>
5168 * <li>Title case character converts to Lower case</li>
5169 * <li>Lower case character converts to Upper case</li>
5170 * </ul>
5171 *
5172 * <p>For a word based algorithm, see {@link WordUtils#swapCase(String)}.
5173 * A <code>null</code> input String returns <code>null</code>.</p>
5174 *
5175 * <pre>
5176 * StringUtils.swapCase(null) = null
5177 * StringUtils.swapCase("") = ""
5178 * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
5179 * </pre>
5180 *
5181 * <p>NOTE: This method changed in Lang version 2.0.
5182 * It no longer performs a word based algorithm.
5183 * If you only use ASCII, you will notice no change.
5184 * That functionality is available in WordUtils.</p>
5185 *
5186 * @param str the String to swap case, may be null
5187 * @return the changed String, <code>null</code> if null String input
5188 */
5189 public static String swapCase(String str) {
5190 int strLen;
5191 if (str == null || (strLen = str.length()) == 0) {
5192 return str;
5193 }
5194 StringBuffer buffer = new StringBuffer(strLen);
5195
5196 char ch = 0;
5197 for (int i = 0; i < strLen; i++) {
5198 ch = str.charAt(i);
5199 if (Character.isUpperCase(ch)) {
5200 ch = Character.toLowerCase(ch);
5201 } else if (Character.isTitleCase(ch)) {
5202 ch = Character.toLowerCase(ch);
5203 } else if (Character.isLowerCase(ch)) {
5204 ch = Character.toUpperCase(ch);
5205 }
5206 buffer.append(ch);
5207 }
5208 return buffer.toString();
5209 }
5210
5211 /**
5212 * <p>Capitalizes all the whitespace separated words in a String.
5213 * Only the first letter of each word is changed.</p>
5214 *
5215 * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.
5216 * A <code>null</code> input String returns <code>null</code>.</p>
5217 *
5218 * @param str the String to capitalize, may be null
5219 * @return capitalized String, <code>null</code> if null String input
5220 * @deprecated Use the relocated {@link WordUtils#capitalize(String)}.
5221 * Method will be removed in Commons Lang 3.0.
5222 */
5223 public static String capitaliseAllWords(String str) {
5224 return WordUtils.capitalize(str);
5225 }
5226
5227 // Count matches
5228 //-----------------------------------------------------------------------
5229 /**
5230 * <p>Counts how many times the substring appears in the larger String.</p>
5231 *
5232 * <p>A <code>null</code> or empty ("") String input returns <code>0</code>.</p>
5233 *
5234 * <pre>
5235 * StringUtils.countMatches(null, *) = 0
5236 * StringUtils.countMatches("", *) = 0
5237 * StringUtils.countMatches("abba", null) = 0
5238 * StringUtils.countMatches("abba", "") = 0
5239 * StringUtils.countMatches("abba", "a") = 2
5240 * StringUtils.countMatches("abba", "ab") = 1
5241 * StringUtils.countMatches("abba", "xxx") = 0
5242 * </pre>
5243 *
5244 * @param str the String to check, may be null
5245 * @param sub the substring to count, may be null
5246 * @return the number of occurrences, 0 if either String is <code>null</code>
5247 */
5248 public static int countMatches(String str, String sub) {
5249 if (isEmpty(str) || isEmpty(sub)) {
5250 return 0;
5251 }
5252 int count = 0;
5253 int idx = 0;
5254 while ((idx = str.indexOf(sub, idx)) != -1) {
5255 count++;
5256 idx += sub.length();
5257 }
5258 return count;
5259 }
5260
5261 // Character Tests
5262 //-----------------------------------------------------------------------
5263 /**
5264 * <p>Checks if the String contains only unicode letters.</p>
5265 *
5266 * <p><code>null</code> will return <code>false</code>.
5267 * An empty String ("") will return <code>true</code>.</p>
5268 *
5269 * <pre>
5270 * StringUtils.isAlpha(null) = false
5271 * StringUtils.isAlpha("") = true
5272 * StringUtils.isAlpha(" ") = false
5273 * StringUtils.isAlpha("abc") = true
5274 * StringUtils.isAlpha("ab2c") = false
5275 * StringUtils.isAlpha("ab-c") = false
5276 * </pre>
5277 *
5278 * @param str the String to check, may be null
5279 * @return <code>true</code> if only contains letters, and is non-null
5280 */
5281 public static boolean isAlpha(String str) {
5282 if (str == null) {
5283 return false;
5284 }
5285 int sz = str.length();
5286 for (int i = 0; i < sz; i++) {
5287 if (Character.isLetter(str.charAt(i)) == false) {
5288 return false;
5289 }
5290 }
5291 return true;
5292 }
5293
5294 /**
5295 * <p>Checks if the String contains only unicode letters and
5296 * space (' ').</p>
5297 *
5298 * <p><code>null</code> will return <code>false</code>
5299 * An empty String ("") will return <code>true</code>.</p>
5300 *
5301 * <pre>
5302 * StringUtils.isAlphaSpace(null) = false
5303 * StringUtils.isAlphaSpace("") = true
5304 * StringUtils.isAlphaSpace(" ") = true
5305 * StringUtils.isAlphaSpace("abc") = true
5306 * StringUtils.isAlphaSpace("ab c") = true
5307 * StringUtils.isAlphaSpace("ab2c") = false
5308 * StringUtils.isAlphaSpace("ab-c") = false
5309 * </pre>
5310 *
5311 * @param str the String to check, may be null
5312 * @return <code>true</code> if only contains letters and space,
5313 * and is non-null
5314 */
5315 public static boolean isAlphaSpace(String str) {
5316 if (str == null) {
5317 return false;
5318 }
5319 int sz = str.length();
5320 for (int i = 0; i < sz; i++) {
5321 if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
5322 return false;
5323 }
5324 }
5325 return true;
5326 }
5327
5328 /**
5329 * <p>Checks if the String contains only unicode letters or digits.</p>
5330 *
5331 * <p><code>null</code> will return <code>false</code>.
5332 * An empty String ("") will return <code>true</code>.</p>
5333 *
5334 * <pre>
5335 * StringUtils.isAlphanumeric(null) = false
5336 * StringUtils.isAlphanumeric("") = true
5337 * StringUtils.isAlphanumeric(" ") = false
5338 * StringUtils.isAlphanumeric("abc") = true
5339 * StringUtils.isAlphanumeric("ab c") = false
5340 * StringUtils.isAlphanumeric("ab2c") = true
5341 * StringUtils.isAlphanumeric("ab-c") = false
5342 * </pre>
5343 *
5344 * @param str the String to check, may be null
5345 * @return <code>true</code> if only contains letters or digits,
5346 * and is non-null
5347 */
5348 public static boolean isAlphanumeric(String str) {
5349 if (str == null) {
5350 return false;
5351 }
5352 int sz = str.length();
5353 for (int i = 0; i < sz; i++) {
5354 if (Character.isLetterOrDigit(str.charAt(i)) == false) {
5355 return false;
5356 }
5357 }
5358 return true;
5359 }
5360
5361 /**
5362 * <p>Checks if the String contains only unicode letters, digits
5363 * or space (<code>' '</code>).</p>
5364 *
5365 * <p><code>null</code> will return <code>false</code>.
5366 * An empty String ("") will return <code>true</code>.</p>
5367 *
5368 * <pre>
5369 * StringUtils.isAlphanumeric(null) = false
5370 * StringUtils.isAlphanumeric("") = true
5371 * StringUtils.isAlphanumeric(" ") = true
5372 * StringUtils.isAlphanumeric("abc") = true
5373 * StringUtils.isAlphanumeric("ab c") = true
5374 * StringUtils.isAlphanumeric("ab2c") = true
5375 * StringUtils.isAlphanumeric("ab-c") = false
5376 * </pre>
5377 *
5378 * @param str the String to check, may be null
5379 * @return <code>true</code> if only contains letters, digits or space,
5380 * and is non-null
5381 */
5382 public static boolean isAlphanumericSpace(String str) {
5383 if (str == null) {
5384 return false;
5385 }
5386 int sz = str.length();
5387 for (int i = 0; i < sz; i++) {
5388 if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
5389 return false;
5390 }
5391 }
5392 return true;
5393 }
5394
5395 /**
5396 * <p>Checks if the string contains only ASCII printable characters.</p>
5397 *
5398 * <p><code>null</code> will return <code>false</code>.
5399 * An empty String ("") will return <code>true</code>.</p>
5400 *
5401 * <pre>
5402 * StringUtils.isAsciiPrintable(null) = false
5403 * StringUtils.isAsciiPrintable("") = true
5404 * StringUtils.isAsciiPrintable(" ") = true
5405 * StringUtils.isAsciiPrintable("Ceki") = true
5406 * StringUtils.isAsciiPrintable("ab2c") = true
5407 * StringUtils.isAsciiPrintable("!ab-c~") = true
5408 * StringUtils.isAsciiPrintable("\u0020") = true
5409 * StringUtils.isAsciiPrintable("\u0021") = true
5410 * StringUtils.isAsciiPrintable("\u007e") = true
5411 * StringUtils.isAsciiPrintable("\u007f") = false
5412 * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
5413 * </pre>
5414 *
5415 * @param str the string to check, may be null
5416 * @return <code>true</code> if every character is in the range
5417 * 32 thru 126
5418 * @since 2.1
5419 */
5420 public static boolean isAsciiPrintable(String str) {
5421 if (str == null) {
5422 return false;
5423 }
5424 int sz = str.length();
5425 for (int i = 0; i < sz; i++) {
5426 if (CharUtils.isAsciiPrintable(str.charAt(i)) == false) {
5427 return false;
5428 }
5429 }
5430 return true;
5431 }
5432
5433 /**
5434 * <p>Checks if the String contains only unicode digits.
5435 * A decimal point is not a unicode digit and returns false.</p>
5436 *
5437 * <p><code>null</code> will return <code>false</code>.
5438 * An empty String ("") will return <code>true</code>.</p>
5439 *
5440 * <pre>
5441 * StringUtils.isNumeric(null) = false
5442 * StringUtils.isNumeric("") = true
5443 * StringUtils.isNumeric(" ") = false
5444 * StringUtils.isNumeric("123") = true
5445 * StringUtils.isNumeric("12 3") = false
5446 * StringUtils.isNumeric("ab2c") = false
5447 * StringUtils.isNumeric("12-3") = false
5448 * StringUtils.isNumeric("12.3") = false
5449 * </pre>
5450 *
5451 * @param str the String to check, may be null
5452 * @return <code>true</code> if only contains digits, and is non-null
5453 */
5454 public static boolean isNumeric(String str) {
5455 if (str == null) {
5456 return false;
5457 }
5458 int sz = str.length();
5459 for (int i = 0; i < sz; i++) {
5460 if (Character.isDigit(str.charAt(i)) == false) {
5461 return false;
5462 }
5463 }
5464 return true;
5465 }
5466
5467 /**
5468 * <p>Checks if the String contains only unicode digits or space
5469 * (<code>' '</code>).
5470 * A decimal point is not a unicode digit and returns false.</p>
5471 *
5472 * <p><code>null</code> will return <code>false</code>.
5473 * An empty String ("") will return <code>true</code>.</p>
5474 *
5475 * <pre>
5476 * StringUtils.isNumeric(null) = false
5477 * StringUtils.isNumeric("") = true
5478 * StringUtils.isNumeric(" ") = true
5479 * StringUtils.isNumeric("123") = true
5480 * StringUtils.isNumeric("12 3") = true
5481 * StringUtils.isNumeric("ab2c") = false
5482 * StringUtils.isNumeric("12-3") = false
5483 * StringUtils.isNumeric("12.3") = false
5484 * </pre>
5485 *
5486 * @param str the String to check, may be null
5487 * @return <code>true</code> if only contains digits or space,
5488 * and is non-null
5489 */
5490 public static boolean isNumericSpace(String str) {
5491 if (str == null) {
5492 return false;
5493 }
5494 int sz = str.length();
5495 for (int i = 0; i < sz; i++) {
5496 if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
5497 return false;
5498 }
5499 }
5500 return true;
5501 }
5502
5503 /**
5504 * <p>Checks if the String contains only whitespace.</p>
5505 *
5506 * <p><code>null</code> will return <code>false</code>.
5507 * An empty String ("") will return <code>true</code>.</p>
5508 *
5509 * <pre>
5510 * StringUtils.isWhitespace(null) = false
5511 * StringUtils.isWhitespace("") = true
5512 * StringUtils.isWhitespace(" ") = true
5513 * StringUtils.isWhitespace("abc") = false
5514 * StringUtils.isWhitespace("ab2c") = false
5515 * StringUtils.isWhitespace("ab-c") = false
5516 * </pre>
5517 *
5518 * @param str the String to check, may be null
5519 * @return <code>true</code> if only contains whitespace, and is non-null
5520 * @since 2.0
5521 */
5522 public static boolean isWhitespace(String str) {
5523 if (str == null) {
5524 return false;
5525 }
5526 int sz = str.length();
5527 for (int i = 0; i < sz; i++) {
5528 if ((Character.isWhitespace(str.charAt(i)) == false)) {
5529 return false;
5530 }
5531 }
5532 return true;
5533 }
5534
5535 /**
5536 * <p>Checks if the String contains only lowercase characters.</p>
5537 *
5538 * <p><code>null</code> will return <code>false</code>.
5539 * An empty String ("") will return <code>false</code>.</p>
5540 *
5541 * <pre>
5542 * StringUtils.isAllLowerCase(null) = false
5543 * StringUtils.isAllLowerCase("") = false
5544 * StringUtils.isAllLowerCase(" ") = false
5545 * StringUtils.isAllLowerCase("abc") = true
5546 * StringUtils.isAllLowerCase("abC") = false
5547 * </pre>
5548 *
5549 * @param str the String to check, may be null
5550 * @return <code>true</code> if only contains lowercase characters, and is non-null
5551 * @since 2.5
5552 */
5553 public static boolean isAllLowerCase(String str) {
5554 if (str == null || isEmpty(str)) {
5555 return false;
5556 }
5557 int sz = str.length();
5558 for (int i = 0; i < sz; i++) {
5559 if (Character.isLowerCase(str.charAt(i)) == false) {
5560 return false;
5561 }
5562 }
5563 return true;
5564 }
5565
5566 /**
5567 * <p>Checks if the String contains only uppercase characters.</p>
5568 *
5569 * <p><code>null</code> will return <code>false</code>.
5570 * An empty String ("") will return <code>false</code>.</p>
5571 *
5572 * <pre>
5573 * StringUtils.isAllUpperCase(null) = false
5574 * StringUtils.isAllUpperCase("") = false
5575 * StringUtils.isAllUpperCase(" ") = false
5576 * StringUtils.isAllUpperCase("ABC") = true
5577 * StringUtils.isAllUpperCase("aBC") = false
5578 * </pre>
5579 *
5580 * @param str the String to check, may be null
5581 * @return <code>true</code> if only contains uppercase characters, and is non-null
5582 * @since 2.5
5583 */
5584 public static boolean isAllUpperCase(String str) {
5585 if (str == null || isEmpty(str)) {
5586 return false;
5587 }
5588 int sz = str.length();
5589 for (int i = 0; i < sz; i++) {
5590 if (Character.isUpperCase(str.charAt(i)) == false) {
5591 return false;
5592 }
5593 }
5594 return true;
5595 }
5596
5597 // Defaults
5598 //-----------------------------------------------------------------------
5599 /**
5600 * <p>Returns either the passed in String,
5601 * or if the String is <code>null</code>, an empty String ("").</p>
5602 *
5603 * <pre>
5604 * StringUtils.defaultString(null) = ""
5605 * StringUtils.defaultString("") = ""
5606 * StringUtils.defaultString("bat") = "bat"
5607 * </pre>
5608 *
5609 * @see ObjectUtils#toString(Object)
5610 * @see String#valueOf(Object)
5611 * @param str the String to check, may be null
5612 * @return the passed in String, or the empty String if it
5613 * was <code>null</code>
5614 */
5615 public static String defaultString(String str) {
5616 return str == null ? EMPTY : str;
5617 }
5618
5619 /**
5620 * <p>Returns either the passed in String, or if the String is
5621 * <code>null</code>, the value of <code>defaultStr</code>.</p>
5622 *
5623 * <pre>
5624 * StringUtils.defaultString(null, "NULL") = "NULL"
5625 * StringUtils.defaultString("", "NULL") = ""
5626 * StringUtils.defaultString("bat", "NULL") = "bat"
5627 * </pre>
5628 *
5629 * @see ObjectUtils#toString(Object,String)
5630 * @see String#valueOf(Object)
5631 * @param str the String to check, may be null
5632 * @param defaultStr the default String to return
5633 * if the input is <code>null</code>, may be null
5634 * @return the passed in String, or the default if it was <code>null</code>
5635 */
5636 public static String defaultString(String str, String defaultStr) {
5637 return str == null ? defaultStr : str;
5638 }
5639
5640 /**
5641 * <p>Returns either the passed in String, or if the String is
5642 * empty or <code>null</code>, the value of <code>defaultStr</code>.</p>
5643 *
5644 * <pre>
5645 * StringUtils.defaultIfEmpty(null, "NULL") = "NULL"
5646 * StringUtils.defaultIfEmpty("", "NULL") = "NULL"
5647 * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
5648 * StringUtils.defaultIfEmpty("", null) = null
5649 * </pre>
5650 *
5651 * @see StringUtils#defaultString(String, String)
5652 * @param str the String to check, may be null
5653 * @param defaultStr the default String to return
5654 * if the input is empty ("") or <code>null</code>, may be null
5655 * @return the passed in String, or the default
5656 */
5657 public static String defaultIfEmpty(String str, String defaultStr) {
5658 return StringUtils.isEmpty(str) ? defaultStr : str;
5659 }
5660
5661 // Reversing
5662 //-----------------------------------------------------------------------
5663 /**
5664 * <p>Reverses a String as per {@link StringBuffer#reverse()}.</p>
5665 *
5666 * <p>A <code>null</code> String returns <code>null</code>.</p>
5667 *
5668 * <pre>
5669 * StringUtils.reverse(null) = null
5670 * StringUtils.reverse("") = ""
5671 * StringUtils.reverse("bat") = "tab"
5672 * </pre>
5673 *
5674 * @param str the String to reverse, may be null
5675 * @return the reversed String, <code>null</code> if null String input
5676 */
5677 public static String reverse(String str) {
5678 if (str == null) {
5679 return null;
5680 }
5681 return new StringBuffer(str).reverse().toString();
5682 }
5683
5684 /**
5685 * <p>Reverses a String that is delimited by a specific character.</p>
5686 *
5687 * <p>The Strings between the delimiters are not reversed.
5688 * Thus java.lang.String becomes String.lang.java (if the delimiter
5689 * is <code>'.'</code>).</p>
5690 *
5691 * <pre>
5692 * StringUtils.reverseDelimited(null, *) = null
5693 * StringUtils.reverseDelimited("", *) = ""
5694 * StringUtils.reverseDelimited("a.b.c", 'x') = "a.b.c"
5695 * StringUtils.reverseDelimited("a.b.c", ".") = "c.b.a"
5696 * </pre>
5697 *
5698 * @param str the String to reverse, may be null
5699 * @param separatorChar the separator character to use
5700 * @return the reversed String, <code>null</code> if null String input
5701 * @since 2.0
5702 */
5703 public static String reverseDelimited(String str, char separatorChar) {
5704 if (str == null) {
5705 return null;
5706 }
5707 // could implement manually, but simple way is to reuse other,
5708 // probably slower, methods.
5709 String[] strs = split(str, separatorChar);
5710 ArrayUtils.reverse(strs);
5711 return join(strs, separatorChar);
5712 }
5713
5714 /**
5715 * <p>Reverses a String that is delimited by a specific character.</p>
5716 *
5717 * <p>The Strings between the delimiters are not reversed.
5718 * Thus java.lang.String becomes String.lang.java (if the delimiter
5719 * is <code>"."</code>).</p>
5720 *
5721 * <pre>
5722 * StringUtils.reverseDelimitedString(null, *) = null
5723 * StringUtils.reverseDelimitedString("",*) = ""
5724 * StringUtils.reverseDelimitedString("a.b.c", null) = "a.b.c"
5725 * StringUtils.reverseDelimitedString("a.b.c", ".") = "c.b.a"
5726 * </pre>
5727 *
5728 * @param str the String to reverse, may be null
5729 * @param separatorChars the separator characters to use, null treated as whitespace
5730 * @return the reversed String, <code>null</code> if null String input
5731 * @deprecated Use {@link #reverseDelimited(String, char)} instead.
5732 * This method is broken as the join doesn't know which char to use.
5733 * Method will be removed in Commons Lang 3.0.
5734 *
5735 */
5736 public static String reverseDelimitedString(String str, String separatorChars) {
5737 if (str == null) {
5738 return null;
5739 }
5740 // could implement manually, but simple way is to reuse other,
5741 // probably slower, methods.
5742 String[] strs = split(str, separatorChars);
5743 ArrayUtils.reverse(strs);
5744 if (separatorChars == null) {
5745 return join(strs, ' ');
5746 }
5747 return join(strs, separatorChars);
5748 }
5749
5750 // Abbreviating
5751 //-----------------------------------------------------------------------
5752 /**
5753 * <p>Abbreviates a String using ellipses. This will turn
5754 * "Now is the time for all good men" into "Now is the time for..."</p>
5755 *
5756 * <p>Specifically:
5757 * <ul>
5758 * <li>If <code>str</code> is less than <code>maxWidth</code> characters
5759 * long, return it.</li>
5760 * <li>Else abbreviate it to <code>(substring(str, 0, max-3) + "...")</code>.</li>
5761 * <li>If <code>maxWidth</code> is less than <code>4</code>, throw an
5762 * <code>IllegalArgumentException</code>.</li>
5763 * <li>In no case will it return a String of length greater than
5764 * <code>maxWidth</code>.</li>
5765 * </ul>
5766 * </p>
5767 *
5768 * <pre>
5769 * StringUtils.abbreviate(null, *) = null
5770 * StringUtils.abbreviate("", 4) = ""
5771 * StringUtils.abbreviate("abcdefg", 6) = "abc..."
5772 * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
5773 * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
5774 * StringUtils.abbreviate("abcdefg", 4) = "a..."
5775 * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
5776 * </pre>
5777 *
5778 * @param str the String to check, may be null
5779 * @param maxWidth maximum length of result String, must be at least 4
5780 * @return abbreviated String, <code>null</code> if null String input
5781 * @throws IllegalArgumentException if the width is too small
5782 * @since 2.0
5783 */
5784 public static String abbreviate(String str, int maxWidth) {
5785 return abbreviate(str, 0, maxWidth);
5786 }
5787
5788 /**
5789 * <p>Abbreviates a String using ellipses. This will turn
5790 * "Now is the time for all good men" into "...is the time for..."</p>
5791 *
5792 * <p>Works like <code>abbreviate(String, int)</code>, but allows you to specify
5793 * a "left edge" offset. Note that this left edge is not necessarily going to
5794 * be the leftmost character in the result, or the first character following the
5795 * ellipses, but it will appear somewhere in the result.
5796 *
5797 * <p>In no case will it return a String of length greater than
5798 * <code>maxWidth</code>.</p>
5799 *
5800 * <pre>
5801 * StringUtils.abbreviate(null, *, *) = null
5802 * StringUtils.abbreviate("", 0, 4) = ""
5803 * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
5804 * StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..."
5805 * StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..."
5806 * StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..."
5807 * StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..."
5808 * StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..."
5809 * StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno"
5810 * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
5811 * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
5812 * StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentException
5813 * StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentException
5814 * </pre>
5815 *
5816 * @param str the String to check, may be null
5817 * @param offset left edge of source String
5818 * @param maxWidth maximum length of result String, must be at least 4
5819 * @return abbreviated String, <code>null</code> if null String input
5820 * @throws IllegalArgumentException if the width is too small
5821 * @since 2.0
5822 */
5823 public static String abbreviate(String str, int offset, int maxWidth) {
5824 if (str == null) {
5825 return null;
5826 }
5827 if (maxWidth < 4) {
5828 throw new IllegalArgumentException("Minimum abbreviation width is 4");
5829 }
5830 if (str.length() <= maxWidth) {
5831 return str;
5832 }
5833 if (offset > str.length()) {
5834 offset = str.length();
5835 }
5836 if ((str.length() - offset) < (maxWidth - 3)) {
5837 offset = str.length() - (maxWidth - 3);
5838 }
5839 if (offset <= 4) {
5840 return str.substring(0, maxWidth - 3) + "...";
5841 }
5842 if (maxWidth < 7) {
5843 throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
5844 }
5845 if ((offset + (maxWidth - 3)) < str.length()) {
5846 return "..." + abbreviate(str.substring(offset), maxWidth - 3);
5847 }
5848 return "..." + str.substring(str.length() - (maxWidth - 3));
5849 }
5850
5851 /**
5852 * <p>Abbreviates a String to the length passed, replacing the middle characters with the supplied
5853 * replacement String.</p>
5854 *
5855 * <p>This abbreviation only occurs if the following criteria is met:
5856 * <ul>
5857 * <li>Neither the String for abbreviation nor the replacement String are null or empty </li>
5858 * <li>The length to truncate to is less than the length of the supplied String</li>
5859 * <li>The length to truncate to is greater than 0</li>
5860 * <li>The abbreviated String will have enough room for the length supplied replacement String
5861 * and the first and last characters of the supplied String for abbreviation</li>
5862 * </ul>
5863 * Otherwise, the returned String will be the same as the supplied String for abbreviation.
5864 * </p>
5865 *
5866 * <pre>
5867 * StringUtils.abbreviateMiddle(null, null, 0) = null
5868 * StringUtils.abbreviateMiddle("abc", null, 0) = "abc"
5869 * StringUtils.abbreviateMiddle("abc", ".", 0) = "abc"
5870 * StringUtils.abbreviateMiddle("abc", ".", 3) = "abc"
5871 * StringUtils.abbreviateMiddle("abcdef", ".", 4) = "ab.f"
5872 * </pre>
5873 *
5874 * @param str the String to abbreviate, may be null
5875 * @param middle the String to replace the middle characters with, may be null
5876 * @param length the length to abbreviate <code>str</code> to.
5877 * @return the abbreviated String if the above criteria is met, or the original String supplied for abbreviation.
5878 * @since 2.5
5879 */
5880 public static String abbreviateMiddle(String str, String middle, int length) {
5881 if (isEmpty(str) || isEmpty(middle)) {
5882 return str;
5883 }
5884
5885 if (length >= str.length() || length < (middle.length()+2)) {
5886 return str;
5887 }
5888
5889 int targetSting = length-middle.length();
5890 int startOffset = targetSting/2+targetSting%2;
5891 int endOffset = str.length()-targetSting/2;
5892
5893 StringBuffer builder = new StringBuffer(length);
5894 builder.append(str.substring(0,startOffset));
5895 builder.append(middle);
5896 builder.append(str.substring(endOffset));
5897
5898 return builder.toString();
5899 }
5900
5901 // Difference
5902 //-----------------------------------------------------------------------
5903 /**
5904 * <p>Compares two Strings, and returns the portion where they differ.
5905 * (More precisely, return the remainder of the second String,
5906 * starting from where it's different from the first.)</p>
5907 *
5908 * <p>For example,
5909 * <code>difference("i am a machine", "i am a robot") -> "robot"</code>.</p>
5910 *
5911 * <pre>
5912 * StringUtils.difference(null, null) = null
5913 * StringUtils.difference("", "") = ""
5914 * StringUtils.difference("", "abc") = "abc"
5915 * StringUtils.difference("abc", "") = ""
5916 * StringUtils.difference("abc", "abc") = ""
5917 * StringUtils.difference("ab", "abxyz") = "xyz"
5918 * StringUtils.difference("abcde", "abxyz") = "xyz"
5919 * StringUtils.difference("abcde", "xyz") = "xyz"
5920 * </pre>
5921 *
5922 * @param str1 the first String, may be null
5923 * @param str2 the second String, may be null
5924 * @return the portion of str2 where it differs from str1; returns the
5925 * empty String if they are equal
5926 * @since 2.0
5927 */
5928 public static String difference(String str1, String str2) {
5929 if (str1 == null) {
5930 return str2;
5931 }
5932 if (str2 == null) {
5933 return str1;
5934 }
5935 int at = indexOfDifference(str1, str2);
5936 if (at == -1) {
5937 return EMPTY;
5938 }
5939 return str2.substring(at);
5940 }
5941
5942 /**
5943 * <p>Compares two Strings, and returns the index at which the
5944 * Strings begin to differ.</p>
5945 *
5946 * <p>For example,
5947 * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code></p>
5948 *
5949 * <pre>
5950 * StringUtils.indexOfDifference(null, null) = -1
5951 * StringUtils.indexOfDifference("", "") = -1
5952 * StringUtils.indexOfDifference("", "abc") = 0
5953 * StringUtils.indexOfDifference("abc", "") = 0
5954 * StringUtils.indexOfDifference("abc", "abc") = -1
5955 * StringUtils.indexOfDifference("ab", "abxyz") = 2
5956 * StringUtils.indexOfDifference("abcde", "abxyz") = 2
5957 * StringUtils.indexOfDifference("abcde", "xyz") = 0
5958 * </pre>
5959 *
5960 * @param str1 the first String, may be null
5961 * @param str2 the second String, may be null
5962 * @return the index where str2 and str1 begin to differ; -1 if they are equal
5963 * @since 2.0
5964 */
5965 public static int indexOfDifference(String str1, String str2) {
5966 if (str1 == str2) {
5967 return -1;
5968 }
5969 if (str1 == null || str2 == null) {
5970 return 0;
5971 }
5972 int i;
5973 for (i = 0; i < str1.length() && i < str2.length(); ++i) {
5974 if (str1.charAt(i) != str2.charAt(i)) {
5975 break;
5976 }
5977 }
5978 if (i < str2.length() || i < str1.length()) {
5979 return i;
5980 }
5981 return -1;
5982 }
5983
5984 /**
5985 * <p>Compares all Strings in an array and returns the index at which the
5986 * Strings begin to differ.</p>
5987 *
5988 * <p>For example,
5989 * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
5990 *
5991 * <pre>
5992 * StringUtils.indexOfDifference(null) = -1
5993 * StringUtils.indexOfDifference(new String[] {}) = -1
5994 * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
5995 * StringUtils.indexOfDifference(new String[] {null, null}) = -1
5996 * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
5997 * StringUtils.indexOfDifference(new String[] {"", null}) = 0
5998 * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
5999 * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
6000 * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
6001 * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
6002 * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
6003 * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
6004 * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
6005 * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
6006 * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
6007 * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
6008 * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
6009 * </pre>
6010 *
6011 * @param strs array of strings, entries may be null
6012 * @return the index where the strings begin to differ; -1 if they are all equal
6013 * @since 2.4
6014 */
6015 public static int indexOfDifference(String[] strs) {
6016 if (strs == null || strs.length <= 1) {
6017 return -1;
6018 }
6019 boolean anyStringNull = false;
6020 boolean allStringsNull = true;
6021 int arrayLen = strs.length;
6022 int shortestStrLen = Integer.MAX_VALUE;
6023 int longestStrLen = 0;
6024
6025 // find the min and max string lengths; this avoids checking to make
6026 // sure we are not exceeding the length of the string each time through
6027 // the bottom loop.
6028 for (int i = 0; i < arrayLen; i++) {
6029 if (strs[i] == null) {
6030 anyStringNull = true;
6031 shortestStrLen = 0;
6032 } else {
6033 allStringsNull = false;
6034 shortestStrLen = Math.min(strs[i].length(), shortestStrLen);
6035 longestStrLen = Math.max(strs[i].length(), longestStrLen);
6036 }
6037 }
6038
6039 // handle lists containing all nulls or all empty strings
6040 if (allStringsNull || (longestStrLen == 0 && !anyStringNull)) {
6041 return -1;
6042 }
6043
6044 // handle lists containing some nulls or some empty strings
6045 if (shortestStrLen == 0) {
6046 return 0;
6047 }
6048
6049 // find the position with the first difference across all strings
6050 int firstDiff = -1;
6051 for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
6052 char comparisonChar = strs[0].charAt(stringPos);
6053 for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
6054 if (strs[arrayPos].charAt(stringPos) != comparisonChar) {
6055 firstDiff = stringPos;
6056 break;
6057 }
6058 }
6059 if (firstDiff != -1) {
6060 break;
6061 }
6062 }
6063
6064 if (firstDiff == -1 && shortestStrLen != longestStrLen) {
6065 // we compared all of the characters up to the length of the
6066 // shortest string and didn't find a match, but the string lengths
6067 // vary, so return the length of the shortest string.
6068 return shortestStrLen;
6069 }
6070 return firstDiff;
6071 }
6072
6073 /**
6074 * <p>Compares all Strings in an array and returns the initial sequence of
6075 * characters that is common to all of them.</p>
6076 *
6077 * <p>For example,
6078 * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "</code></p>
6079 *
6080 * <pre>
6081 * StringUtils.getCommonPrefix(null) = ""
6082 * StringUtils.getCommonPrefix(new String[] {}) = ""
6083 * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
6084 * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
6085 * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
6086 * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
6087 * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
6088 * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
6089 * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
6090 * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
6091 * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
6092 * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
6093 * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
6094 * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
6095 * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
6096 * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
6097 * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "
6098 * </pre>
6099 *
6100 * @param strs array of String objects, entries may be null
6101 * @return the initial sequence of characters that are common to all Strings
6102 * in the array; empty String if the array is null, the elements are all null
6103 * or if there is no common prefix.
6104 * @since 2.4
6105 */
6106 public static String getCommonPrefix(String[] strs) {
6107 if (strs == null || strs.length == 0) {
6108 return EMPTY;
6109 }
6110 int smallestIndexOfDiff = indexOfDifference(strs);
6111 if (smallestIndexOfDiff == -1) {
6112 // all strings were identical
6113 if (strs[0] == null) {
6114 return EMPTY;
6115 }
6116 return strs[0];
6117 } else if (smallestIndexOfDiff == 0) {
6118 // there were no common initial characters
6119 return EMPTY;
6120 } else {
6121 // we found a common initial character sequence
6122 return strs[0].substring(0, smallestIndexOfDiff);
6123 }
6124 }
6125
6126 // Misc
6127 //-----------------------------------------------------------------------
6128 /**
6129 * <p>Find the Levenshtein distance between two Strings.</p>
6130 *
6131 * <p>This is the number of changes needed to change one String into
6132 * another, where each change is a single character modification (deletion,
6133 * insertion or substitution).</p>
6134 *
6135 * <p>The previous implementation of the Levenshtein distance algorithm
6136 * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
6137 *
6138 * <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
6139 * which can occur when my Java implementation is used with very large strings.<br>
6140 * This implementation of the Levenshtein distance algorithm
6141 * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p>
6142 *
6143 * <pre>
6144 * StringUtils.getLevenshteinDistance(null, *) = IllegalArgumentException
6145 * StringUtils.getLevenshteinDistance(*, null) = IllegalArgumentException
6146 * StringUtils.getLevenshteinDistance("","") = 0
6147 * StringUtils.getLevenshteinDistance("","a") = 1
6148 * StringUtils.getLevenshteinDistance("aaapppp", "") = 7
6149 * StringUtils.getLevenshteinDistance("frog", "fog") = 1
6150 * StringUtils.getLevenshteinDistance("fly", "ant") = 3
6151 * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
6152 * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
6153 * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
6154 * StringUtils.getLevenshteinDistance("hello", "hallo") = 1
6155 * </pre>
6156 *
6157 * @param s the first String, must not be null
6158 * @param t the second String, must not be null
6159 * @return result distance
6160 * @throws IllegalArgumentException if either String input <code>null</code>
6161 */
6162 public static int getLevenshteinDistance(String s, String t) {
6163 if (s == null || t == null) {
6164 throw new IllegalArgumentException("Strings must not be null");
6165 }
6166
6167 /*
6168 The difference between this impl. and the previous is that, rather
6169 than creating and retaining a matrix of size s.length()+1 by t.length()+1,
6170 we maintain two single-dimensional arrays of length s.length()+1. The first, d,
6171 is the 'current working' distance array that maintains the newest distance cost
6172 counts as we iterate through the characters of String s. Each time we increment
6173 the index of String t we are comparing, d is copied to p, the second int[]. Doing so
6174 allows us to retain the previous cost counts as required by the algorithm (taking
6175 the minimum of the cost count to the left, up one, and diagonally up and to the left
6176 of the current cost count being calculated). (Note that the arrays aren't really
6177 copied anymore, just switched...this is clearly much better than cloning an array
6178 or doing a System.arraycopy() each time through the outer loop.)
6179
6180 Effectively, the difference between the two implementations is this one does not
6181 cause an out of memory condition when calculating the LD over two very large strings.
6182 */
6183
6184 int n = s.length(); // length of s
6185 int m = t.length(); // length of t
6186
6187 if (n == 0) {
6188 return m;
6189 } else if (m == 0) {
6190 return n;
6191 }
6192
6193 if (n > m) {
6194 // swap the input strings to consume less memory
6195 String tmp = s;
6196 s = t;
6197 t = tmp;
6198 n = m;
6199 m = t.length();
6200 }
6201
6202 int p[] = new int[n+1]; //'previous' cost array, horizontally
6203 int d[] = new int[n+1]; // cost array, horizontally
6204 int _d[]; //placeholder to assist in swapping p and d
6205
6206 // indexes into strings s and t
6207 int i; // iterates through s
6208 int j; // iterates through t
6209
6210 char t_j; // jth character of t
6211
6212 int cost; // cost
6213
6214 for (i = 0; i<=n; i++) {
6215 p[i] = i;
6216 }
6217
6218 for (j = 1; j<=m; j++) {
6219 t_j = t.charAt(j-1);
6220 d[0] = j;
6221
6222 for (i=1; i<=n; i++) {
6223 cost = s.charAt(i-1)==t_j ? 0 : 1;
6224 // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
6225 d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1), p[i-1]+cost);
6226 }
6227
6228 // copy current distance counts to 'previous row' distance counts
6229 _d = p;
6230 p = d;
6231 d = _d;
6232 }
6233
6234 // our last action in the above loop was to switch d and p, so p now
6235 // actually has the most recent cost counts
6236 return p[n];
6237 }
6238
6239 /**
6240 * <p>Gets the minimum of three <code>int</code> values.</p>
6241 *
6242 * @param a value 1
6243 * @param b value 2
6244 * @param c value 3
6245 * @return the smallest of the values
6246 */
6247 /*
6248 private static int min(int a, int b, int c) {
6249 // Method copied from NumberUtils to avoid dependency on subpackage
6250 if (b < a) {
6251 a = b;
6252 }
6253 if (c < a) {
6254 a = c;
6255 }
6256 return a;
6257 }
6258 */
6259
6260 // startsWith
6261 //-----------------------------------------------------------------------
6262
6263 /**
6264 * <p>Check if a String starts with a specified prefix.</p>
6265 *
6266 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
6267 * references are considered to be equal. The comparison is case sensitive.</p>
6268 *
6269 * <pre>
6270 * StringUtils.startsWith(null, null) = true
6271 * StringUtils.startsWith(null, "abc") = false
6272 * StringUtils.startsWith("abcdef", null) = false
6273 * StringUtils.startsWith("abcdef", "abc") = true
6274 * StringUtils.startsWith("ABCDEF", "abc") = false
6275 * </pre>
6276 *
6277 * @see java.lang.String#startsWith(String)
6278 * @param str the String to check, may be null
6279 * @param prefix the prefix to find, may be null
6280 * @return <code>true</code> if the String starts with the prefix, case sensitive, or
6281 * both <code>null</code>
6282 * @since 2.4
6283 */
6284 public static boolean startsWith(String str, String prefix) {
6285 return startsWith(str, prefix, false);
6286 }
6287
6288 /**
6289 * <p>Case insensitive check if a String starts with a specified prefix.</p>
6290 *
6291 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
6292 * references are considered to be equal. The comparison is case insensitive.</p>
6293 *
6294 * <pre>
6295 * StringUtils.startsWithIgnoreCase(null, null) = true
6296 * StringUtils.startsWithIgnoreCase(null, "abc") = false
6297 * StringUtils.startsWithIgnoreCase("abcdef", null) = false
6298 * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
6299 * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
6300 * </pre>
6301 *
6302 * @see java.lang.String#startsWith(String)
6303 * @param str the String to check, may be null
6304 * @param prefix the prefix to find, may be null
6305 * @return <code>true</code> if the String starts with the prefix, case insensitive, or
6306 * both <code>null</code>
6307 * @since 2.4
6308 */
6309 public static boolean startsWithIgnoreCase(String str, String prefix) {
6310 return startsWith(str, prefix, true);
6311 }
6312
6313 /**
6314 * <p>Check if a String starts with a specified prefix (optionally case insensitive).</p>
6315 *
6316 * @see java.lang.String#startsWith(String)
6317 * @param str the String to check, may be null
6318 * @param prefix the prefix to find, may be null
6319 * @param ignoreCase inidicates whether the compare should ignore case
6320 * (case insensitive) or not.
6321 * @return <code>true</code> if the String starts with the prefix or
6322 * both <code>null</code>
6323 */
6324 private static boolean startsWith(String str, String prefix, boolean ignoreCase) {
6325 if (str == null || prefix == null) {
6326 return (str == null && prefix == null);
6327 }
6328 if (prefix.length() > str.length()) {
6329 return false;
6330 }
6331 return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
6332 }
6333
6334 /**
6335 * <p>Check if a String starts with any of an array of specified strings.</p>
6336 *
6337 * <pre>
6338 * StringUtils.startsWithAny(null, null) = false
6339 * StringUtils.startsWithAny(null, new String[] {"abc"}) = false
6340 * StringUtils.startsWithAny("abcxyz", null) = false
6341 * StringUtils.startsWithAny("abcxyz", new String[] {""}) = false
6342 * StringUtils.startsWithAny("abcxyz", new String[] {"abc"}) = true
6343 * StringUtils.startsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
6344 * </pre>
6345 *
6346 * @see #startsWith(String, String)
6347 * @param string the String to check, may be null
6348 * @param searchStrings the Strings to find, may be null or empty
6349 * @return <code>true</code> if the String starts with any of the the prefixes, case insensitive, or
6350 * both <code>null</code>
6351 * @since 2.5
6352 */
6353 public static boolean startsWithAny(String string, String[] searchStrings) {
6354 if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
6355 return false;
6356 }
6357 for (int i = 0; i < searchStrings.length; i++) {
6358 String searchString = searchStrings[i];
6359 if (StringUtils.startsWith(string, searchString)) {
6360 return true;
6361 }
6362 }
6363 return false;
6364 }
6365
6366 // endsWith
6367 //-----------------------------------------------------------------------
6368
6369 /**
6370 * <p>Check if a String ends with a specified suffix.</p>
6371 *
6372 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
6373 * references are considered to be equal. The comparison is case sensitive.</p>
6374 *
6375 * <pre>
6376 * StringUtils.endsWith(null, null) = true
6377 * StringUtils.endsWith(null, "def") = false
6378 * StringUtils.endsWith("abcdef", null) = false
6379 * StringUtils.endsWith("abcdef", "def") = true
6380 * StringUtils.endsWith("ABCDEF", "def") = false
6381 * StringUtils.endsWith("ABCDEF", "cde") = false
6382 * </pre>
6383 *
6384 * @see java.lang.String#endsWith(String)
6385 * @param str the String to check, may be null
6386 * @param suffix the suffix to find, may be null
6387 * @return <code>true</code> if the String ends with the suffix, case sensitive, or
6388 * both <code>null</code>
6389 * @since 2.4
6390 */
6391 public static boolean endsWith(String str, String suffix) {
6392 return endsWith(str, suffix, false);
6393 }
6394
6395 /**
6396 * <p>Case insensitive check if a String ends with a specified suffix.</p>
6397 *
6398 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
6399 * references are considered to be equal. The comparison is case insensitive.</p>
6400 *
6401 * <pre>
6402 * StringUtils.endsWithIgnoreCase(null, null) = true
6403 * StringUtils.endsWithIgnoreCase(null, "def") = false
6404 * StringUtils.endsWithIgnoreCase("abcdef", null) = false
6405 * StringUtils.endsWithIgnoreCase("abcdef", "def") = true
6406 * StringUtils.endsWithIgnoreCase("ABCDEF", "def") = true
6407 * StringUtils.endsWithIgnoreCase("ABCDEF", "cde") = false
6408 * </pre>
6409 *
6410 * @see java.lang.String#endsWith(String)
6411 * @param str the String to check, may be null
6412 * @param suffix the suffix to find, may be null
6413 * @return <code>true</code> if the String ends with the suffix, case insensitive, or
6414 * both <code>null</code>
6415 * @since 2.4
6416 */
6417 public static boolean endsWithIgnoreCase(String str, String suffix) {
6418 return endsWith(str, suffix, true);
6419 }
6420
6421 /**
6422 * <p>Check if a String ends with a specified suffix (optionally case insensitive).</p>
6423 *
6424 * @see java.lang.String#endsWith(String)
6425 * @param str the String to check, may be null
6426 * @param suffix the suffix to find, may be null
6427 * @param ignoreCase inidicates whether the compare should ignore case
6428 * (case insensitive) or not.
6429 * @return <code>true</code> if the String starts with the prefix or
6430 * both <code>null</code>
6431 */
6432 private static boolean endsWith(String str, String suffix, boolean ignoreCase) {
6433 if (str == null || suffix == null) {
6434 return (str == null && suffix == null);
6435 }
6436 if (suffix.length() > str.length()) {
6437 return false;
6438 }
6439 int strOffset = str.length() - suffix.length();
6440 return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
6441 }
6442 }