Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: libadblockplus-android/src/org/apache/commons/lang/StringUtils.java

Issue 29415555: Issue 5148 - Remove Apache String Utils code (Closed)
Patch Set: Created April 17, 2017, 7:11 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Simplified by Andrey Novikov for AdBlock Plus
3 */
4
5 /*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements. See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21 package org.apache.commons.lang;
22
23
24 /**
25 * <p>Operations on {@link java.lang.String} that are
26 * <code>null</code> safe.</p>
27 * <p/>
28 * <ul>
29 * <li><b>IsEmpty/IsBlank</b>
30 * - checks if a String contains text</li>
31 * <li><b>Trim/Strip</b>
32 * - removes leading and trailing whitespace</li>
33 * <li><b>Equals</b>
34 * - compares two strings null-safe</li>
35 * <li><b>startsWith</b>
36 * - check if a String starts with a prefix null-safe</li>
37 * <li><b>endsWith</b>
38 * - check if a String ends with a suffix null-safe</li>
39 * <li><b>IndexOf/LastIndexOf/Contains</b>
40 * - null-safe index-of checks
41 * <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
42 * - index-of any of a set of Strings</li>
43 * <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
44 * - does String contains only/none/any of these characters</li>
45 * <li><b>Substring/Left/Right/Mid</b>
46 * - null-safe substring extractions</li>
47 * <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
48 * - substring extraction relative to other strings</li>
49 * <li><b>Split/Join</b>
50 * - splits a String into an array of substrings and vice versa</li>
51 * <li><b>Remove/Delete</b>
52 * - removes part of a String</li>
53 * <li><b>Replace/Overlay</b>
54 * - Searches a String and replaces one String with another</li>
55 * <li><b>Chomp/Chop</b>
56 * - removes the last part of a String</li>
57 * <li><b>LeftPad/RightPad/Center/Repeat</b>
58 * - pads a String</li>
59 * <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
60 * - changes the case of a String</li>
61 * <li><b>CountMatches</b>
62 * - counts the number of occurrences of one String in another</li>
63 * <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
64 * - checks the characters in a String</li>
65 * <li><b>DefaultString</b>
66 * - protects against a null input String</li>
67 * <li><b>Reverse/ReverseDelimited</b>
68 * - reverses a String</li>
69 * <li><b>Abbreviate</b>
70 * - abbreviates a string using ellipsis</li>
71 * <li><b>Difference</b>
72 * - compares Strings and reports on their differences</li>
73 * <li><b>LevensteinDistance</b>
74 * - the number of changes needed to change one String into another</li>
75 * </ul>
76 * <p/>
77 * <p>The <code>StringUtils</code> class defines certain words related to
78 * String handling.</p>
79 * <p/>
80 * <ul>
81 * <li>null - <code>null</code></li>
82 * <li>empty - a zero-length string (<code>""</code>)</li>
83 * <li>space - the space character (<code>' '</code>, char 32)</li>
84 * <li>whitespace - the characters defined by {@link Character#isWhitespace(char )}</li>
85 * <li>trim - the characters &lt;= 32 as in {@link String#trim()}</li>
86 * </ul>
87 * <p/>
88 * <p><code>StringUtils</code> handles <code>null</code> input Strings quietly.
89 * That is to say that a <code>null</code> input will return <code>null</code>.
90 * Where a <code>boolean</code> or <code>int</code> is being returned
91 * details vary by method.</p>
92 * <p/>
93 * <p>A side effect of the <code>null</code> handling is that a
94 * <code>NullPointerException</code> should be considered a bug in
95 * <code>StringUtils</code> (except for deprecated methods).</p>
96 * <p/>
97 * <p>Methods in this class give sample code to explain their operation.
98 * The symbol <code>*</code> is used to indicate any input including <code>null< /code>.</p>
99 *
100 * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</ a>
101 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
102 * @author Daniel L. Rall
103 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
104 * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
105 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
106 * @author Stephen Colebourne
107 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
108 * @author Holger Krauth
109 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
110 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
111 * @author Arun Mammen Thomas
112 * @author Gary Gregory
113 * @author Phil Steitz
114 * @author Al Chou
115 * @author Michael Davey
116 * @author Reuben Sivan
117 * @author Chris Hyzer
118 * @author Scott Johnson
119 * @version $Id: StringUtils.java 635447 2008-03-10 06:27:09Z bayard $
120 * @see java.lang.String
121 * @since 1.0
122 */
123 public class StringUtils
124 {
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 *
144 * @since 2.0
145 */
146 public static final String EMPTY = "";
147
148 /**
149 * Represents a failed index search.
150 *
151 * @since 2.1
152 */
153 public static final int INDEX_NOT_FOUND = -1;
154
155 /**
156 * <p>The maximum size to which the padding constant(s) can expand.</p>
157 */
158 private static final int PAD_LIMIT = 8192;
159
160 /**
161 * <p><code>StringUtils</code> instances should NOT be constructed in
162 * standard programming. Instead, the class should be used as
163 * <code>StringUtils.trim(" foo ");</code>.</p>
164 * <p/>
165 * <p>This constructor is public to permit tools that require a JavaBean
166 * instance to operate.</p>
167 */
168 public StringUtils()
169 {
170 super();
171 }
172
173 // Empty checks
174 //-----------------------------------------------------------------------
175
176 /**
177 * <p>Checks if a String is empty ("") or null.</p>
178 * <p/>
179 * <pre>
180 * StringUtils.isEmpty(null) = true
181 * StringUtils.isEmpty("") = true
182 * StringUtils.isEmpty(" ") = false
183 * StringUtils.isEmpty("bob") = false
184 * StringUtils.isEmpty(" bob ") = false
185 * </pre>
186 * <p/>
187 * <p>NOTE: This method changed in Lang version 2.0.
188 * It no longer trims the String.
189 * That functionality is available in isBlank().</p>
190 *
191 * @param str the String to check, may be null
192 * @return <code>true</code> if the String is empty or null
193 */
194 public static boolean isEmpty(String str)
195 {
196 return str == null || str.length() == 0;
197 }
198
199 /**
200 * <p>Checks if a String is not empty ("") and not null.</p>
201 * <p/>
202 * <pre>
203 * StringUtils.isNotEmpty(null) = false
204 * StringUtils.isNotEmpty("") = false
205 * StringUtils.isNotEmpty(" ") = true
206 * StringUtils.isNotEmpty("bob") = true
207 * StringUtils.isNotEmpty(" bob ") = true
208 * </pre>
209 *
210 * @param str the String to check, may be null
211 * @return <code>true</code> if the String is not empty and not null
212 */
213 public static boolean isNotEmpty(String str)
214 {
215 return !StringUtils.isEmpty(str);
216 }
217
218 /**
219 * <p>Checks if a String is whitespace, empty ("") or null.</p>
220 * <p/>
221 * <pre>
222 * StringUtils.isBlank(null) = true
223 * StringUtils.isBlank("") = true
224 * StringUtils.isBlank(" ") = true
225 * StringUtils.isBlank("bob") = false
226 * StringUtils.isBlank(" bob ") = false
227 * </pre>
228 *
229 * @param str the String to check, may be null
230 * @return <code>true</code> if the String is null, empty or whitespace
231 * @since 2.0
232 */
233 public static boolean isBlank(String str)
234 {
235 int strLen;
236 if (str == null || (strLen = str.length()) == 0)
237 {
238 return true;
239 }
240 for (int i = 0; i < strLen; i++)
241 {
242 if ((Character.isWhitespace(str.charAt(i)) == false))
243 {
244 return false;
245 }
246 }
247 return true;
248 }
249
250 /**
251 * <p>Checks if a String is not empty (""), not null and not whitespace only.< /p>
252 * <p/>
253 * <pre>
254 * StringUtils.isNotBlank(null) = false
255 * StringUtils.isNotBlank("") = false
256 * StringUtils.isNotBlank(" ") = false
257 * StringUtils.isNotBlank("bob") = true
258 * StringUtils.isNotBlank(" bob ") = true
259 * </pre>
260 *
261 * @param str the String to check, may be null
262 * @return <code>true</code> if the String is
263 * not empty and not null and not whitespace
264 * @since 2.0
265 */
266 public static boolean isNotBlank(String str)
267 {
268 return !StringUtils.isBlank(str);
269 }
270
271 // Trim
272 //-----------------------------------------------------------------------
273
274 /**
275 * <p>Removes control characters (char &lt;= 32) from both
276 * ends of this String, handling <code>null</code> by returning
277 * an empty String ("").</p>
278 * <p/>
279 * <pre>
280 * StringUtils.clean(null) = ""
281 * StringUtils.clean("") = ""
282 * StringUtils.clean("abc") = "abc"
283 * StringUtils.clean(" abc ") = "abc"
284 * StringUtils.clean(" ") = ""
285 * </pre>
286 *
287 * @param str the String to clean, may be null
288 * @return the trimmed text, never <code>null</code>
289 * @see java.lang.String#trim()
290 * @deprecated Use the clearer named {@link #trimToEmpty(String)}.
291 * Method will be removed in Commons Lang 3.0.
292 */
293 public static String clean(String str)
294 {
295 return str == null ? EMPTY : str.trim();
296 }
297
298 /**
299 * <p>Removes control characters (char &lt;= 32) from both
300 * ends of this String, handling <code>null</code> by returning
301 * <code>null</code>.</p>
302 * <p/>
303 * <p>The String is trimmed using {@link String#trim()}.
304 * Trim removes start and end characters &lt;= 32.
305 * To strip whitespace use {@link #strip(String)}.</p>
306 * <p/>
307 * <p>To trim your choice of characters, use the
308 * {@link #strip(String, String)} methods.</p>
309 * <p/>
310 * <pre>
311 * StringUtils.trim(null) = null
312 * StringUtils.trim("") = ""
313 * StringUtils.trim(" ") = ""
314 * StringUtils.trim("abc") = "abc"
315 * StringUtils.trim(" abc ") = "abc"
316 * </pre>
317 *
318 * @param str the String to be trimmed, may be null
319 * @return the trimmed string, <code>null</code> if null String input
320 */
321 public static String trim(String str)
322 {
323 return str == null ? null : str.trim();
324 }
325
326 /**
327 * <p>Removes control characters (char &lt;= 32) from both
328 * ends of this String returning <code>null</code> if the String is
329 * empty ("") after the trim or if it is <code>null</code>.
330 * <p/>
331 * <p>The String is trimmed using {@link String#trim()}.
332 * Trim removes start and end characters &lt;= 32.
333 * To strip whitespace use {@link #stripToNull(String)}.</p>
334 * <p/>
335 * <pre>
336 * StringUtils.trimToNull(null) = null
337 * StringUtils.trimToNull("") = null
338 * StringUtils.trimToNull(" ") = null
339 * StringUtils.trimToNull("abc") = "abc"
340 * StringUtils.trimToNull(" abc ") = "abc"
341 * </pre>
342 *
343 * @param str the String to be trimmed, may be null
344 * @return the trimmed String,
345 * <code>null</code> if only chars &lt;= 32, empty or null String input
346 * @since 2.0
347 */
348 public static String trimToNull(String str)
349 {
350 String ts = trim(str);
351 return isEmpty(ts) ? null : ts;
352 }
353
354 /**
355 * <p>Removes control characters (char &lt;= 32) from both
356 * ends of this String returning an empty String ("") if the String
357 * is empty ("") after the trim or if it is <code>null</code>.
358 * <p/>
359 * <p>The String is trimmed using {@link String#trim()}.
360 * Trim removes start and end characters &lt;= 32.
361 * To strip whitespace use {@link #stripToEmpty(String)}.</p>
362 * <p/>
363 * <pre>
364 * StringUtils.trimToEmpty(null) = ""
365 * StringUtils.trimToEmpty("") = ""
366 * StringUtils.trimToEmpty(" ") = ""
367 * StringUtils.trimToEmpty("abc") = "abc"
368 * StringUtils.trimToEmpty(" abc ") = "abc"
369 * </pre>
370 *
371 * @param str the String to be trimmed, may be null
372 * @return the trimmed String, or an empty String if <code>null</code> input
373 * @since 2.0
374 */
375 public static String trimToEmpty(String str)
376 {
377 return str == null ? EMPTY : str.trim();
378 }
379
380 // Stripping
381 //-----------------------------------------------------------------------
382
383 /**
384 * <p>Strips whitespace from the start and end of a String.</p>
385 * <p/>
386 * <p>This is similar to {@link #trim(String)} but removes whitespace.
387 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
388 * <p/>
389 * <p>A <code>null</code> input String returns <code>null</code>.</p>
390 * <p/>
391 * <pre>
392 * StringUtils.strip(null) = null
393 * StringUtils.strip("") = ""
394 * StringUtils.strip(" ") = ""
395 * StringUtils.strip("abc") = "abc"
396 * StringUtils.strip(" abc") = "abc"
397 * StringUtils.strip("abc ") = "abc"
398 * StringUtils.strip(" abc ") = "abc"
399 * StringUtils.strip(" ab c ") = "ab c"
400 * </pre>
401 *
402 * @param str the String to remove whitespace from, may be null
403 * @return the stripped String, <code>null</code> if null String input
404 */
405 public static String strip(String str)
406 {
407 return strip(str, null);
408 }
409
410 /**
411 * <p>Strips whitespace from the start and end of a String returning
412 * <code>null</code> if the String is empty ("") after the strip.</p>
413 * <p/>
414 * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.
415 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
416 * <p/>
417 * <pre>
418 * StringUtils.stripToNull(null) = null
419 * StringUtils.stripToNull("") = null
420 * StringUtils.stripToNull(" ") = null
421 * StringUtils.stripToNull("abc") = "abc"
422 * StringUtils.stripToNull(" abc") = "abc"
423 * StringUtils.stripToNull("abc ") = "abc"
424 * StringUtils.stripToNull(" abc ") = "abc"
425 * StringUtils.stripToNull(" ab c ") = "ab c"
426 * </pre>
427 *
428 * @param str the String to be stripped, may be null
429 * @return the stripped String,
430 * <code>null</code> if whitespace, empty or null String input
431 * @since 2.0
432 */
433 public static String stripToNull(String str)
434 {
435 if (str == null)
436 {
437 return null;
438 }
439 str = strip(str, null);
440 return str.length() == 0 ? null : str;
441 }
442
443 /**
444 * <p>Strips whitespace from the start and end of a String returning
445 * an empty String if <code>null</code> input.</p>
446 * <p/>
447 * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.
448 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
449 * <p/>
450 * <pre>
451 * StringUtils.stripToEmpty(null) = ""
452 * StringUtils.stripToEmpty("") = ""
453 * StringUtils.stripToEmpty(" ") = ""
454 * StringUtils.stripToEmpty("abc") = "abc"
455 * StringUtils.stripToEmpty(" abc") = "abc"
456 * StringUtils.stripToEmpty("abc ") = "abc"
457 * StringUtils.stripToEmpty(" abc ") = "abc"
458 * StringUtils.stripToEmpty(" ab c ") = "ab c"
459 * </pre>
460 *
461 * @param str the String to be stripped, may be null
462 * @return the trimmed String, or an empty String if <code>null</code> input
463 * @since 2.0
464 */
465 public static String stripToEmpty(String str)
466 {
467 return str == null ? EMPTY : strip(str, null);
468 }
469
470 /**
471 * <p>Strips any of a set of characters from the start and end of a String.
472 * This is similar to {@link String#trim()} but allows the characters
473 * to be stripped to be controlled.</p>
474 * <p/>
475 * <p>A <code>null</code> input String returns <code>null</code>.
476 * An empty string ("") input returns the empty string.</p>
477 * <p/>
478 * <p>If the stripChars String is <code>null</code>, whitespace is
479 * stripped as defined by {@link Character#isWhitespace(char)}.
480 * Alternatively use {@link #strip(String)}.</p>
481 * <p/>
482 * <pre>
483 * StringUtils.strip(null, *) = null
484 * StringUtils.strip("", *) = ""
485 * StringUtils.strip("abc", null) = "abc"
486 * StringUtils.strip(" abc", null) = "abc"
487 * StringUtils.strip("abc ", null) = "abc"
488 * StringUtils.strip(" abc ", null) = "abc"
489 * StringUtils.strip(" abcyx", "xyz") = " abc"
490 * </pre>
491 *
492 * @param str the String to remove characters from, may be null
493 * @param stripChars the characters to remove, null treated as whitespace
494 * @return the stripped String, <code>null</code> if null String input
495 */
496 public static String strip(String str, String stripChars)
497 {
498 if (isEmpty(str))
499 {
500 return str;
501 }
502 str = stripStart(str, stripChars);
503 return stripEnd(str, stripChars);
504 }
505
506 /**
507 * <p>Strips any of a set of characters from the start of a String.</p>
508 * <p/>
509 * <p>A <code>null</code> input String returns <code>null</code>.
510 * An empty string ("") input returns the empty string.</p>
511 * <p/>
512 * <p>If the stripChars String is <code>null</code>, whitespace is
513 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
514 * <p/>
515 * <pre>
516 * StringUtils.stripStart(null, *) = null
517 * StringUtils.stripStart("", *) = ""
518 * StringUtils.stripStart("abc", "") = "abc"
519 * StringUtils.stripStart("abc", null) = "abc"
520 * StringUtils.stripStart(" abc", null) = "abc"
521 * StringUtils.stripStart("abc ", null) = "abc "
522 * StringUtils.stripStart(" abc ", null) = "abc "
523 * StringUtils.stripStart("yxabc ", "xyz") = "abc "
524 * </pre>
525 *
526 * @param str the String to remove characters from, may be null
527 * @param stripChars the characters to remove, null treated as whitespace
528 * @return the stripped String, <code>null</code> if null String input
529 */
530 public static String stripStart(String str, String stripChars)
531 {
532 int strLen;
533 if (str == null || (strLen = str.length()) == 0)
534 {
535 return str;
536 }
537 int start = 0;
538 if (stripChars == null)
539 {
540 while ((start != strLen) && Character.isWhitespace(str.charAt(start)))
541 {
542 start++;
543 }
544 } else if (stripChars.length() == 0)
545 {
546 return str;
547 } else
548 {
549 while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1))
550 {
551 start++;
552 }
553 }
554 return str.substring(start);
555 }
556
557 /**
558 * <p>Strips any of a set of characters from the end of a String.</p>
559 * <p/>
560 * <p>A <code>null</code> input String returns <code>null</code>.
561 * An empty string ("") input returns the empty string.</p>
562 * <p/>
563 * <p>If the stripChars String is <code>null</code>, whitespace is
564 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
565 * <p/>
566 * <pre>
567 * StringUtils.stripEnd(null, *) = null
568 * StringUtils.stripEnd("", *) = ""
569 * StringUtils.stripEnd("abc", "") = "abc"
570 * StringUtils.stripEnd("abc", null) = "abc"
571 * StringUtils.stripEnd(" abc", null) = " abc"
572 * StringUtils.stripEnd("abc ", null) = "abc"
573 * StringUtils.stripEnd(" abc ", null) = " abc"
574 * StringUtils.stripEnd(" abcyx", "xyz") = " abc"
575 * </pre>
576 *
577 * @param str the String to remove characters from, may be null
578 * @param stripChars the characters to remove, null treated as whitespace
579 * @return the stripped String, <code>null</code> if null String input
580 */
581 public static String stripEnd(String str, String stripChars)
582 {
583 int end;
584 if (str == null || (end = str.length()) == 0)
585 {
586 return str;
587 }
588
589 if (stripChars == null)
590 {
591 while ((end != 0) && Character.isWhitespace(str.charAt(end - 1)))
592 {
593 end--;
594 }
595 } else if (stripChars.length() == 0)
596 {
597 return str;
598 } else
599 {
600 while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1))
601 {
602 end--;
603 }
604 }
605 return str.substring(0, end);
606 }
607
608 // StripAll
609 //-----------------------------------------------------------------------
610
611 /**
612 * <p>Strips whitespace from the start and end of every String in an array.
613 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
614 * <p/>
615 * <p>A new array is returned each time, except for length zero.
616 * A <code>null</code> array will return <code>null</code>.
617 * An empty array will return itself.
618 * A <code>null</code> array entry will be ignored.</p>
619 * <p/>
620 * <pre>
621 * StringUtils.stripAll(null) = null
622 * StringUtils.stripAll([]) = []
623 * StringUtils.stripAll(["abc", " abc"]) = ["abc", "abc"]
624 * StringUtils.stripAll(["abc ", null]) = ["abc", null]
625 * </pre>
626 *
627 * @param strs the array to remove whitespace from, may be null
628 * @return the stripped Strings, <code>null</code> if null array input
629 */
630 public static String[] stripAll(String[] strs)
631 {
632 return stripAll(strs, null);
633 }
634
635 /**
636 * <p>Strips any of a set of characters from the start and end of every
637 * String in an array.</p>
638 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
639 * <p/>
640 * <p>A new array is returned each time, except for length zero.
641 * A <code>null</code> array will return <code>null</code>.
642 * An empty array will return itself.
643 * A <code>null</code> array entry will be ignored.
644 * A <code>null</code> stripChars will strip whitespace as defined by
645 * {@link Character#isWhitespace(char)}.</p>
646 * <p/>
647 * <pre>
648 * StringUtils.stripAll(null, *) = null
649 * StringUtils.stripAll([], *) = []
650 * StringUtils.stripAll(["abc", " abc"], null) = ["abc", "abc"]
651 * StringUtils.stripAll(["abc ", null], null) = ["abc", null]
652 * StringUtils.stripAll(["abc ", null], "yz") = ["abc ", null]
653 * StringUtils.stripAll(["yabcz", null], "yz") = ["abc", null]
654 * </pre>
655 *
656 * @param strs the array to remove characters from, may be null
657 * @param stripChars the characters to remove, null treated as whitespace
658 * @return the stripped Strings, <code>null</code> if null array input
659 */
660 public static String[] stripAll(String[] strs, String stripChars)
661 {
662 int strsLen;
663 if (strs == null || (strsLen = strs.length) == 0)
664 {
665 return strs;
666 }
667 String[] newArr = new String[strsLen];
668 for (int i = 0; i < strsLen; i++)
669 {
670 newArr[i] = strip(strs[i], stripChars);
671 }
672 return newArr;
673 }
674
675 // Equals
676 //-----------------------------------------------------------------------
677
678 /**
679 * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
680 * <p/>
681 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
682 * references are considered to be equal. The comparison is case sensitive.</p >
683 * <p/>
684 * <pre>
685 * StringUtils.equals(null, null) = true
686 * StringUtils.equals(null, "abc") = false
687 * StringUtils.equals("abc", null) = false
688 * StringUtils.equals("abc", "abc") = true
689 * StringUtils.equals("abc", "ABC") = false
690 * </pre>
691 *
692 * @param str1 the first String, may be null
693 * @param str2 the second String, may be null
694 * @return <code>true</code> if the Strings are equal, case sensitive, or
695 * both <code>null</code>
696 * @see java.lang.String#equals(Object)
697 */
698 public static boolean equals(String str1, String str2)
699 {
700 return str1 == null ? str2 == null : str1.equals(str2);
701 }
702
703 /**
704 * <p>Compares two Strings, returning <code>true</code> if they are equal igno ring
705 * the case.</p>
706 * <p/>
707 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
708 * references are considered equal. Comparison is case insensitive.</p>
709 * <p/>
710 * <pre>
711 * StringUtils.equalsIgnoreCase(null, null) = true
712 * StringUtils.equalsIgnoreCase(null, "abc") = false
713 * StringUtils.equalsIgnoreCase("abc", null) = false
714 * StringUtils.equalsIgnoreCase("abc", "abc") = true
715 * StringUtils.equalsIgnoreCase("abc", "ABC") = true
716 * </pre>
717 *
718 * @param str1 the first String, may be null
719 * @param str2 the second String, may be null
720 * @return <code>true</code> if the Strings are equal, case insensitive, or
721 * both <code>null</code>
722 * @see java.lang.String#equalsIgnoreCase(String)
723 */
724 public static boolean equalsIgnoreCase(String str1, String str2)
725 {
726 return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
727 }
728
729 // IndexOf
730 //-----------------------------------------------------------------------
731
732 /**
733 * <p>Finds the first index within a String, handling <code>null</code>.
734 * This method uses {@link String#indexOf(int)}.</p>
735 * <p/>
736 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p >
737 * <p/>
738 * <pre>
739 * StringUtils.indexOf(null, *) = -1
740 * StringUtils.indexOf("", *) = -1
741 * StringUtils.indexOf("aabaabaa", 'a') = 0
742 * StringUtils.indexOf("aabaabaa", 'b') = 2
743 * </pre>
744 *
745 * @param str the String to check, may be null
746 * @param searchChar the character to find
747 * @return the first index of the search character,
748 * -1 if no match or <code>null</code> string input
749 * @since 2.0
750 */
751 public static int indexOf(String str, char searchChar)
752 {
753 if (isEmpty(str))
754 {
755 return -1;
756 }
757 return str.indexOf(searchChar);
758 }
759
760 /**
761 * <p>Finds the first index within a String from a start position,
762 * handling <code>null</code>.
763 * This method uses {@link String#indexOf(int, int)}.</p>
764 * <p/>
765 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
766 * A negative start position is treated as zero.
767 * A start position greater than the string length returns <code>-1</code>.</p >
768 * <p/>
769 * <pre>
770 * StringUtils.indexOf(null, *, *) = -1
771 * StringUtils.indexOf("", *, *) = -1
772 * StringUtils.indexOf("aabaabaa", 'b', 0) = 2
773 * StringUtils.indexOf("aabaabaa", 'b', 3) = 5
774 * StringUtils.indexOf("aabaabaa", 'b', 9) = -1
775 * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
776 * </pre>
777 *
778 * @param str the String to check, may be null
779 * @param searchChar the character to find
780 * @param startPos the start position, negative treated as zero
781 * @return the first index of the search character,
782 * -1 if no match or <code>null</code> string input
783 * @since 2.0
784 */
785 public static int indexOf(String str, char searchChar, int startPos)
786 {
787 if (isEmpty(str))
788 {
789 return -1;
790 }
791 return str.indexOf(searchChar, startPos);
792 }
793
794 /**
795 * <p>Finds the first index within a String, handling <code>null</code>.
796 * This method uses {@link String#indexOf(String)}.</p>
797 * <p/>
798 * <p>A <code>null</code> String will return <code>-1</code>.</p>
799 * <p/>
800 * <pre>
801 * StringUtils.indexOf(null, *) = -1
802 * StringUtils.indexOf(*, null) = -1
803 * StringUtils.indexOf("", "") = 0
804 * StringUtils.indexOf("aabaabaa", "a") = 0
805 * StringUtils.indexOf("aabaabaa", "b") = 2
806 * StringUtils.indexOf("aabaabaa", "ab") = 1
807 * StringUtils.indexOf("aabaabaa", "") = 0
808 * </pre>
809 *
810 * @param str the String to check, may be null
811 * @param searchStr the String to find, may be null
812 * @return the first index of the search String,
813 * -1 if no match or <code>null</code> string input
814 * @since 2.0
815 */
816 public static int indexOf(String str, String searchStr)
817 {
818 if (str == null || searchStr == null)
819 {
820 return -1;
821 }
822 return str.indexOf(searchStr);
823 }
824
825 /**
826 * <p>Finds the n-th index within a String, handling <code>null</code>.
827 * This method uses {@link String#indexOf(String)}.</p>
828 * <p/>
829 * <p>A <code>null</code> String will return <code>-1</code>.</p>
830 * <p/>
831 * <pre>
832 * StringUtils.ordinalIndexOf(null, *, *) = -1
833 * StringUtils.ordinalIndexOf(*, null, *) = -1
834 * StringUtils.ordinalIndexOf("", "", *) = 0
835 * StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0
836 * StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1
837 * StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2
838 * StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5
839 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
840 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
841 * StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0
842 * StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0
843 * </pre>
844 *
845 * @param str the String to check, may be null
846 * @param searchStr the String to find, may be null
847 * @param ordinal the n-th <code>searchStr</code> to find
848 * @return the n-th index of the search String,
849 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</c ode> string input
850 * @since 2.1
851 */
852 public static int ordinalIndexOf(String str, String searchStr, int ordinal)
853 {
854 if (str == null || searchStr == null || ordinal <= 0)
855 {
856 return INDEX_NOT_FOUND;
857 }
858 if (searchStr.length() == 0)
859 {
860 return 0;
861 }
862 int found = 0;
863 int index = INDEX_NOT_FOUND;
864 do
865 {
866 index = str.indexOf(searchStr, index + 1);
867 if (index < 0)
868 {
869 return index;
870 }
871 found++;
872 } while (found < ordinal);
873 return index;
874 }
875
876 /**
877 * <p>Finds the first index within a String, handling <code>null</code>.
878 * This method uses {@link String#indexOf(String, int)}.</p>
879 * <p/>
880 * <p>A <code>null</code> String will return <code>-1</code>.
881 * A negative start position is treated as zero.
882 * An empty ("") search String always matches.
883 * A start position greater than the string length only matches
884 * an empty search String.</p>
885 * <p/>
886 * <pre>
887 * StringUtils.indexOf(null, *, *) = -1
888 * StringUtils.indexOf(*, null, *) = -1
889 * StringUtils.indexOf("", "", 0) = 0
890 * StringUtils.indexOf("aabaabaa", "a", 0) = 0
891 * StringUtils.indexOf("aabaabaa", "b", 0) = 2
892 * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
893 * StringUtils.indexOf("aabaabaa", "b", 3) = 5
894 * StringUtils.indexOf("aabaabaa", "b", 9) = -1
895 * StringUtils.indexOf("aabaabaa", "b", -1) = 2
896 * StringUtils.indexOf("aabaabaa", "", 2) = 2
897 * StringUtils.indexOf("abc", "", 9) = 3
898 * </pre>
899 *
900 * @param str the String to check, may be null
901 * @param searchStr the String to find, may be null
902 * @param startPos the start position, negative treated as zero
903 * @return the first index of the search String,
904 * -1 if no match or <code>null</code> string input
905 * @since 2.0
906 */
907 public static int indexOf(String str, String searchStr, int startPos)
908 {
909 if (str == null || searchStr == null)
910 {
911 return -1;
912 }
913 // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence
914 if (searchStr.length() == 0 && startPos >= str.length())
915 {
916 return str.length();
917 }
918 return str.indexOf(searchStr, startPos);
919 }
920
921 // LastIndexOf
922 //-----------------------------------------------------------------------
923
924 /**
925 * <p>Finds the last index within a String, handling <code>null</code>.
926 * This method uses {@link String#lastIndexOf(int)}.</p>
927 * <p/>
928 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p >
929 * <p/>
930 * <pre>
931 * StringUtils.lastIndexOf(null, *) = -1
932 * StringUtils.lastIndexOf("", *) = -1
933 * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
934 * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
935 * </pre>
936 *
937 * @param str the String to check, may be null
938 * @param searchChar the character to find
939 * @return the last index of the search character,
940 * -1 if no match or <code>null</code> string input
941 * @since 2.0
942 */
943 public static int lastIndexOf(String str, char searchChar)
944 {
945 if (isEmpty(str))
946 {
947 return -1;
948 }
949 return str.lastIndexOf(searchChar);
950 }
951
952 /**
953 * <p>Finds the last index within a String from a start position,
954 * handling <code>null</code>.
955 * This method uses {@link String#lastIndexOf(int, int)}.</p>
956 * <p/>
957 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
958 * A negative start position returns <code>-1</code>.
959 * A start position greater than the string length searches the whole string.< /p>
960 * <p/>
961 * <pre>
962 * StringUtils.lastIndexOf(null, *, *) = -1
963 * StringUtils.lastIndexOf("", *, *) = -1
964 * StringUtils.lastIndexOf("aabaabaa", 'b', 8) = 5
965 * StringUtils.lastIndexOf("aabaabaa", 'b', 4) = 2
966 * StringUtils.lastIndexOf("aabaabaa", 'b', 0) = -1
967 * StringUtils.lastIndexOf("aabaabaa", 'b', 9) = 5
968 * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
969 * StringUtils.lastIndexOf("aabaabaa", 'a', 0) = 0
970 * </pre>
971 *
972 * @param str the String to check, may be null
973 * @param searchChar the character to find
974 * @param startPos the start position
975 * @return the last index of the search character,
976 * -1 if no match or <code>null</code> string input
977 * @since 2.0
978 */
979 public static int lastIndexOf(String str, char searchChar, int startPos)
980 {
981 if (isEmpty(str))
982 {
983 return -1;
984 }
985 return str.lastIndexOf(searchChar, startPos);
986 }
987
988 /**
989 * <p>Finds the last index within a String, handling <code>null</code>.
990 * This method uses {@link String#lastIndexOf(String)}.</p>
991 * <p/>
992 * <p>A <code>null</code> String will return <code>-1</code>.</p>
993 * <p/>
994 * <pre>
995 * StringUtils.lastIndexOf(null, *) = -1
996 * StringUtils.lastIndexOf(*, null) = -1
997 * StringUtils.lastIndexOf("", "") = 0
998 * StringUtils.lastIndexOf("aabaabaa", "a") = 0
999 * StringUtils.lastIndexOf("aabaabaa", "b") = 2
1000 * StringUtils.lastIndexOf("aabaabaa", "ab") = 1
1001 * StringUtils.lastIndexOf("aabaabaa", "") = 8
1002 * </pre>
1003 *
1004 * @param str the String to check, may be null
1005 * @param searchStr the String to find, may be null
1006 * @return the last index of the search String,
1007 * -1 if no match or <code>null</code> string input
1008 * @since 2.0
1009 */
1010 public static int lastIndexOf(String str, String searchStr)
1011 {
1012 if (str == null || searchStr == null)
1013 {
1014 return -1;
1015 }
1016 return str.lastIndexOf(searchStr);
1017 }
1018
1019 /**
1020 * <p>Finds the first index within a String, handling <code>null</code>.
1021 * This method uses {@link String#lastIndexOf(String, int)}.</p>
1022 * <p/>
1023 * <p>A <code>null</code> String will return <code>-1</code>.
1024 * A negative start position returns <code>-1</code>.
1025 * An empty ("") search String always matches unless the start position is neg ative.
1026 * A start position greater than the string length searches the whole string.< /p>
1027 * <p/>
1028 * <pre>
1029 * StringUtils.lastIndexOf(null, *, *) = -1
1030 * StringUtils.lastIndexOf(*, null, *) = -1
1031 * StringUtils.lastIndexOf("aabaabaa", "a", 8) = 7
1032 * StringUtils.lastIndexOf("aabaabaa", "b", 8) = 5
1033 * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
1034 * StringUtils.lastIndexOf("aabaabaa", "b", 9) = 5
1035 * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
1036 * StringUtils.lastIndexOf("aabaabaa", "a", 0) = 0
1037 * StringUtils.lastIndexOf("aabaabaa", "b", 0) = -1
1038 * </pre>
1039 *
1040 * @param str the String to check, may be null
1041 * @param searchStr the String to find, may be null
1042 * @param startPos the start position, negative treated as zero
1043 * @return the first index of the search String,
1044 * -1 if no match or <code>null</code> string input
1045 * @since 2.0
1046 */
1047 public static int lastIndexOf(String str, String searchStr, int startPos)
1048 {
1049 if (str == null || searchStr == null)
1050 {
1051 return -1;
1052 }
1053 return str.lastIndexOf(searchStr, startPos);
1054 }
1055
1056 // Contains
1057 //-----------------------------------------------------------------------
1058
1059 /**
1060 * <p>Checks if String contains a search character, handling <code>null</code> .
1061 * This method uses {@link String#indexOf(int)}.</p>
1062 * <p/>
1063 * <p>A <code>null</code> or empty ("") String will return <code>false</code>. </p>
1064 * <p/>
1065 * <pre>
1066 * StringUtils.contains(null, *) = false
1067 * StringUtils.contains("", *) = false
1068 * StringUtils.contains("abc", 'a') = true
1069 * StringUtils.contains("abc", 'z') = false
1070 * </pre>
1071 *
1072 * @param str the String to check, may be null
1073 * @param searchChar the character to find
1074 * @return true if the String contains the search character,
1075 * false if not or <code>null</code> string input
1076 * @since 2.0
1077 */
1078 public static boolean contains(String str, char searchChar)
1079 {
1080 if (isEmpty(str))
1081 {
1082 return false;
1083 }
1084 return str.indexOf(searchChar) >= 0;
1085 }
1086
1087 /**
1088 * <p>Checks if String contains a search String, handling <code>null</code>.
1089 * This method uses {@link String#indexOf(String)}.</p>
1090 * <p/>
1091 * <p>A <code>null</code> String will return <code>false</code>.</p>
1092 * <p/>
1093 * <pre>
1094 * StringUtils.contains(null, *) = false
1095 * StringUtils.contains(*, null) = false
1096 * StringUtils.contains("", "") = true
1097 * StringUtils.contains("abc", "") = true
1098 * StringUtils.contains("abc", "a") = true
1099 * StringUtils.contains("abc", "z") = false
1100 * </pre>
1101 *
1102 * @param str the String to check, may be null
1103 * @param searchStr the String to find, may be null
1104 * @return true if the String contains the search String,
1105 * false if not or <code>null</code> string input
1106 * @since 2.0
1107 */
1108 public static boolean contains(String str, String searchStr)
1109 {
1110 if (str == null || searchStr == null)
1111 {
1112 return false;
1113 }
1114 return str.indexOf(searchStr) >= 0;
1115 }
1116
1117 /**
1118 * <p>Checks if String contains a search String irrespective of case,
1119 * handling <code>null</code>. This method uses
1120 * {@link #contains(String, String)}.</p>
1121 * <p/>
1122 * <p>A <code>null</code> String will return <code>false</code>.</p>
1123 * <p/>
1124 * <pre>
1125 * StringUtils.contains(null, *) = false
1126 * StringUtils.contains(*, null) = false
1127 * StringUtils.contains("", "") = true
1128 * StringUtils.contains("abc", "") = true
1129 * StringUtils.contains("abc", "a") = true
1130 * StringUtils.contains("abc", "z") = false
1131 * StringUtils.contains("abc", "A") = true
1132 * StringUtils.contains("abc", "Z") = false
1133 * </pre>
1134 *
1135 * @param str the String to check, may be null
1136 * @param searchStr the String to find, may be null
1137 * @return true if the String contains the search String irrespective of
1138 * case or false if not or <code>null</code> string input
1139 */
1140 public static boolean containsIgnoreCase(String str, String searchStr)
1141 {
1142 if (str == null || searchStr == null)
1143 {
1144 return false;
1145 }
1146 return contains(str.toUpperCase(), searchStr.toUpperCase());
1147 }
1148
1149 // ContainsAny
1150 //-----------------------------------------------------------------------
1151
1152 /**
1153 * <p>Checks if the String contains any character in the given
1154 * set of characters.</p>
1155 * <p/>
1156 * <p>A <code>null</code> String will return <code>false</code>.
1157 * A <code>null</code> or zero length search array will return <code>false</co de>.</p>
1158 * <p/>
1159 * <pre>
1160 * StringUtils.containsAny(null, *) = false
1161 * StringUtils.containsAny("", *) = false
1162 * StringUtils.containsAny(*, null) = false
1163 * StringUtils.containsAny(*, []) = false
1164 * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
1165 * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
1166 * StringUtils.containsAny("aba", ['z']) = false
1167 * </pre>
1168 *
1169 * @param str the String to check, may be null
1170 * @param searchChars the chars to search for, may be null
1171 * @return the <code>true</code> if any of the chars are found,
1172 * <code>false</code> if no match or null input
1173 * @since 2.4
1174 */
1175 public static boolean containsAny(String str, char[] searchChars)
1176 {
1177 if (str == null || str.length() == 0 || searchChars == null || searchChars.l ength == 0)
1178 {
1179 return false;
1180 }
1181 for (int i = 0; i < str.length(); i++)
1182 {
1183 char ch = str.charAt(i);
1184 for (int j = 0; j < searchChars.length; j++)
1185 {
1186 if (searchChars[j] == ch)
1187 {
1188 return true;
1189 }
1190 }
1191 }
1192 return false;
1193 }
1194
1195 /**
1196 * <p>
1197 * Checks if the String contains any character in the given set of characters.
1198 * </p>
1199 * <p/>
1200 * <p>
1201 * A <code>null</code> String will return <code>false</code>. A <code>null</co de> search string will return
1202 * <code>false</code>.
1203 * </p>
1204 * <p/>
1205 * <pre>
1206 * StringUtils.containsAny(null, *) = false
1207 * StringUtils.containsAny("", *) = false
1208 * StringUtils.containsAny(*, null) = false
1209 * StringUtils.containsAny(*, "") = false
1210 * StringUtils.containsAny("zzabyycdxx", "za") = true
1211 * StringUtils.containsAny("zzabyycdxx", "by") = true
1212 * StringUtils.containsAny("aba","z") = false
1213 * </pre>
1214 *
1215 * @param str the String to check, may be null
1216 * @param searchChars the chars to search for, may be null
1217 * @return the <code>true</code> if any of the chars are found, <code>false</c ode> if no match or null input
1218 * @since 2.4
1219 */
1220 public static boolean containsAny(String str, String searchChars)
1221 {
1222 if (searchChars == null)
1223 {
1224 return false;
1225 }
1226 return containsAny(str, searchChars.toCharArray());
1227 }
1228
1229 /**
1230 * <p>Search a String to find the first index of any
1231 * character not in the given set of characters.</p>
1232 * <p/>
1233 * <p>A <code>null</code> String will return <code>-1</code>.
1234 * A <code>null</code> search string will return <code>-1</code>.</p>
1235 * <p/>
1236 * <pre>
1237 * StringUtils.indexOfAnyBut(null, *) = -1
1238 * StringUtils.indexOfAnyBut("", *) = -1
1239 * StringUtils.indexOfAnyBut(*, null) = -1
1240 * StringUtils.indexOfAnyBut(*, "") = -1
1241 * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
1242 * StringUtils.indexOfAnyBut("zzabyycdxx", "") = 0
1243 * StringUtils.indexOfAnyBut("aba","ab") = -1
1244 * </pre>
1245 *
1246 * @param str the String to check, may be null
1247 * @param searchChars the chars to search for, may be null
1248 * @return the index of any of the chars, -1 if no match or null input
1249 * @since 2.0
1250 */
1251 public static int indexOfAnyBut(String str, String searchChars)
1252 {
1253 if (isEmpty(str) || isEmpty(searchChars))
1254 {
1255 return -1;
1256 }
1257 for (int i = 0; i < str.length(); i++)
1258 {
1259 if (searchChars.indexOf(str.charAt(i)) < 0)
1260 {
1261 return i;
1262 }
1263 }
1264 return -1;
1265 }
1266
1267 // ContainsNone
1268 //-----------------------------------------------------------------------
1269
1270 /**
1271 * <p>Checks that the String does not contain certain characters.</p>
1272 * <p/>
1273 * <p>A <code>null</code> String will return <code>true</code>.
1274 * A <code>null</code> invalid character array will return <code>true</code>.
1275 * An empty String ("") always returns true.</p>
1276 * <p/>
1277 * <pre>
1278 * StringUtils.containsNone(null, *) = true
1279 * StringUtils.containsNone(*, null) = true
1280 * StringUtils.containsNone("", *) = true
1281 * StringUtils.containsNone("ab", '') = true
1282 * StringUtils.containsNone("abab", 'xyz') = true
1283 * StringUtils.containsNone("ab1", 'xyz') = true
1284 * StringUtils.containsNone("abz", 'xyz') = false
1285 * </pre>
1286 *
1287 * @param str the String to check, may be null
1288 * @param invalidChars an array of invalid chars, may be null
1289 * @return true if it contains none of the invalid chars, or is null
1290 * @since 2.0
1291 */
1292 public static boolean containsNone(String str, char[] invalidChars)
1293 {
1294 if (str == null || invalidChars == null)
1295 {
1296 return true;
1297 }
1298 int strSize = str.length();
1299 int validSize = invalidChars.length;
1300 for (int i = 0; i < strSize; i++)
1301 {
1302 char ch = str.charAt(i);
1303 for (int j = 0; j < validSize; j++)
1304 {
1305 if (invalidChars[j] == ch)
1306 {
1307 return false;
1308 }
1309 }
1310 }
1311 return true;
1312 }
1313
1314 /**
1315 * <p>Checks that the String does not contain certain characters.</p>
1316 * <p/>
1317 * <p>A <code>null</code> String will return <code>true</code>.
1318 * A <code>null</code> invalid character array will return <code>true</code>.
1319 * An empty String ("") always returns true.</p>
1320 * <p/>
1321 * <pre>
1322 * StringUtils.containsNone(null, *) = true
1323 * StringUtils.containsNone(*, null) = true
1324 * StringUtils.containsNone("", *) = true
1325 * StringUtils.containsNone("ab", "") = true
1326 * StringUtils.containsNone("abab", "xyz") = true
1327 * StringUtils.containsNone("ab1", "xyz") = true
1328 * StringUtils.containsNone("abz", "xyz") = false
1329 * </pre>
1330 *
1331 * @param str the String to check, may be null
1332 * @param invalidChars a String of invalid chars, may be null
1333 * @return true if it contains none of the invalid chars, or is null
1334 * @since 2.0
1335 */
1336 public static boolean containsNone(String str, String invalidChars)
1337 {
1338 if (str == null || invalidChars == null)
1339 {
1340 return true;
1341 }
1342 return containsNone(str, invalidChars.toCharArray());
1343 }
1344
1345 // IndexOfAny strings
1346 //-----------------------------------------------------------------------
1347
1348 /**
1349 * <p>Find the first index of any of a set of potential substrings.</p>
1350 * <p/>
1351 * <p>A <code>null</code> String will return <code>-1</code>.
1352 * A <code>null</code> or zero length search array will return <code>-1</code> .
1353 * A <code>null</code> search array entry will be ignored, but a search
1354 * array containing "" will return <code>0</code> if <code>str</code> is not
1355 * null. This method uses {@link String#indexOf(String)}.</p>
1356 * <p/>
1357 * <pre>
1358 * StringUtils.indexOfAny(null, *) = -1
1359 * StringUtils.indexOfAny(*, null) = -1
1360 * StringUtils.indexOfAny(*, []) = -1
1361 * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"]) = 2
1362 * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"]) = 2
1363 * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"]) = -1
1364 * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
1365 * StringUtils.indexOfAny("zzabyycdxx", [""]) = 0
1366 * StringUtils.indexOfAny("", [""]) = 0
1367 * StringUtils.indexOfAny("", ["a"]) = -1
1368 * </pre>
1369 *
1370 * @param str the String to check, may be null
1371 * @param searchStrs the Strings to search for, may be null
1372 * @return the first index of any of the searchStrs in str, -1 if no match
1373 */
1374 public static int indexOfAny(String str, String[] searchStrs)
1375 {
1376 if ((str == null) || (searchStrs == null))
1377 {
1378 return -1;
1379 }
1380 int sz = searchStrs.length;
1381
1382 // String's can't have a MAX_VALUEth index.
1383 int ret = Integer.MAX_VALUE;
1384
1385 int tmp = 0;
1386 for (int i = 0; i < sz; i++)
1387 {
1388 String search = searchStrs[i];
1389 if (search == null)
1390 {
1391 continue;
1392 }
1393 tmp = str.indexOf(search);
1394 if (tmp == -1)
1395 {
1396 continue;
1397 }
1398
1399 if (tmp < ret)
1400 {
1401 ret = tmp;
1402 }
1403 }
1404
1405 return (ret == Integer.MAX_VALUE) ? -1 : ret;
1406 }
1407
1408 /**
1409 * <p>Find the latest index of any of a set of potential substrings.</p>
1410 * <p/>
1411 * <p>A <code>null</code> String will return <code>-1</code>.
1412 * A <code>null</code> search array will return <code>-1</code>.
1413 * A <code>null</code> or zero length search array entry will be ignored,
1414 * but a search array containing "" will return the length of <code>str</code>
1415 * if <code>str</code> is not null. This method uses {@link String#indexOf(Str ing)}</p>
1416 * <p/>
1417 * <pre>
1418 * StringUtils.lastIndexOfAny(null, *) = -1
1419 * StringUtils.lastIndexOfAny(*, null) = -1
1420 * StringUtils.lastIndexOfAny(*, []) = -1
1421 * StringUtils.lastIndexOfAny(*, [null]) = -1
1422 * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
1423 * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
1424 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1425 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1426 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""]) = 10
1427 * </pre>
1428 *
1429 * @param str the String to check, may be null
1430 * @param searchStrs the Strings to search for, may be null
1431 * @return the last index of any of the Strings, -1 if no match
1432 */
1433 public static int lastIndexOfAny(String str, String[] searchStrs)
1434 {
1435 if ((str == null) || (searchStrs == null))
1436 {
1437 return -1;
1438 }
1439 int sz = searchStrs.length;
1440 int ret = -1;
1441 int tmp = 0;
1442 for (int i = 0; i < sz; i++)
1443 {
1444 String search = searchStrs[i];
1445 if (search == null)
1446 {
1447 continue;
1448 }
1449 tmp = str.lastIndexOf(search);
1450 if (tmp > ret)
1451 {
1452 ret = tmp;
1453 }
1454 }
1455 return ret;
1456 }
1457
1458 // Substring
1459 //-----------------------------------------------------------------------
1460
1461 /**
1462 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1463 * <p/>
1464 * <p>A negative start position can be used to start <code>n</code>
1465 * characters from the end of the String.</p>
1466 * <p/>
1467 * <p>A <code>null</code> String will return <code>null</code>.
1468 * An empty ("") String will return "".</p>
1469 * <p/>
1470 * <pre>
1471 * StringUtils.substring(null, *) = null
1472 * StringUtils.substring("", *) = ""
1473 * StringUtils.substring("abc", 0) = "abc"
1474 * StringUtils.substring("abc", 2) = "c"
1475 * StringUtils.substring("abc", 4) = ""
1476 * StringUtils.substring("abc", -2) = "bc"
1477 * StringUtils.substring("abc", -4) = "abc"
1478 * </pre>
1479 *
1480 * @param str the String to get the substring from, may be null
1481 * @param start the position to start from, negative means
1482 * count back from the end of the String by this many characters
1483 * @return substring from start position, <code>null</code> if null String inp ut
1484 */
1485 public static String substring(String str, int start)
1486 {
1487 if (str == null)
1488 {
1489 return null;
1490 }
1491
1492 // handle negatives, which means last n characters
1493 if (start < 0)
1494 {
1495 start = str.length() + start; // remember start is negative
1496 }
1497
1498 if (start < 0)
1499 {
1500 start = 0;
1501 }
1502 if (start > str.length())
1503 {
1504 return EMPTY;
1505 }
1506
1507 return str.substring(start);
1508 }
1509
1510 /**
1511 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1512 * <p/>
1513 * <p>A negative start position can be used to start/end <code>n</code>
1514 * characters from the end of the String.</p>
1515 * <p/>
1516 * <p>The returned substring starts with the character in the <code>start</cod e>
1517 * position and ends before the <code>end</code> position. All position counti ng is
1518 * zero-based -- i.e., to start at the beginning of the string use
1519 * <code>start = 0</code>. Negative start and end positions can be used to
1520 * specify offsets relative to the end of the String.</p>
1521 * <p/>
1522 * <p>If <code>start</code> is not strictly to the left of <code>end</code>, " "
1523 * is returned.</p>
1524 * <p/>
1525 * <pre>
1526 * StringUtils.substring(null, *, *) = null
1527 * StringUtils.substring("", * , *) = "";
1528 * StringUtils.substring("abc", 0, 2) = "ab"
1529 * StringUtils.substring("abc", 2, 0) = ""
1530 * StringUtils.substring("abc", 2, 4) = "c"
1531 * StringUtils.substring("abc", 4, 6) = ""
1532 * StringUtils.substring("abc", 2, 2) = ""
1533 * StringUtils.substring("abc", -2, -1) = "b"
1534 * StringUtils.substring("abc", -4, 2) = "ab"
1535 * </pre>
1536 *
1537 * @param str the String to get the substring from, may be null
1538 * @param start the position to start from, negative means
1539 * count back from the end of the String by this many characters
1540 * @param end the position to end at (exclusive), negative means
1541 * count back from the end of the String by this many characters
1542 * @return substring from start position to end positon,
1543 * <code>null</code> if null String input
1544 */
1545 public static String substring(String str, int start, int end)
1546 {
1547 if (str == null)
1548 {
1549 return null;
1550 }
1551
1552 // handle negatives
1553 if (end < 0)
1554 {
1555 end = str.length() + end; // remember end is negative
1556 }
1557 if (start < 0)
1558 {
1559 start = str.length() + start; // remember start is negative
1560 }
1561
1562 // check length next
1563 if (end > str.length())
1564 {
1565 end = str.length();
1566 }
1567
1568 // if start is greater than end, return ""
1569 if (start > end)
1570 {
1571 return EMPTY;
1572 }
1573
1574 if (start < 0)
1575 {
1576 start = 0;
1577 }
1578 if (end < 0)
1579 {
1580 end = 0;
1581 }
1582
1583 return str.substring(start, end);
1584 }
1585
1586 // Left/Right/Mid
1587 //-----------------------------------------------------------------------
1588
1589 /**
1590 * <p>Gets the leftmost <code>len</code> characters of a String.</p>
1591 * <p/>
1592 * <p>If <code>len</code> characters are not available, or the
1593 * String is <code>null</code>, the String will be returned without
1594 * an exception. An exception is thrown if len is negative.</p>
1595 * <p/>
1596 * <pre>
1597 * StringUtils.left(null, *) = null
1598 * StringUtils.left(*, -ve) = ""
1599 * StringUtils.left("", *) = ""
1600 * StringUtils.left("abc", 0) = ""
1601 * StringUtils.left("abc", 2) = "ab"
1602 * StringUtils.left("abc", 4) = "abc"
1603 * </pre>
1604 *
1605 * @param str the String to get the leftmost characters from, may be null
1606 * @param len the length of the required String, must be zero or positive
1607 * @return the leftmost characters, <code>null</code> if null String input
1608 */
1609 public static String left(String str, int len)
1610 {
1611 if (str == null)
1612 {
1613 return null;
1614 }
1615 if (len < 0)
1616 {
1617 return EMPTY;
1618 }
1619 if (str.length() <= len)
1620 {
1621 return str;
1622 }
1623 return str.substring(0, len);
1624 }
1625
1626 /**
1627 * <p>Gets the rightmost <code>len</code> characters of a String.</p>
1628 * <p/>
1629 * <p>If <code>len</code> characters are not available, or the String
1630 * is <code>null</code>, the String will be returned without an
1631 * an exception. An exception is thrown if len is negative.</p>
1632 * <p/>
1633 * <pre>
1634 * StringUtils.right(null, *) = null
1635 * StringUtils.right(*, -ve) = ""
1636 * StringUtils.right("", *) = ""
1637 * StringUtils.right("abc", 0) = ""
1638 * StringUtils.right("abc", 2) = "bc"
1639 * StringUtils.right("abc", 4) = "abc"
1640 * </pre>
1641 *
1642 * @param str the String to get the rightmost characters from, may be null
1643 * @param len the length of the required String, must be zero or positive
1644 * @return the rightmost characters, <code>null</code> if null String input
1645 */
1646 public static String right(String str, int len)
1647 {
1648 if (str == null)
1649 {
1650 return null;
1651 }
1652 if (len < 0)
1653 {
1654 return EMPTY;
1655 }
1656 if (str.length() <= len)
1657 {
1658 return str;
1659 }
1660 return str.substring(str.length() - len);
1661 }
1662
1663 /**
1664 * <p>Gets <code>len</code> characters from the middle of a String.</p>
1665 * <p/>
1666 * <p>If <code>len</code> characters are not available, the remainder
1667 * of the String will be returned without an exception. If the
1668 * String is <code>null</code>, <code>null</code> will be returned.
1669 * An exception is thrown if len is negative.</p>
1670 * <p/>
1671 * <pre>
1672 * StringUtils.mid(null, *, *) = null
1673 * StringUtils.mid(*, *, -ve) = ""
1674 * StringUtils.mid("", 0, *) = ""
1675 * StringUtils.mid("abc", 0, 2) = "ab"
1676 * StringUtils.mid("abc", 0, 4) = "abc"
1677 * StringUtils.mid("abc", 2, 4) = "c"
1678 * StringUtils.mid("abc", 4, 2) = ""
1679 * StringUtils.mid("abc", -2, 2) = "ab"
1680 * </pre>
1681 *
1682 * @param str the String to get the characters from, may be null
1683 * @param pos the position to start from, negative treated as zero
1684 * @param len the length of the required String, must be zero or positive
1685 * @return the middle characters, <code>null</code> if null String input
1686 */
1687 public static String mid(String str, int pos, int len)
1688 {
1689 if (str == null)
1690 {
1691 return null;
1692 }
1693 if (len < 0 || pos > str.length())
1694 {
1695 return EMPTY;
1696 }
1697 if (pos < 0)
1698 {
1699 pos = 0;
1700 }
1701 if (str.length() <= (pos + len))
1702 {
1703 return str.substring(pos);
1704 }
1705 return str.substring(pos, pos + len);
1706 }
1707
1708 // SubStringAfter/SubStringBefore
1709 //-----------------------------------------------------------------------
1710
1711 /**
1712 * <p>Gets the substring before the first occurrence of a separator.
1713 * The separator is not returned.</p>
1714 * <p/>
1715 * <p>A <code>null</code> string input will return <code>null</code>.
1716 * An empty ("") string input will return the empty string.
1717 * A <code>null</code> separator will return the input string.</p>
1718 * <p/>
1719 * <pre>
1720 * StringUtils.substringBefore(null, *) = null
1721 * StringUtils.substringBefore("", *) = ""
1722 * StringUtils.substringBefore("abc", "a") = ""
1723 * StringUtils.substringBefore("abcba", "b") = "a"
1724 * StringUtils.substringBefore("abc", "c") = "ab"
1725 * StringUtils.substringBefore("abc", "d") = "abc"
1726 * StringUtils.substringBefore("abc", "") = ""
1727 * StringUtils.substringBefore("abc", null) = "abc"
1728 * </pre>
1729 *
1730 * @param str the String to get a substring from, may be null
1731 * @param separator the String to search for, may be null
1732 * @return the substring before the first occurrence of the separator,
1733 * <code>null</code> if null String input
1734 * @since 2.0
1735 */
1736 public static String substringBefore(String str, String separator)
1737 {
1738 if (isEmpty(str) || separator == null)
1739 {
1740 return str;
1741 }
1742 if (separator.length() == 0)
1743 {
1744 return EMPTY;
1745 }
1746 int pos = str.indexOf(separator);
1747 if (pos == -1)
1748 {
1749 return str;
1750 }
1751 return str.substring(0, pos);
1752 }
1753
1754 /**
1755 * <p>Gets the substring after the first occurrence of a separator.
1756 * The separator is not returned.</p>
1757 * <p/>
1758 * <p>A <code>null</code> string input will return <code>null</code>.
1759 * An empty ("") string input will return the empty string.
1760 * A <code>null</code> separator will return the empty string if the
1761 * input string is not <code>null</code>.</p>
1762 * <p/>
1763 * <pre>
1764 * StringUtils.substringAfter(null, *) = null
1765 * StringUtils.substringAfter("", *) = ""
1766 * StringUtils.substringAfter(*, null) = ""
1767 * StringUtils.substringAfter("abc", "a") = "bc"
1768 * StringUtils.substringAfter("abcba", "b") = "cba"
1769 * StringUtils.substringAfter("abc", "c") = ""
1770 * StringUtils.substringAfter("abc", "d") = ""
1771 * StringUtils.substringAfter("abc", "") = "abc"
1772 * </pre>
1773 *
1774 * @param str the String to get a substring from, may be null
1775 * @param separator the String to search for, may be null
1776 * @return the substring after the first occurrence of the separator,
1777 * <code>null</code> if null String input
1778 * @since 2.0
1779 */
1780 public static String substringAfter(String str, String separator)
1781 {
1782 if (isEmpty(str))
1783 {
1784 return str;
1785 }
1786 if (separator == null)
1787 {
1788 return EMPTY;
1789 }
1790 int pos = str.indexOf(separator);
1791 if (pos == -1)
1792 {
1793 return EMPTY;
1794 }
1795 return str.substring(pos + separator.length());
1796 }
1797
1798 /**
1799 * <p>Gets the substring before the last occurrence of a separator.
1800 * The separator is not returned.</p>
1801 * <p/>
1802 * <p>A <code>null</code> string input will return <code>null</code>.
1803 * An empty ("") string input will return the empty string.
1804 * An empty or <code>null</code> separator will return the input string.</p>
1805 * <p/>
1806 * <pre>
1807 * StringUtils.substringBeforeLast(null, *) = null
1808 * StringUtils.substringBeforeLast("", *) = ""
1809 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
1810 * StringUtils.substringBeforeLast("abc", "c") = "ab"
1811 * StringUtils.substringBeforeLast("a", "a") = ""
1812 * StringUtils.substringBeforeLast("a", "z") = "a"
1813 * StringUtils.substringBeforeLast("a", null) = "a"
1814 * StringUtils.substringBeforeLast("a", "") = "a"
1815 * </pre>
1816 *
1817 * @param str the String to get a substring from, may be null
1818 * @param separator the String to search for, may be null
1819 * @return the substring before the last occurrence of the separator,
1820 * <code>null</code> if null String input
1821 * @since 2.0
1822 */
1823 public static String substringBeforeLast(String str, String separator)
1824 {
1825 if (isEmpty(str) || isEmpty(separator))
1826 {
1827 return str;
1828 }
1829 int pos = str.lastIndexOf(separator);
1830 if (pos == -1)
1831 {
1832 return str;
1833 }
1834 return str.substring(0, pos);
1835 }
1836
1837 /**
1838 * <p>Gets the substring after the last occurrence of a separator.
1839 * The separator is not returned.</p>
1840 * <p/>
1841 * <p>A <code>null</code> string input will return <code>null</code>.
1842 * An empty ("") string input will return the empty string.
1843 * An empty or <code>null</code> separator will return the empty string if
1844 * the input string is not <code>null</code>.</p>
1845 * <p/>
1846 * <pre>
1847 * StringUtils.substringAfterLast(null, *) = null
1848 * StringUtils.substringAfterLast("", *) = ""
1849 * StringUtils.substringAfterLast(*, "") = ""
1850 * StringUtils.substringAfterLast(*, null) = ""
1851 * StringUtils.substringAfterLast("abc", "a") = "bc"
1852 * StringUtils.substringAfterLast("abcba", "b") = "a"
1853 * StringUtils.substringAfterLast("abc", "c") = ""
1854 * StringUtils.substringAfterLast("a", "a") = ""
1855 * StringUtils.substringAfterLast("a", "z") = ""
1856 * </pre>
1857 *
1858 * @param str the String to get a substring from, may be null
1859 * @param separator the String to search for, may be null
1860 * @return the substring after the last occurrence of the separator,
1861 * <code>null</code> if null String input
1862 * @since 2.0
1863 */
1864 public static String substringAfterLast(String str, String separator)
1865 {
1866 if (isEmpty(str))
1867 {
1868 return str;
1869 }
1870 if (isEmpty(separator))
1871 {
1872 return EMPTY;
1873 }
1874 int pos = str.lastIndexOf(separator);
1875 if (pos == -1 || pos == (str.length() - separator.length()))
1876 {
1877 return EMPTY;
1878 }
1879 return str.substring(pos + separator.length());
1880 }
1881
1882 // Substring between
1883 //-----------------------------------------------------------------------
1884
1885 /**
1886 * <p>Gets the String that is nested in between two instances of the
1887 * same String.</p>
1888 * <p/>
1889 * <p>A <code>null</code> input String returns <code>null</code>.
1890 * A <code>null</code> tag returns <code>null</code>.</p>
1891 * <p/>
1892 * <pre>
1893 * StringUtils.substringBetween(null, *) = null
1894 * StringUtils.substringBetween("", "") = ""
1895 * StringUtils.substringBetween("", "tag") = null
1896 * StringUtils.substringBetween("tagabctag", null) = null
1897 * StringUtils.substringBetween("tagabctag", "") = ""
1898 * StringUtils.substringBetween("tagabctag", "tag") = "abc"
1899 * </pre>
1900 *
1901 * @param str the String containing the substring, may be null
1902 * @param tag the String before and after the substring, may be null
1903 * @return the substring, <code>null</code> if no match
1904 * @since 2.0
1905 */
1906 public static String substringBetween(String str, String tag)
1907 {
1908 return substringBetween(str, tag, tag);
1909 }
1910
1911 /**
1912 * <p>Gets the String that is nested in between two Strings.
1913 * Only the first match is returned.</p>
1914 * <p/>
1915 * <p>A <code>null</code> input String returns <code>null</code>.
1916 * A <code>null</code> open/close returns <code>null</code> (no match).
1917 * An empty ("") open and close returns an empty string.</p>
1918 * <p/>
1919 * <pre>
1920 * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
1921 * StringUtils.substringBetween(null, *, *) = null
1922 * StringUtils.substringBetween(*, null, *) = null
1923 * StringUtils.substringBetween(*, *, null) = null
1924 * StringUtils.substringBetween("", "", "") = ""
1925 * StringUtils.substringBetween("", "", "]") = null
1926 * StringUtils.substringBetween("", "[", "]") = null
1927 * StringUtils.substringBetween("yabcz", "", "") = ""
1928 * StringUtils.substringBetween("yabcz", "y", "z") = "abc"
1929 * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc"
1930 * </pre>
1931 *
1932 * @param str the String containing the substring, may be null
1933 * @param open the String before the substring, may be null
1934 * @param close the String after the substring, may be null
1935 * @return the substring, <code>null</code> if no match
1936 * @since 2.0
1937 */
1938 public static String substringBetween(String str, String open, String close)
1939 {
1940 if (str == null || open == null || close == null)
1941 {
1942 return null;
1943 }
1944 int start = str.indexOf(open);
1945 if (start != -1)
1946 {
1947 int end = str.indexOf(close, start + open.length());
1948 if (end != -1)
1949 {
1950 return str.substring(start + open.length(), end);
1951 }
1952 }
1953 return null;
1954 }
1955
1956 // Joining
1957 //-----------------------------------------------------------------------
1958
1959 /**
1960 * <p>Concatenates elements of an array into a single String.
1961 * Null objects or empty strings within the array are represented by
1962 * empty strings.</p>
1963 * <p/>
1964 * <pre>
1965 * StringUtils.concatenate(null) = null
1966 * StringUtils.concatenate([]) = ""
1967 * StringUtils.concatenate([null]) = ""
1968 * StringUtils.concatenate(["a", "b", "c"]) = "abc"
1969 * StringUtils.concatenate([null, "", "a"]) = "a"
1970 * </pre>
1971 *
1972 * @param array the array of values to concatenate, may be null
1973 * @return the concatenated String, <code>null</code> if null array input
1974 * @deprecated Use the better named {@link #join(Object[])} instead.
1975 * Method will be removed in Commons Lang 3.0.
1976 */
1977 public static String concatenate(Object[] array)
1978 {
1979 return join(array, null);
1980 }
1981
1982 /**
1983 * <p>Joins the elements of the provided array into a single String
1984 * containing the provided list of elements.</p>
1985 * <p/>
1986 * <p>No separator is added to the joined String.
1987 * Null objects or empty strings within the array are represented by
1988 * empty strings.</p>
1989 * <p/>
1990 * <pre>
1991 * StringUtils.join(null) = null
1992 * StringUtils.join([]) = ""
1993 * StringUtils.join([null]) = ""
1994 * StringUtils.join(["a", "b", "c"]) = "abc"
1995 * StringUtils.join([null, "", "a"]) = "a"
1996 * </pre>
1997 *
1998 * @param array the array of values to join together, may be null
1999 * @return the joined String, <code>null</code> if null array input
2000 * @since 2.0
2001 */
2002 public static String join(Object[] array)
2003 {
2004 return join(array, null);
2005 }
2006
2007 /**
2008 * <p>Joins the elements of the provided array into a single String
2009 * containing the provided list of elements.</p>
2010 * <p/>
2011 * <p>No delimiter is added before or after the list.
2012 * Null objects or empty strings within the array are represented by
2013 * empty strings.</p>
2014 * <p/>
2015 * <pre>
2016 * StringUtils.join(null, *) = null
2017 * StringUtils.join([], *) = ""
2018 * StringUtils.join([null], *) = ""
2019 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
2020 * StringUtils.join(["a", "b", "c"], null) = "abc"
2021 * StringUtils.join([null, "", "a"], ';') = ";;a"
2022 * </pre>
2023 *
2024 * @param array the array of values to join together, may be null
2025 * @param separator the separator character to use
2026 * @return the joined String, <code>null</code> if null array input
2027 * @since 2.0
2028 */
2029 public static String join(Object[] array, char separator)
2030 {
2031 if (array == null)
2032 {
2033 return null;
2034 }
2035
2036 return join(array, separator, 0, array.length);
2037 }
2038
2039 /**
2040 * <p>Joins the elements of the provided array into a single String
2041 * containing the provided list of elements.</p>
2042 * <p/>
2043 * <p>No delimiter is added before or after the list.
2044 * Null objects or empty strings within the array are represented by
2045 * empty strings.</p>
2046 * <p/>
2047 * <pre>
2048 * StringUtils.join(null, *) = null
2049 * StringUtils.join([], *) = ""
2050 * StringUtils.join([null], *) = ""
2051 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
2052 * StringUtils.join(["a", "b", "c"], null) = "abc"
2053 * StringUtils.join([null, "", "a"], ';') = ";;a"
2054 * </pre>
2055 *
2056 * @param array the array of values to join together, may be null
2057 * @param separator the separator character to use
2058 * @param startIndex the first index to start joining from. It is
2059 * an error to pass in an end index past the end of the arra y
2060 * @param endIndex the index to stop joining from (exclusive). It is
2061 * an error to pass in an end index past the end of the arra y
2062 * @return the joined String, <code>null</code> if null array input
2063 * @since 2.0
2064 */
2065 public static String join(Object[] array, char separator, int startIndex, int endIndex)
2066 {
2067 if (array == null)
2068 {
2069 return null;
2070 }
2071 int bufSize = (endIndex - startIndex);
2072 if (bufSize <= 0)
2073 {
2074 return EMPTY;
2075 }
2076
2077 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().l ength()) + 1);
2078 StringBuffer buf = new StringBuffer(bufSize);
2079
2080 for (int i = startIndex; i < endIndex; i++)
2081 {
2082 if (i > startIndex)
2083 {
2084 buf.append(separator);
2085 }
2086 if (array[i] != null)
2087 {
2088 buf.append(array[i]);
2089 }
2090 }
2091 return buf.toString();
2092 }
2093
2094
2095 /**
2096 * <p>Joins the elements of the provided array into a single String
2097 * containing the provided list of elements.</p>
2098 * <p/>
2099 * <p>No delimiter is added before or after the list.
2100 * A <code>null</code> separator is the same as an empty String ("").
2101 * Null objects or empty strings within the array are represented by
2102 * empty strings.</p>
2103 * <p/>
2104 * <pre>
2105 * StringUtils.join(null, *) = null
2106 * StringUtils.join([], *) = ""
2107 * StringUtils.join([null], *) = ""
2108 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
2109 * StringUtils.join(["a", "b", "c"], null) = "abc"
2110 * StringUtils.join(["a", "b", "c"], "") = "abc"
2111 * StringUtils.join([null, "", "a"], ',') = ",,a"
2112 * </pre>
2113 *
2114 * @param array the array of values to join together, may be null
2115 * @param separator the separator character to use, null treated as ""
2116 * @return the joined String, <code>null</code> if null array input
2117 */
2118 public static String join(Object[] array, String separator)
2119 {
2120 if (array == null)
2121 {
2122 return null;
2123 }
2124 return join(array, separator, 0, array.length);
2125 }
2126
2127 /**
2128 * <p>Joins the elements of the provided array into a single String
2129 * containing the provided list of elements.</p>
2130 * <p/>
2131 * <p>No delimiter is added before or after the list.
2132 * A <code>null</code> separator is the same as an empty String ("").
2133 * Null objects or empty strings within the array are represented by
2134 * empty strings.</p>
2135 * <p/>
2136 * <pre>
2137 * StringUtils.join(null, *) = null
2138 * StringUtils.join([], *) = ""
2139 * StringUtils.join([null], *) = ""
2140 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
2141 * StringUtils.join(["a", "b", "c"], null) = "abc"
2142 * StringUtils.join(["a", "b", "c"], "") = "abc"
2143 * StringUtils.join([null, "", "a"], ',') = ",,a"
2144 * </pre>
2145 *
2146 * @param array the array of values to join together, may be null
2147 * @param separator the separator character to use, null treated as ""
2148 * @param startIndex the first index to start joining from. It is
2149 * an error to pass in an end index past the end of the arra y
2150 * @param endIndex the index to stop joining from (exclusive). It is
2151 * an error to pass in an end index past the end of the arra y
2152 * @return the joined String, <code>null</code> if null array input
2153 */
2154 public static String join(Object[] array, String separator, int startIndex, in t endIndex)
2155 {
2156 if (array == null)
2157 {
2158 return null;
2159 }
2160 if (separator == null)
2161 {
2162 separator = EMPTY;
2163 }
2164
2165 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(se parator))
2166 // (Assuming that all Strings are roughly equally long)
2167 int bufSize = (endIndex - startIndex);
2168 if (bufSize <= 0)
2169 {
2170 return EMPTY;
2171 }
2172
2173 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().l ength())
2174 + separator.length());
2175
2176 StringBuffer buf = new StringBuffer(bufSize);
2177
2178 for (int i = startIndex; i < endIndex; i++)
2179 {
2180 if (i > startIndex)
2181 {
2182 buf.append(separator);
2183 }
2184 if (array[i] != null)
2185 {
2186 buf.append(array[i]);
2187 }
2188 }
2189 return buf.toString();
2190 }
2191
2192 // Delete
2193 //-----------------------------------------------------------------------
2194
2195 /**
2196 * <p>Deletes all whitespaces from a String as defined by
2197 * {@link Character#isWhitespace(char)}.</p>
2198 * <p/>
2199 * <pre>
2200 * StringUtils.deleteWhitespace(null) = null
2201 * StringUtils.deleteWhitespace("") = ""
2202 * StringUtils.deleteWhitespace("abc") = "abc"
2203 * StringUtils.deleteWhitespace(" ab c ") = "abc"
2204 * </pre>
2205 *
2206 * @param str the String to delete whitespace from, may be null
2207 * @return the String without whitespaces, <code>null</code> if null String in put
2208 */
2209 public static String deleteWhitespace(String str)
2210 {
2211 if (isEmpty(str))
2212 {
2213 return str;
2214 }
2215 int sz = str.length();
2216 char[] chs = new char[sz];
2217 int count = 0;
2218 for (int i = 0; i < sz; i++)
2219 {
2220 if (!Character.isWhitespace(str.charAt(i)))
2221 {
2222 chs[count++] = str.charAt(i);
2223 }
2224 }
2225 if (count == sz)
2226 {
2227 return str;
2228 }
2229 return new String(chs, 0, count);
2230 }
2231
2232 // Remove
2233 //-----------------------------------------------------------------------
2234
2235 /**
2236 * <p>Removes a substring only if it is at the begining of a source string,
2237 * otherwise returns the source string.</p>
2238 * <p/>
2239 * <p>A <code>null</code> source string will return <code>null</code>.
2240 * An empty ("") source string will return the empty string.
2241 * A <code>null</code> search string will return the source string.</p>
2242 * <p/>
2243 * <pre>
2244 * StringUtils.removeStart(null, *) = null
2245 * StringUtils.removeStart("", *) = ""
2246 * StringUtils.removeStart(*, null) = *
2247 * StringUtils.removeStart("www.domain.com", "www.") = "domain.com"
2248 * StringUtils.removeStart("domain.com", "www.") = "domain.com"
2249 * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
2250 * StringUtils.removeStart("abc", "") = "abc"
2251 * </pre>
2252 *
2253 * @param str the source String to search, may be null
2254 * @param remove the String to search for and remove, may be null
2255 * @return the substring with the string removed if found,
2256 * <code>null</code> if null String input
2257 * @since 2.1
2258 */
2259 public static String removeStart(String str, String remove)
2260 {
2261 if (isEmpty(str) || isEmpty(remove))
2262 {
2263 return str;
2264 }
2265 if (str.startsWith(remove))
2266 {
2267 return str.substring(remove.length());
2268 }
2269 return str;
2270 }
2271
2272 /**
2273 * <p>Case insensitive removal of a substring if it is at the begining of a so urce string,
2274 * otherwise returns the source string.</p>
2275 * <p/>
2276 * <p>A <code>null</code> source string will return <code>null</code>.
2277 * An empty ("") source string will return the empty string.
2278 * A <code>null</code> search string will return the source string.</p>
2279 * <p/>
2280 * <pre>
2281 * StringUtils.removeStartIgnoreCase(null, *) = null
2282 * StringUtils.removeStartIgnoreCase("", *) = ""
2283 * StringUtils.removeStartIgnoreCase(*, null) = *
2284 * StringUtils.removeStartIgnoreCase("www.domain.com", "www.") = "domain.com "
2285 * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.") = "domain.com "
2286 * StringUtils.removeStartIgnoreCase("domain.com", "www.") = "domain.com "
2287 * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain .com"
2288 * StringUtils.removeStartIgnoreCase("abc", "") = "abc"
2289 * </pre>
2290 *
2291 * @param str the source String to search, may be null
2292 * @param remove the String to search for (case insensitive) and remove, may b e null
2293 * @return the substring with the string removed if found,
2294 * <code>null</code> if null String input
2295 * @since 2.4
2296 */
2297 public static String removeStartIgnoreCase(String str, String remove)
2298 {
2299 if (isEmpty(str) || isEmpty(remove))
2300 {
2301 return str;
2302 }
2303 if (startsWithIgnoreCase(str, remove))
2304 {
2305 return str.substring(remove.length());
2306 }
2307 return str;
2308 }
2309
2310 /**
2311 * <p>Removes a substring only if it is at the end of a source string,
2312 * otherwise returns the source string.</p>
2313 * <p/>
2314 * <p>A <code>null</code> source string will return <code>null</code>.
2315 * An empty ("") source string will return the empty string.
2316 * A <code>null</code> search string will return the source string.</p>
2317 * <p/>
2318 * <pre>
2319 * StringUtils.removeEnd(null, *) = null
2320 * StringUtils.removeEnd("", *) = ""
2321 * StringUtils.removeEnd(*, null) = *
2322 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com"
2323 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
2324 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
2325 * StringUtils.removeEnd("abc", "") = "abc"
2326 * </pre>
2327 *
2328 * @param str the source String to search, may be null
2329 * @param remove the String to search for and remove, may be null
2330 * @return the substring with the string removed if found,
2331 * <code>null</code> if null String input
2332 * @since 2.1
2333 */
2334 public static String removeEnd(String str, String remove)
2335 {
2336 if (isEmpty(str) || isEmpty(remove))
2337 {
2338 return str;
2339 }
2340 if (str.endsWith(remove))
2341 {
2342 return str.substring(0, str.length() - remove.length());
2343 }
2344 return str;
2345 }
2346
2347 /**
2348 * <p>Case insensitive removal of a substring if it is at the end of a source string,
2349 * otherwise returns the source string.</p>
2350 * <p/>
2351 * <p>A <code>null</code> source string will return <code>null</code>.
2352 * An empty ("") source string will return the empty string.
2353 * A <code>null</code> search string will return the source string.</p>
2354 * <p/>
2355 * <pre>
2356 * StringUtils.removeEnd(null, *) = null
2357 * StringUtils.removeEnd("", *) = ""
2358 * StringUtils.removeEnd(*, null) = *
2359 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com."
2360 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
2361 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
2362 * StringUtils.removeEnd("abc", "") = "abc"
2363 * </pre>
2364 *
2365 * @param str the source String to search, may be null
2366 * @param remove the String to search for (case insensitive) and remove, may b e null
2367 * @return the substring with the string removed if found,
2368 * <code>null</code> if null String input
2369 * @since 2.4
2370 */
2371 public static String removeEndIgnoreCase(String str, String remove)
2372 {
2373 if (isEmpty(str) || isEmpty(remove))
2374 {
2375 return str;
2376 }
2377 if (endsWithIgnoreCase(str, remove))
2378 {
2379 return str.substring(0, str.length() - remove.length());
2380 }
2381 return str;
2382 }
2383
2384 /**
2385 * <p>Removes all occurrences of a substring from within the source string.</p >
2386 * <p/>
2387 * <p>A <code>null</code> source string will return <code>null</code>.
2388 * An empty ("") source string will return the empty string.
2389 * A <code>null</code> remove string will return the source string.
2390 * An empty ("") remove string will return the source string.</p>
2391 * <p/>
2392 * <pre>
2393 * StringUtils.remove(null, *) = null
2394 * StringUtils.remove("", *) = ""
2395 * StringUtils.remove(*, null) = *
2396 * StringUtils.remove(*, "") = *
2397 * StringUtils.remove("queued", "ue") = "qd"
2398 * StringUtils.remove("queued", "zz") = "queued"
2399 * </pre>
2400 *
2401 * @param str the source String to search, may be null
2402 * @param remove the String to search for and remove, may be null
2403 * @return the substring with the string removed if found,
2404 * <code>null</code> if null String input
2405 * @since 2.1
2406 */
2407 public static String remove(String str, String remove)
2408 {
2409 if (isEmpty(str) || isEmpty(remove))
2410 {
2411 return str;
2412 }
2413 return replace(str, remove, EMPTY, -1);
2414 }
2415
2416 /**
2417 * <p>Removes all occurrences of a character from within the source string.</p >
2418 * <p/>
2419 * <p>A <code>null</code> source string will return <code>null</code>.
2420 * An empty ("") source string will return the empty string.</p>
2421 * <p/>
2422 * <pre>
2423 * StringUtils.remove(null, *) = null
2424 * StringUtils.remove("", *) = ""
2425 * StringUtils.remove("queued", 'u') = "qeed"
2426 * StringUtils.remove("queued", 'z') = "queued"
2427 * </pre>
2428 *
2429 * @param str the source String to search, may be null
2430 * @param remove the char to search for and remove, may be null
2431 * @return the substring with the char removed if found,
2432 * <code>null</code> if null String input
2433 * @since 2.1
2434 */
2435 public static String remove(String str, char remove)
2436 {
2437 if (isEmpty(str) || str.indexOf(remove) == -1)
2438 {
2439 return str;
2440 }
2441 char[] chars = str.toCharArray();
2442 int pos = 0;
2443 for (int i = 0; i < chars.length; i++)
2444 {
2445 if (chars[i] != remove)
2446 {
2447 chars[pos++] = chars[i];
2448 }
2449 }
2450 return new String(chars, 0, pos);
2451 }
2452
2453 // Replacing
2454 //-----------------------------------------------------------------------
2455
2456 /**
2457 * <p>Replaces a String with another String inside a larger String, once.</p>
2458 * <p/>
2459 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2460 * <p/>
2461 * <pre>
2462 * StringUtils.replaceOnce(null, *, *) = null
2463 * StringUtils.replaceOnce("", *, *) = ""
2464 * StringUtils.replaceOnce("any", null, *) = "any"
2465 * StringUtils.replaceOnce("any", *, null) = "any"
2466 * StringUtils.replaceOnce("any", "", *) = "any"
2467 * StringUtils.replaceOnce("aba", "a", null) = "aba"
2468 * StringUtils.replaceOnce("aba", "a", "") = "ba"
2469 * StringUtils.replaceOnce("aba", "a", "z") = "zba"
2470 * </pre>
2471 *
2472 * @param text text to search and replace in, may be null
2473 * @param searchString the String to search for, may be null
2474 * @param replacement the String to replace with, may be null
2475 * @return the text with any replacements processed,
2476 * <code>null</code> if null String input
2477 * @see #replace(String text, String searchString, String replacement, int max )
2478 */
2479 public static String replaceOnce(String text, String searchString, String repl acement)
2480 {
2481 return replace(text, searchString, replacement, 1);
2482 }
2483
2484 /**
2485 * <p>Replaces all occurrences of a String within another String.</p>
2486 * <p/>
2487 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2488 * <p/>
2489 * <pre>
2490 * StringUtils.replace(null, *, *) = null
2491 * StringUtils.replace("", *, *) = ""
2492 * StringUtils.replace("any", null, *) = "any"
2493 * StringUtils.replace("any", *, null) = "any"
2494 * StringUtils.replace("any", "", *) = "any"
2495 * StringUtils.replace("aba", "a", null) = "aba"
2496 * StringUtils.replace("aba", "a", "") = "b"
2497 * StringUtils.replace("aba", "a", "z") = "zbz"
2498 * </pre>
2499 *
2500 * @param text text to search and replace in, may be null
2501 * @param searchString the String to search for, may be null
2502 * @param replacement the String to replace it with, may be null
2503 * @return the text with any replacements processed,
2504 * <code>null</code> if null String input
2505 * @see #replace(String text, String searchString, String replacement, int max )
2506 */
2507 public static String replace(String text, String searchString, String replacem ent)
2508 {
2509 return replace(text, searchString, replacement, -1);
2510 }
2511
2512 /**
2513 * <p>Replaces a String with another String inside a larger String,
2514 * for the first <code>max</code> values of the search String.</p>
2515 * <p/>
2516 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2517 * <p/>
2518 * <pre>
2519 * StringUtils.replace(null, *, *, *) = null
2520 * StringUtils.replace("", *, *, *) = ""
2521 * StringUtils.replace("any", null, *, *) = "any"
2522 * StringUtils.replace("any", *, null, *) = "any"
2523 * StringUtils.replace("any", "", *, *) = "any"
2524 * StringUtils.replace("any", *, *, 0) = "any"
2525 * StringUtils.replace("abaa", "a", null, -1) = "abaa"
2526 * StringUtils.replace("abaa", "a", "", -1) = "b"
2527 * StringUtils.replace("abaa", "a", "z", 0) = "abaa"
2528 * StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
2529 * StringUtils.replace("abaa", "a", "z", 2) = "zbza"
2530 * StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
2531 * </pre>
2532 *
2533 * @param text text to search and replace in, may be null
2534 * @param searchString the String to search for, may be null
2535 * @param replacement the String to replace it with, may be null
2536 * @param max maximum number of values to replace, or <code>-1</code> if no maximum
2537 * @return the text with any replacements processed,
2538 * <code>null</code> if null String input
2539 */
2540 public static String replace(String text, String searchString, String replacem ent, int max)
2541 {
2542 if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0)
2543 {
2544 return text;
2545 }
2546 int start = 0;
2547 int end = text.indexOf(searchString, start);
2548 if (end == -1)
2549 {
2550 return text;
2551 }
2552 int replLength = searchString.length();
2553 int increase = replacement.length() - replLength;
2554 increase = (increase < 0 ? 0 : increase);
2555 increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
2556 StringBuffer buf = new StringBuffer(text.length() + increase);
2557 while (end != -1)
2558 {
2559 buf.append(text.substring(start, end)).append(replacement);
2560 start = end + replLength;
2561 if (--max == 0)
2562 {
2563 break;
2564 }
2565 end = text.indexOf(searchString, start);
2566 }
2567 buf.append(text.substring(start));
2568 return buf.toString();
2569 }
2570
2571 /**
2572 * <p>
2573 * Replaces all occurrences of Strings within another String.
2574 * </p>
2575 * <p/>
2576 * <p>
2577 * A <code>null</code> reference passed to this method is a no-op, or if
2578 * any "search string" or "string to replace" is null, that replace will be
2579 * ignored. This will not repeat. For repeating replaces, call the
2580 * overloaded method.
2581 * </p>
2582 * <p/>
2583 * <pre>
2584 * StringUtils.replaceEach(null, *, *) = null
2585 * StringUtils.replaceEach("", *, *) = ""
2586 * StringUtils.replaceEach("aba", null, null) = "aba"
2587 * StringUtils.replaceEach("aba", new String[0], null) = "aba"
2588 * StringUtils.replaceEach("aba", null, new String[0]) = "aba"
2589 * StringUtils.replaceEach("aba", new String[]{"a"}, null) = "aba"
2590 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}) = "b"
2591 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}) = " aba"
2592 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w" , "t"}) = "wcte"
2593 * (example of how it does not repeat)
2594 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}) = "dcte"
2595 * </pre>
2596 *
2597 * @param text text to search and replace in, no-op if null
2598 * @param searchList the Strings to search for, no-op if null
2599 * @param replacementList the Strings to replace them with, no-op if null
2600 * @return the text with any replacements processed, <code>null</code> if
2601 * null String input
2602 * @throws IndexOutOfBoundsException if the lengths of the arrays are not the same (null is ok,
2603 * and/or size 0)
2604 * @since 2.4
2605 */
2606 public static String replaceEach(String text, String[] searchList, String[] re placementList)
2607 {
2608 return replaceEach(text, searchList, replacementList, false, 0);
2609 }
2610
2611 /**
2612 * <p>
2613 * Replaces all occurrences of Strings within another String.
2614 * </p>
2615 * <p/>
2616 * <p>
2617 * A <code>null</code> reference passed to this method is a no-op, or if
2618 * any "search string" or "string to replace" is null, that replace will be
2619 * ignored. This will not repeat. For repeating replaces, call the
2620 * overloaded method.
2621 * </p>
2622 * <p/>
2623 * <pre>
2624 * StringUtils.replaceEach(null, *, *, *) = null
2625 * StringUtils.replaceEach("", *, *, *) = ""
2626 * StringUtils.replaceEach("aba", null, null, *) = "aba"
2627 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
2628 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
2629 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
2630 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = " b"
2631 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
2632 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w" , "t"}, *) = "wcte"
2633 * (example of how it repeats)
2634 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, false) = "dcte"
2635 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, true) = "tcte"
2636 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "ab"}, true) = IllegalArgumentException
2637 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "ab"}, false) = "dcabe"
2638 * </pre>
2639 *
2640 * @param text text to search and replace in, no-op if null
2641 * @param searchList the Strings to search for, no-op if null
2642 * @param replacementList the Strings to replace them with, no-op if null
2643 * @return the text with any replacements processed, <code>null</code> if
2644 * null String input
2645 * @throws IllegalArgumentException if the search is repeating and there is a n endless loop due
2646 * to outputs of one being inputs to another
2647 * @throws IndexOutOfBoundsException if the lengths of the arrays are not the same (null is ok,
2648 * and/or size 0)
2649 * @since 2.4
2650 */
2651 public static String replaceEachRepeatedly(String text, String[] searchList, S tring[] replacementList)
2652 {
2653 // timeToLive should be 0 if not used or nothing to replace, else it's
2654 // the length of the replace array
2655 int timeToLive = searchList == null ? 0 : searchList.length;
2656 return replaceEach(text, searchList, replacementList, true, timeToLive);
2657 }
2658
2659 /**
2660 * <p>
2661 * Replaces all occurrences of Strings within another String.
2662 * </p>
2663 * <p/>
2664 * <p>
2665 * A <code>null</code> reference passed to this method is a no-op, or if
2666 * any "search string" or "string to replace" is null, that replace will be
2667 * ignored.
2668 * </p>
2669 * <p/>
2670 * <pre>
2671 * StringUtils.replaceEach(null, *, *, *) = null
2672 * StringUtils.replaceEach("", *, *, *) = ""
2673 * StringUtils.replaceEach("aba", null, null, *) = "aba"
2674 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
2675 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
2676 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
2677 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = " b"
2678 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
2679 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w" , "t"}, *) = "wcte"
2680 * (example of how it repeats)
2681 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, false) = "dcte"
2682 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, true) = "tcte"
2683 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "ab"}, *) = IllegalArgumentException
2684 * </pre>
2685 *
2686 * @param text text to search and replace in, no-op if null
2687 * @param searchList the Strings to search for, no-op if null
2688 * @param replacementList the Strings to replace them with, no-op if null
2689 * @param repeat if true, then replace repeatedly
2690 * until there are no more possible replacements or tim eToLive < 0
2691 * @param timeToLive if less than 0 then there is a circular reference an d endless
2692 * loop
2693 * @return the text with any replacements processed, <code>null</code> if
2694 * null String input
2695 * @throws IllegalArgumentException if the search is repeating and there is a n endless loop due
2696 * to outputs of one being inputs to another
2697 * @throws IndexOutOfBoundsException if the lengths of the arrays are not the same (null is ok,
2698 * and/or size 0)
2699 * @since 2.4
2700 */
2701 private static String replaceEach(String text, String[] searchList, String[] r eplacementList,
2702 boolean repeat, int timeToLive)
2703 {
2704
2705 // mchyzer Performance note: This creates very few new objects (one major go al)
2706 // let me know if there are performance requests, we can create a harness to measure
2707
2708 if (text == null || text.length() == 0 || searchList == null ||
2709 searchList.length == 0 || replacementList == null || replacementList.lengt h == 0)
2710 {
2711 return text;
2712 }
2713
2714 // if recursing, this shouldnt be less than 0
2715 if (timeToLive < 0)
2716 {
2717 throw new IllegalStateException("TimeToLive of " + timeToLive + " is less than 0: " + text);
2718 }
2719
2720 int searchLength = searchList.length;
2721 int replacementLength = replacementList.length;
2722
2723 // make sure lengths are ok, these need to be equal
2724 if (searchLength != replacementLength)
2725 {
2726 throw new IllegalArgumentException("Search and Replace array lengths don't match: "
2727 + searchLength
2728 + " vs "
2729 + replacementLength);
2730 }
2731
2732 // keep track of which still have matches
2733 boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
2734
2735 // index on index that the match was found
2736 int textIndex = -1;
2737 int replaceIndex = -1;
2738 int tempIndex = -1;
2739
2740 // index of replace array that will replace the search string found
2741 // NOTE: logic duplicated below START
2742 for (int i = 0; i < searchLength; i++)
2743 {
2744 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
2745 searchList[i].length() == 0 || replacementList[i] == null)
2746 {
2747 continue;
2748 }
2749 tempIndex = text.indexOf(searchList[i]);
2750
2751 // see if we need to keep searching for this
2752 if (tempIndex == -1)
2753 {
2754 noMoreMatchesForReplIndex[i] = true;
2755 } else
2756 {
2757 if (textIndex == -1 || tempIndex < textIndex)
2758 {
2759 textIndex = tempIndex;
2760 replaceIndex = i;
2761 }
2762 }
2763 }
2764 // NOTE: logic mostly below END
2765
2766 // no search strings found, we are done
2767 if (textIndex == -1)
2768 {
2769 return text;
2770 }
2771
2772 int start = 0;
2773
2774 // get a good guess on the size of the result buffer so it doesnt have to do uble if it goes over a bit
2775 int increase = 0;
2776
2777 // count the replacement text elements that are larger than their correspond ing text being replaced
2778 for (int i = 0; i < searchList.length; i++)
2779 {
2780 int greater = replacementList[i].length() - searchList[i].length();
2781 if (greater > 0)
2782 {
2783 increase += 3 * greater; // assume 3 matches
2784 }
2785 }
2786 // have upper-bound at 20% increase, then let Java take over
2787 increase = Math.min(increase, text.length() / 5);
2788
2789 StringBuffer buf = new StringBuffer(text.length() + increase);
2790
2791 while (textIndex != -1)
2792 {
2793
2794 for (int i = start; i < textIndex; i++)
2795 {
2796 buf.append(text.charAt(i));
2797 }
2798 buf.append(replacementList[replaceIndex]);
2799
2800 start = textIndex + searchList[replaceIndex].length();
2801
2802 textIndex = -1;
2803 replaceIndex = -1;
2804 tempIndex = -1;
2805 // find the next earliest match
2806 // NOTE: logic mostly duplicated above START
2807 for (int i = 0; i < searchLength; i++)
2808 {
2809 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
2810 searchList[i].length() == 0 || replacementList[i] == null)
2811 {
2812 continue;
2813 }
2814 tempIndex = text.indexOf(searchList[i], start);
2815
2816 // see if we need to keep searching for this
2817 if (tempIndex == -1)
2818 {
2819 noMoreMatchesForReplIndex[i] = true;
2820 } else
2821 {
2822 if (textIndex == -1 || tempIndex < textIndex)
2823 {
2824 textIndex = tempIndex;
2825 replaceIndex = i;
2826 }
2827 }
2828 }
2829 // NOTE: logic duplicated above END
2830
2831 }
2832 int textLength = text.length();
2833 for (int i = start; i < textLength; i++)
2834 {
2835 buf.append(text.charAt(i));
2836 }
2837 String result = buf.toString();
2838 if (!repeat)
2839 {
2840 return result;
2841 }
2842
2843 return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
2844 }
2845
2846 // Replace, character based
2847 //-----------------------------------------------------------------------
2848
2849 /**
2850 * <p>Replaces all occurrences of a character in a String with another.
2851 * This is a null-safe version of {@link String#replace(char, char)}.</p>
2852 * <p/>
2853 * <p>A <code>null</code> string input returns <code>null</code>.
2854 * An empty ("") string input returns an empty string.</p>
2855 * <p/>
2856 * <pre>
2857 * StringUtils.replaceChars(null, *, *) = null
2858 * StringUtils.replaceChars("", *, *) = ""
2859 * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
2860 * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
2861 * </pre>
2862 *
2863 * @param str String to replace characters in, may be null
2864 * @param searchChar the character to search for, may be null
2865 * @param replaceChar the character to replace, may be null
2866 * @return modified String, <code>null</code> if null string input
2867 * @since 2.0
2868 */
2869 public static String replaceChars(String str, char searchChar, char replaceCha r)
2870 {
2871 if (str == null)
2872 {
2873 return null;
2874 }
2875 return str.replace(searchChar, replaceChar);
2876 }
2877
2878 /**
2879 * <p>Replaces multiple characters in a String in one go.
2880 * This method can also be used to delete characters.</p>
2881 * <p/>
2882 * <p>For example:<br />
2883 * <code>replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = jel ly</code>.</p>
2884 * <p/>
2885 * <p>A <code>null</code> string input returns <code>null</code>.
2886 * An empty ("") string input returns an empty string.
2887 * A null or empty set of search characters returns the input string.</p>
2888 * <p/>
2889 * <p>The length of the search characters should normally equal the length
2890 * of the replace characters.
2891 * If the search characters is longer, then the extra search characters
2892 * are deleted.
2893 * If the search characters is shorter, then the extra replace characters
2894 * are ignored.</p>
2895 * <p/>
2896 * <pre>
2897 * StringUtils.replaceChars(null, *, *) = null
2898 * StringUtils.replaceChars("", *, *) = ""
2899 * StringUtils.replaceChars("abc", null, *) = "abc"
2900 * StringUtils.replaceChars("abc", "", *) = "abc"
2901 * StringUtils.replaceChars("abc", "b", null) = "ac"
2902 * StringUtils.replaceChars("abc", "b", "") = "ac"
2903 * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya"
2904 * StringUtils.replaceChars("abcba", "bc", "y") = "ayya"
2905 * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
2906 * </pre>
2907 *
2908 * @param str String to replace characters in, may be null
2909 * @param searchChars a set of characters to search for, may be null
2910 * @param replaceChars a set of characters to replace, may be null
2911 * @return modified String, <code>null</code> if null string input
2912 * @since 2.0
2913 */
2914 public static String replaceChars(String str, String searchChars, String repla ceChars)
2915 {
2916 if (isEmpty(str) || isEmpty(searchChars))
2917 {
2918 return str;
2919 }
2920 if (replaceChars == null)
2921 {
2922 replaceChars = EMPTY;
2923 }
2924 boolean modified = false;
2925 int replaceCharsLength = replaceChars.length();
2926 int strLength = str.length();
2927 StringBuffer buf = new StringBuffer(strLength);
2928 for (int i = 0; i < strLength; i++)
2929 {
2930 char ch = str.charAt(i);
2931 int index = searchChars.indexOf(ch);
2932 if (index >= 0)
2933 {
2934 modified = true;
2935 if (index < replaceCharsLength)
2936 {
2937 buf.append(replaceChars.charAt(index));
2938 }
2939 } else
2940 {
2941 buf.append(ch);
2942 }
2943 }
2944 if (modified)
2945 {
2946 return buf.toString();
2947 }
2948 return str;
2949 }
2950
2951 // Overlay
2952 //-----------------------------------------------------------------------
2953
2954 /**
2955 * <p>Overlays part of a String with another String.</p>
2956 * <p/>
2957 * <pre>
2958 * StringUtils.overlayString(null, *, *, *) = NullPointerException
2959 * StringUtils.overlayString(*, null, *, *) = NullPointerException
2960 * StringUtils.overlayString("", "abc", 0, 0) = "abc"
2961 * StringUtils.overlayString("abcdef", null, 2, 4) = "abef"
2962 * StringUtils.overlayString("abcdef", "", 2, 4) = "abef"
2963 * StringUtils.overlayString("abcdef", "zzzz", 2, 4) = "abzzzzef"
2964 * StringUtils.overlayString("abcdef", "zzzz", 4, 2) = "abcdzzzzcdef"
2965 * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsExcept ion
2966 * StringUtils.overlayString("abcdef", "zzzz", 2, 8) = IndexOutOfBoundsExcept ion
2967 * </pre>
2968 *
2969 * @param text the String to do overlaying in, may be null
2970 * @param overlay the String to overlay, may be null
2971 * @param start the position to start overlaying at, must be valid
2972 * @param end the position to stop overlaying before, must be valid
2973 * @return overlayed String, <code>null</code> if null String input
2974 * @throws NullPointerException if text or overlay is null
2975 * @throws IndexOutOfBoundsException if either position is invalid
2976 * @deprecated Use better named {@link #overlay(String, String, int, int)} ins tead.
2977 * Method will be removed in Commons Lang 3.0.
2978 */
2979 public static String overlayString(String text, String overlay, int start, int end)
2980 {
2981 return new StringBuffer(start + overlay.length() + text.length() - end + 1)
2982 .append(text.substring(0, start))
2983 .append(overlay)
2984 .append(text.substring(end))
2985 .toString();
2986 }
2987
2988 /**
2989 * <p>Overlays part of a String with another String.</p>
2990 * <p/>
2991 * <p>A <code>null</code> string input returns <code>null</code>.
2992 * A negative index is treated as zero.
2993 * An index greater than the string length is treated as the string length.
2994 * The start index is always the smaller of the two indices.</p>
2995 * <p/>
2996 * <pre>
2997 * StringUtils.overlay(null, *, *, *) = null
2998 * StringUtils.overlay("", "abc", 0, 0) = "abc"
2999 * StringUtils.overlay("abcdef", null, 2, 4) = "abef"
3000 * StringUtils.overlay("abcdef", "", 2, 4) = "abef"
3001 * StringUtils.overlay("abcdef", "", 4, 2) = "abef"
3002 * StringUtils.overlay("abcdef", "zzzz", 2, 4) = "abzzzzef"
3003 * StringUtils.overlay("abcdef", "zzzz", 4, 2) = "abzzzzef"
3004 * StringUtils.overlay("abcdef", "zzzz", -1, 4) = "zzzzef"
3005 * StringUtils.overlay("abcdef", "zzzz", 2, 8) = "abzzzz"
3006 * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
3007 * StringUtils.overlay("abcdef", "zzzz", 8, 10) = "abcdefzzzz"
3008 * </pre>
3009 *
3010 * @param str the String to do overlaying in, may be null
3011 * @param overlay the String to overlay, may be null
3012 * @param start the position to start overlaying at
3013 * @param end the position to stop overlaying before
3014 * @return overlayed String, <code>null</code> if null String input
3015 * @since 2.0
3016 */
3017 public static String overlay(String str, String overlay, int start, int end)
3018 {
3019 if (str == null)
3020 {
3021 return null;
3022 }
3023 if (overlay == null)
3024 {
3025 overlay = EMPTY;
3026 }
3027 int len = str.length();
3028 if (start < 0)
3029 {
3030 start = 0;
3031 }
3032 if (start > len)
3033 {
3034 start = len;
3035 }
3036 if (end < 0)
3037 {
3038 end = 0;
3039 }
3040 if (end > len)
3041 {
3042 end = len;
3043 }
3044 if (start > end)
3045 {
3046 int temp = start;
3047 start = end;
3048 end = temp;
3049 }
3050 return new StringBuffer(len + start - end + overlay.length() + 1)
3051 .append(str.substring(0, start))
3052 .append(overlay)
3053 .append(str.substring(end))
3054 .toString();
3055 }
3056
3057 // Chomping
3058 //-----------------------------------------------------------------------
3059
3060 /**
3061 * <p>Removes one newline from end of a String if it's there,
3062 * otherwise leave it alone. A newline is &quot;<code>\n</code>&quot;,
3063 * &quot;<code>\r</code>&quot;, or &quot;<code>\r\n</code>&quot;.</p>
3064 * <p/>
3065 * <p>NOTE: This method changed in 2.0.
3066 * It now more closely matches Perl chomp.</p>
3067 * <p/>
3068 * <pre>
3069 * StringUtils.chomp(null) = null
3070 * StringUtils.chomp("") = ""
3071 * StringUtils.chomp("abc \r") = "abc "
3072 * StringUtils.chomp("abc\n") = "abc"
3073 * StringUtils.chomp("abc\r\n") = "abc"
3074 * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
3075 * StringUtils.chomp("abc\n\r") = "abc\n"
3076 * StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
3077 * StringUtils.chomp("\r") = ""
3078 * StringUtils.chomp("\n") = ""
3079 * StringUtils.chomp("\r\n") = ""
3080 * </pre>
3081 *
3082 * @param str the String to chomp a newline from, may be null
3083 * @return String without newline, <code>null</code> if null String input
3084 */
3085 public static String chomp(String str)
3086 {
3087 if (isEmpty(str))
3088 {
3089 return str;
3090 }
3091
3092 if (str.length() == 1)
3093 {
3094 char ch = str.charAt(0);
3095 if (ch == CharUtils.CR || ch == CharUtils.LF)
3096 {
3097 return EMPTY;
3098 }
3099 return str;
3100 }
3101
3102 int lastIdx = str.length() - 1;
3103 char last = str.charAt(lastIdx);
3104
3105 if (last == CharUtils.LF)
3106 {
3107 if (str.charAt(lastIdx - 1) == CharUtils.CR)
3108 {
3109 lastIdx--;
3110 }
3111 } else if (last != CharUtils.CR)
3112 {
3113 lastIdx++;
3114 }
3115 return str.substring(0, lastIdx);
3116 }
3117
3118 /**
3119 * <p>Removes <code>separator</code> from the end of
3120 * <code>str</code> if it's there, otherwise leave it alone.</p>
3121 * <p/>
3122 * <p>NOTE: This method changed in version 2.0.
3123 * It now more closely matches Perl chomp.
3124 * For the previous behavior, use {@link #substringBeforeLast(String, String)} .
3125 * This method uses {@link String#endsWith(String)}.</p>
3126 * <p/>
3127 * <pre>
3128 * StringUtils.chomp(null, *) = null
3129 * StringUtils.chomp("", *) = ""
3130 * StringUtils.chomp("foobar", "bar") = "foo"
3131 * StringUtils.chomp("foobar", "baz") = "foobar"
3132 * StringUtils.chomp("foo", "foo") = ""
3133 * StringUtils.chomp("foo ", "foo") = "foo "
3134 * StringUtils.chomp(" foo", "foo") = " "
3135 * StringUtils.chomp("foo", "foooo") = "foo"
3136 * StringUtils.chomp("foo", "") = "foo"
3137 * StringUtils.chomp("foo", null) = "foo"
3138 * </pre>
3139 *
3140 * @param str the String to chomp from, may be null
3141 * @param separator separator String, may be null
3142 * @return String without trailing separator, <code>null</code> if null String input
3143 */
3144 public static String chomp(String str, String separator)
3145 {
3146 if (isEmpty(str) || separator == null)
3147 {
3148 return str;
3149 }
3150 if (str.endsWith(separator))
3151 {
3152 return str.substring(0, str.length() - separator.length());
3153 }
3154 return str;
3155 }
3156
3157 /**
3158 * <p>Remove any &quot;\n&quot; if and only if it is at the end
3159 * of the supplied String.</p>
3160 *
3161 * @param str the String to chomp from, must not be null
3162 * @return String without chomped ending
3163 * @throws NullPointerException if str is <code>null</code>
3164 * @deprecated Use {@link #chomp(String)} instead.
3165 * Method will be removed in Commons Lang 3.0.
3166 */
3167 public static String chompLast(String str)
3168 {
3169 return chompLast(str, "\n");
3170 }
3171
3172 /**
3173 * <p>Remove a value if and only if the String ends with that value.</p>
3174 *
3175 * @param str the String to chomp from, must not be null
3176 * @param sep the String to chomp, must not be null
3177 * @return String without chomped ending
3178 * @throws NullPointerException if str or sep is <code>null</code>
3179 * @deprecated Use {@link #chomp(String, String)} instead.
3180 * Method will be removed in Commons Lang 3.0.
3181 */
3182 public static String chompLast(String str, String sep)
3183 {
3184 if (str.length() == 0)
3185 {
3186 return str;
3187 }
3188 String sub = str.substring(str.length() - sep.length());
3189 if (sep.equals(sub))
3190 {
3191 return str.substring(0, str.length() - sep.length());
3192 }
3193 return str;
3194 }
3195
3196 /**
3197 * <p>Remove everything and return the last value of a supplied String, and
3198 * everything after it from a String.</p>
3199 *
3200 * @param str the String to chomp from, must not be null
3201 * @param sep the String to chomp, must not be null
3202 * @return String chomped
3203 * @throws NullPointerException if str or sep is <code>null</code>
3204 * @deprecated Use {@link #substringAfterLast(String, String)} instead
3205 * (although this doesn't include the separator)
3206 * Method will be removed in Commons Lang 3.0.
3207 */
3208 public static String getChomp(String str, String sep)
3209 {
3210 int idx = str.lastIndexOf(sep);
3211 if (idx == str.length() - sep.length())
3212 {
3213 return sep;
3214 } else if (idx != -1)
3215 {
3216 return str.substring(idx);
3217 } else
3218 {
3219 return EMPTY;
3220 }
3221 }
3222
3223 /**
3224 * <p>Remove the first value of a supplied String, and everything before it
3225 * from a String.</p>
3226 *
3227 * @param str the String to chomp from, must not be null
3228 * @param sep the String to chomp, must not be null
3229 * @return String without chomped beginning
3230 * @throws NullPointerException if str or sep is <code>null</code>
3231 * @deprecated Use {@link #substringAfter(String, String)} instead.
3232 * Method will be removed in Commons Lang 3.0.
3233 */
3234 public static String prechomp(String str, String sep)
3235 {
3236 int idx = str.indexOf(sep);
3237 if (idx == -1)
3238 {
3239 return str;
3240 }
3241 return str.substring(idx + sep.length());
3242 }
3243
3244 /**
3245 * <p>Remove and return everything before the first value of a
3246 * supplied String from another String.</p>
3247 *
3248 * @param str the String to chomp from, must not be null
3249 * @param sep the String to chomp, must not be null
3250 * @return String prechomped
3251 * @throws NullPointerException if str or sep is <code>null</code>
3252 * @deprecated Use {@link #substringBefore(String, String)} instead
3253 * (although this doesn't include the separator).
3254 * Method will be removed in Commons Lang 3.0.
3255 */
3256 public static String getPrechomp(String str, String sep)
3257 {
3258 int idx = str.indexOf(sep);
3259 if (idx == -1)
3260 {
3261 return EMPTY;
3262 }
3263 return str.substring(0, idx + sep.length());
3264 }
3265
3266 // Chopping
3267 //-----------------------------------------------------------------------
3268
3269 /**
3270 * <p>Remove the last character from a String.</p>
3271 * <p/>
3272 * <p>If the String ends in <code>\r\n</code>, then remove both
3273 * of them.</p>
3274 * <p/>
3275 * <pre>
3276 * StringUtils.chop(null) = null
3277 * StringUtils.chop("") = ""
3278 * StringUtils.chop("abc \r") = "abc "
3279 * StringUtils.chop("abc\n") = "abc"
3280 * StringUtils.chop("abc\r\n") = "abc"
3281 * StringUtils.chop("abc") = "ab"
3282 * StringUtils.chop("abc\nabc") = "abc\nab"
3283 * StringUtils.chop("a") = ""
3284 * StringUtils.chop("\r") = ""
3285 * StringUtils.chop("\n") = ""
3286 * StringUtils.chop("\r\n") = ""
3287 * </pre>
3288 *
3289 * @param str the String to chop last character from, may be null
3290 * @return String without last character, <code>null</code> if null String inp ut
3291 */
3292 public static String chop(String str)
3293 {
3294 if (str == null)
3295 {
3296 return null;
3297 }
3298 int strLen = str.length();
3299 if (strLen < 2)
3300 {
3301 return EMPTY;
3302 }
3303 int lastIdx = strLen - 1;
3304 String ret = str.substring(0, lastIdx);
3305 char last = str.charAt(lastIdx);
3306 if (last == CharUtils.LF)
3307 {
3308 if (ret.charAt(lastIdx - 1) == CharUtils.CR)
3309 {
3310 return ret.substring(0, lastIdx - 1);
3311 }
3312 }
3313 return ret;
3314 }
3315
3316 /**
3317 * <p>Removes <code>\n</code> from end of a String if it's there.
3318 * If a <code>\r</code> precedes it, then remove that too.</p>
3319 *
3320 * @param str the String to chop a newline from, must not be null
3321 * @return String without newline
3322 * @throws NullPointerException if str is <code>null</code>
3323 * @deprecated Use {@link #chomp(String)} instead.
3324 * Method will be removed in Commons Lang 3.0.
3325 */
3326 public static String chopNewline(String str)
3327 {
3328 int lastIdx = str.length() - 1;
3329 if (lastIdx <= 0)
3330 {
3331 return EMPTY;
3332 }
3333 char last = str.charAt(lastIdx);
3334 if (last == CharUtils.LF)
3335 {
3336 if (str.charAt(lastIdx - 1) == CharUtils.CR)
3337 {
3338 lastIdx--;
3339 }
3340 } else
3341 {
3342 lastIdx++;
3343 }
3344 return str.substring(0, lastIdx);
3345 }
3346
3347 // Conversion
3348 //-----------------------------------------------------------------------
3349
3350 /**
3351 * <p>Escapes any values it finds into their String form.</p>
3352 * <p/>
3353 * <p>So a tab becomes the characters <code>'\\'</code> and
3354 * <code>'t'</code>.</p>
3355 * <p/>
3356 * <p>As of Lang 2.0, this calls {@link StringEscapeUtils#escapeJava(String)}
3357 * behind the scenes.
3358 * </p>
3359 *
3360 * @param str String to escape values in
3361 * @return String with escaped values
3362 * @throws NullPointerException if str is <code>null</code>
3363 * @see StringEscapeUtils#escapeJava(java.lang.String)
3364 * @deprecated Use {@link StringEscapeUtils#escapeJava(String)}
3365 * This method will be removed in Commons Lang 3.0
3366 */
3367 public static String escape(String str)
3368 {
3369 return StringEscapeUtils.escapeJava(str);
3370 }
3371
3372 // Padding
3373 //-----------------------------------------------------------------------
3374
3375 /**
3376 * <p>Repeat a String <code>repeat</code> times to form a
3377 * new String.</p>
3378 * <p/>
3379 * <pre>
3380 * StringUtils.repeat(null, 2) = null
3381 * StringUtils.repeat("", 0) = ""
3382 * StringUtils.repeat("", 2) = ""
3383 * StringUtils.repeat("a", 3) = "aaa"
3384 * StringUtils.repeat("ab", 2) = "abab"
3385 * StringUtils.repeat("a", -2) = ""
3386 * </pre>
3387 *
3388 * @param str the String to repeat, may be null
3389 * @param repeat number of times to repeat str, negative treated as zero
3390 * @return a new String consisting of the original String repeated,
3391 * <code>null</code> if null String input
3392 */
3393 public static String repeat(String str, int repeat)
3394 {
3395 // Performance tuned for 2.0 (JDK1.4)
3396
3397 if (str == null)
3398 {
3399 return null;
3400 }
3401 if (repeat <= 0)
3402 {
3403 return EMPTY;
3404 }
3405 int inputLength = str.length();
3406 if (repeat == 1 || inputLength == 0)
3407 {
3408 return str;
3409 }
3410 if (inputLength == 1 && repeat <= PAD_LIMIT)
3411 {
3412 return padding(repeat, str.charAt(0));
3413 }
3414
3415 int outputLength = inputLength * repeat;
3416 switch (inputLength)
3417 {
3418 case 1:
3419 char ch = str.charAt(0);
3420 char[] output1 = new char[outputLength];
3421 for (int i = repeat - 1; i >= 0; i--)
3422 {
3423 output1[i] = ch;
3424 }
3425 return new String(output1);
3426 case 2:
3427 char ch0 = str.charAt(0);
3428 char ch1 = str.charAt(1);
3429 char[] output2 = new char[outputLength];
3430 for (int i = repeat * 2 - 2; i >= 0; i--, i--)
3431 {
3432 output2[i] = ch0;
3433 output2[i + 1] = ch1;
3434 }
3435 return new String(output2);
3436 default:
3437 StringBuffer buf = new StringBuffer(outputLength);
3438 for (int i = 0; i < repeat; i++)
3439 {
3440 buf.append(str);
3441 }
3442 return buf.toString();
3443 }
3444 }
3445
3446 /**
3447 * <p>Returns padding using the specified delimiter repeated
3448 * to a given length.</p>
3449 * <p/>
3450 * <pre>
3451 * StringUtils.padding(0, 'e') = ""
3452 * StringUtils.padding(3, 'e') = "eee"
3453 * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
3454 * </pre>
3455 * <p/>
3456 * <p>Note: this method doesn't not support padding with
3457 * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicode Supplementary Characters</a>
3458 * as they require a pair of <code>char</code>s to be represented.
3459 * If you are needing to support full I18N of your applications
3460 * consider using {@link #repeat(String, int)} instead.
3461 * </p>
3462 *
3463 * @param repeat number of times to repeat delim
3464 * @param padChar character to repeat
3465 * @return String with repeated character
3466 * @throws IndexOutOfBoundsException if <code>repeat &lt; 0</code>
3467 * @see #repeat(String, int)
3468 */
3469 private static String padding(int repeat, char padChar) throws IndexOutOfBound sException
3470 {
3471 if (repeat < 0)
3472 {
3473 throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + rep eat);
3474 }
3475 final char[] buf = new char[repeat];
3476 for (int i = 0; i < buf.length; i++)
3477 {
3478 buf[i] = padChar;
3479 }
3480 return new String(buf);
3481 }
3482
3483 /**
3484 * <p>Right pad a String with spaces (' ').</p>
3485 * <p/>
3486 * <p>The String is padded to the size of <code>size</code>.</p>
3487 * <p/>
3488 * <pre>
3489 * StringUtils.rightPad(null, *) = null
3490 * StringUtils.rightPad("", 3) = " "
3491 * StringUtils.rightPad("bat", 3) = "bat"
3492 * StringUtils.rightPad("bat", 5) = "bat "
3493 * StringUtils.rightPad("bat", 1) = "bat"
3494 * StringUtils.rightPad("bat", -1) = "bat"
3495 * </pre>
3496 *
3497 * @param str the String to pad out, may be null
3498 * @param size the size to pad to
3499 * @return right padded String or original String if no padding is necessary,
3500 * <code>null</code> if null String input
3501 */
3502 public static String rightPad(String str, int size)
3503 {
3504 return rightPad(str, size, ' ');
3505 }
3506
3507 /**
3508 * <p>Right pad a String with a specified character.</p>
3509 * <p/>
3510 * <p>The String is padded to the size of <code>size</code>.</p>
3511 * <p/>
3512 * <pre>
3513 * StringUtils.rightPad(null, *, *) = null
3514 * StringUtils.rightPad("", 3, 'z') = "zzz"
3515 * StringUtils.rightPad("bat", 3, 'z') = "bat"
3516 * StringUtils.rightPad("bat", 5, 'z') = "batzz"
3517 * StringUtils.rightPad("bat", 1, 'z') = "bat"
3518 * StringUtils.rightPad("bat", -1, 'z') = "bat"
3519 * </pre>
3520 *
3521 * @param str the String to pad out, may be null
3522 * @param size the size to pad to
3523 * @param padChar the character to pad with
3524 * @return right padded String or original String if no padding is necessary,
3525 * <code>null</code> if null String input
3526 * @since 2.0
3527 */
3528 public static String rightPad(String str, int size, char padChar)
3529 {
3530 if (str == null)
3531 {
3532 return null;
3533 }
3534 int pads = size - str.length();
3535 if (pads <= 0)
3536 {
3537 return str; // returns original String when possible
3538 }
3539 if (pads > PAD_LIMIT)
3540 {
3541 return rightPad(str, size, String.valueOf(padChar));
3542 }
3543 return str.concat(padding(pads, padChar));
3544 }
3545
3546 /**
3547 * <p>Right pad a String with a specified String.</p>
3548 * <p/>
3549 * <p>The String is padded to the size of <code>size</code>.</p>
3550 * <p/>
3551 * <pre>
3552 * StringUtils.rightPad(null, *, *) = null
3553 * StringUtils.rightPad("", 3, "z") = "zzz"
3554 * StringUtils.rightPad("bat", 3, "yz") = "bat"
3555 * StringUtils.rightPad("bat", 5, "yz") = "batyz"
3556 * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy"
3557 * StringUtils.rightPad("bat", 1, "yz") = "bat"
3558 * StringUtils.rightPad("bat", -1, "yz") = "bat"
3559 * StringUtils.rightPad("bat", 5, null) = "bat "
3560 * StringUtils.rightPad("bat", 5, "") = "bat "
3561 * </pre>
3562 *
3563 * @param str the String to pad out, may be null
3564 * @param size the size to pad to
3565 * @param padStr the String to pad with, null or empty treated as single space
3566 * @return right padded String or original String if no padding is necessary,
3567 * <code>null</code> if null String input
3568 */
3569 public static String rightPad(String str, int size, String padStr)
3570 {
3571 if (str == null)
3572 {
3573 return null;
3574 }
3575 if (isEmpty(padStr))
3576 {
3577 padStr = " ";
3578 }
3579 int padLen = padStr.length();
3580 int strLen = str.length();
3581 int pads = size - strLen;
3582 if (pads <= 0)
3583 {
3584 return str; // returns original String when possible
3585 }
3586 if (padLen == 1 && pads <= PAD_LIMIT)
3587 {
3588 return rightPad(str, size, padStr.charAt(0));
3589 }
3590
3591 if (pads == padLen)
3592 {
3593 return str.concat(padStr);
3594 } else if (pads < padLen)
3595 {
3596 return str.concat(padStr.substring(0, pads));
3597 } else
3598 {
3599 char[] padding = new char[pads];
3600 char[] padChars = padStr.toCharArray();
3601 for (int i = 0; i < pads; i++)
3602 {
3603 padding[i] = padChars[i % padLen];
3604 }
3605 return str.concat(new String(padding));
3606 }
3607 }
3608
3609 /**
3610 * <p>Left pad a String with spaces (' ').</p>
3611 * <p/>
3612 * <p>The String is padded to the size of <code>size<code>.</p>
3613 * <p/>
3614 * <pre>
3615 * StringUtils.leftPad(null, *) = null
3616 * StringUtils.leftPad("", 3) = " "
3617 * StringUtils.leftPad("bat", 3) = "bat"
3618 * StringUtils.leftPad("bat", 5) = " bat"
3619 * StringUtils.leftPad("bat", 1) = "bat"
3620 * StringUtils.leftPad("bat", -1) = "bat"
3621 * </pre>
3622 *
3623 * @param str the String to pad out, may be null
3624 * @param size the size to pad to
3625 * @return left padded String or original String if no padding is necessary,
3626 * <code>null</code> if null String input
3627 */
3628 public static String leftPad(String str, int size)
3629 {
3630 return leftPad(str, size, ' ');
3631 }
3632
3633 /**
3634 * <p>Left pad a String with a specified character.</p>
3635 * <p/>
3636 * <p>Pad to a size of <code>size</code>.</p>
3637 * <p/>
3638 * <pre>
3639 * StringUtils.leftPad(null, *, *) = null
3640 * StringUtils.leftPad("", 3, 'z') = "zzz"
3641 * StringUtils.leftPad("bat", 3, 'z') = "bat"
3642 * StringUtils.leftPad("bat", 5, 'z') = "zzbat"
3643 * StringUtils.leftPad("bat", 1, 'z') = "bat"
3644 * StringUtils.leftPad("bat", -1, 'z') = "bat"
3645 * </pre>
3646 *
3647 * @param str the String to pad out, may be null
3648 * @param size the size to pad to
3649 * @param padChar the character to pad with
3650 * @return left padded String or original String if no padding is necessary,
3651 * <code>null</code> if null String input
3652 * @since 2.0
3653 */
3654 public static String leftPad(String str, int size, char padChar)
3655 {
3656 if (str == null)
3657 {
3658 return null;
3659 }
3660 int pads = size - str.length();
3661 if (pads <= 0)
3662 {
3663 return str; // returns original String when possible
3664 }
3665 if (pads > PAD_LIMIT)
3666 {
3667 return leftPad(str, size, String.valueOf(padChar));
3668 }
3669 return padding(pads, padChar).concat(str);
3670 }
3671
3672 /**
3673 * <p>Left pad a String with a specified String.</p>
3674 * <p/>
3675 * <p>Pad to a size of <code>size</code>.</p>
3676 * <p/>
3677 * <pre>
3678 * StringUtils.leftPad(null, *, *) = null
3679 * StringUtils.leftPad("", 3, "z") = "zzz"
3680 * StringUtils.leftPad("bat", 3, "yz") = "bat"
3681 * StringUtils.leftPad("bat", 5, "yz") = "yzbat"
3682 * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
3683 * StringUtils.leftPad("bat", 1, "yz") = "bat"
3684 * StringUtils.leftPad("bat", -1, "yz") = "bat"
3685 * StringUtils.leftPad("bat", 5, null) = " bat"
3686 * StringUtils.leftPad("bat", 5, "") = " bat"
3687 * </pre>
3688 *
3689 * @param str the String to pad out, may be null
3690 * @param size the size to pad to
3691 * @param padStr the String to pad with, null or empty treated as single space
3692 * @return left padded String or original String if no padding is necessary,
3693 * <code>null</code> if null String input
3694 */
3695 public static String leftPad(String str, int size, String padStr)
3696 {
3697 if (str == null)
3698 {
3699 return null;
3700 }
3701 if (isEmpty(padStr))
3702 {
3703 padStr = " ";
3704 }
3705 int padLen = padStr.length();
3706 int strLen = str.length();
3707 int pads = size - strLen;
3708 if (pads <= 0)
3709 {
3710 return str; // returns original String when possible
3711 }
3712 if (padLen == 1 && pads <= PAD_LIMIT)
3713 {
3714 return leftPad(str, size, padStr.charAt(0));
3715 }
3716
3717 if (pads == padLen)
3718 {
3719 return padStr.concat(str);
3720 } else if (pads < padLen)
3721 {
3722 return padStr.substring(0, pads).concat(str);
3723 } else
3724 {
3725 char[] padding = new char[pads];
3726 char[] padChars = padStr.toCharArray();
3727 for (int i = 0; i < pads; i++)
3728 {
3729 padding[i] = padChars[i % padLen];
3730 }
3731 return new String(padding).concat(str);
3732 }
3733 }
3734
3735 /**
3736 * Gets a String's length or <code>0</code> if the String is <code>null</code> .
3737 *
3738 * @param str a String or <code>null</code>
3739 * @return String length or <code>0</code> if the String is <code>null</code>.
3740 * @since 2.4
3741 */
3742 public static int length(String str)
3743 {
3744 return str == null ? 0 : str.length();
3745 }
3746
3747 // Centering
3748 //-----------------------------------------------------------------------
3749
3750 /**
3751 * <p>Centers a String in a larger String of size <code>size</code>
3752 * using the space character (' ').<p>
3753 * <p/>
3754 * <p>If the size is less than the String length, the String is returned.
3755 * A <code>null</code> String returns <code>null</code>.
3756 * A negative size is treated as zero.</p>
3757 * <p/>
3758 * <p>Equivalent to <code>center(str, size, " ")</code>.</p>
3759 * <p/>
3760 * <pre>
3761 * StringUtils.center(null, *) = null
3762 * StringUtils.center("", 4) = " "
3763 * StringUtils.center("ab", -1) = "ab"
3764 * StringUtils.center("ab", 4) = " ab "
3765 * StringUtils.center("abcd", 2) = "abcd"
3766 * StringUtils.center("a", 4) = " a "
3767 * </pre>
3768 *
3769 * @param str the String to center, may be null
3770 * @param size the int size of new String, negative treated as zero
3771 * @return centered String, <code>null</code> if null String input
3772 */
3773 public static String center(String str, int size)
3774 {
3775 return center(str, size, ' ');
3776 }
3777
3778 /**
3779 * <p>Centers a String in a larger String of size <code>size</code>.
3780 * Uses a supplied character as the value to pad the String with.</p>
3781 * <p/>
3782 * <p>If the size is less than the String length, the String is returned.
3783 * A <code>null</code> String returns <code>null</code>.
3784 * A negative size is treated as zero.</p>
3785 * <p/>
3786 * <pre>
3787 * StringUtils.center(null, *, *) = null
3788 * StringUtils.center("", 4, ' ') = " "
3789 * StringUtils.center("ab", -1, ' ') = "ab"
3790 * StringUtils.center("ab", 4, ' ') = " ab"
3791 * StringUtils.center("abcd", 2, ' ') = "abcd"
3792 * StringUtils.center("a", 4, ' ') = " a "
3793 * StringUtils.center("a", 4, 'y') = "yayy"
3794 * </pre>
3795 *
3796 * @param str the String to center, may be null
3797 * @param size the int size of new String, negative treated as zero
3798 * @param padChar the character to pad the new String with
3799 * @return centered String, <code>null</code> if null String input
3800 * @since 2.0
3801 */
3802 public static String center(String str, int size, char padChar)
3803 {
3804 if (str == null || size <= 0)
3805 {
3806 return str;
3807 }
3808 int strLen = str.length();
3809 int pads = size - strLen;
3810 if (pads <= 0)
3811 {
3812 return str;
3813 }
3814 str = leftPad(str, strLen + pads / 2, padChar);
3815 str = rightPad(str, size, padChar);
3816 return str;
3817 }
3818
3819 /**
3820 * <p>Centers a String in a larger String of size <code>size</code>.
3821 * Uses a supplied String as the value to pad the String with.</p>
3822 * <p/>
3823 * <p>If the size is less than the String length, the String is returned.
3824 * A <code>null</code> String returns <code>null</code>.
3825 * A negative size is treated as zero.</p>
3826 * <p/>
3827 * <pre>
3828 * StringUtils.center(null, *, *) = null
3829 * StringUtils.center("", 4, " ") = " "
3830 * StringUtils.center("ab", -1, " ") = "ab"
3831 * StringUtils.center("ab", 4, " ") = " ab"
3832 * StringUtils.center("abcd", 2, " ") = "abcd"
3833 * StringUtils.center("a", 4, " ") = " a "
3834 * StringUtils.center("a", 4, "yz") = "yayz"
3835 * StringUtils.center("abc", 7, null) = " abc "
3836 * StringUtils.center("abc", 7, "") = " abc "
3837 * </pre>
3838 *
3839 * @param str the String to center, may be null
3840 * @param size the int size of new String, negative treated as zero
3841 * @param padStr the String to pad the new String with, must not be null or em pty
3842 * @return centered String, <code>null</code> if null String input
3843 * @throws IllegalArgumentException if padStr is <code>null</code> or empty
3844 */
3845 public static String center(String str, int size, String padStr)
3846 {
3847 if (str == null || size <= 0)
3848 {
3849 return str;
3850 }
3851 if (isEmpty(padStr))
3852 {
3853 padStr = " ";
3854 }
3855 int strLen = str.length();
3856 int pads = size - strLen;
3857 if (pads <= 0)
3858 {
3859 return str;
3860 }
3861 str = leftPad(str, strLen + pads / 2, padStr);
3862 str = rightPad(str, size, padStr);
3863 return str;
3864 }
3865
3866 // Case conversion
3867 //-----------------------------------------------------------------------
3868
3869 /**
3870 * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
3871 * <p/>
3872 * <p>A <code>null</code> input String returns <code>null</code>.</p>
3873 * <p/>
3874 * <pre>
3875 * StringUtils.upperCase(null) = null
3876 * StringUtils.upperCase("") = ""
3877 * StringUtils.upperCase("aBc") = "ABC"
3878 * </pre>
3879 *
3880 * @param str the String to upper case, may be null
3881 * @return the upper cased String, <code>null</code> if null String input
3882 */
3883 public static String upperCase(String str)
3884 {
3885 if (str == null)
3886 {
3887 return null;
3888 }
3889 return str.toUpperCase();
3890 }
3891
3892 /**
3893 * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>
3894 * <p/>
3895 * <p>A <code>null</code> input String returns <code>null</code>.</p>
3896 * <p/>
3897 * <pre>
3898 * StringUtils.lowerCase(null) = null
3899 * StringUtils.lowerCase("") = ""
3900 * StringUtils.lowerCase("aBc") = "abc"
3901 * </pre>
3902 *
3903 * @param str the String to lower case, may be null
3904 * @return the lower cased String, <code>null</code> if null String input
3905 */
3906 public static String lowerCase(String str)
3907 {
3908 if (str == null)
3909 {
3910 return null;
3911 }
3912 return str.toLowerCase();
3913 }
3914
3915 /**
3916 * <p>Capitalizes a String changing the first letter to title case as
3917 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
3918 * <p/>
3919 * <p>For a word based algorithm, see {@link WordUtils#capitalize(String)}.
3920 * A <code>null</code> input String returns <code>null</code>.</p>
3921 * <p/>
3922 * <pre>
3923 * StringUtils.capitalize(null) = null
3924 * StringUtils.capitalize("") = ""
3925 * StringUtils.capitalize("cat") = "Cat"
3926 * StringUtils.capitalize("cAt") = "CAt"
3927 * </pre>
3928 *
3929 * @param str the String to capitalize, may be null
3930 * @return the capitalized String, <code>null</code> if null String input
3931 * @see WordUtils#capitalize(String)
3932 * @see #uncapitalize(String)
3933 * @since 2.0
3934 */
3935 public static String capitalize(String str)
3936 {
3937 int strLen;
3938 if (str == null || (strLen = str.length()) == 0)
3939 {
3940 return str;
3941 }
3942 return new StringBuffer(strLen)
3943 .append(Character.toTitleCase(str.charAt(0)))
3944 .append(str.substring(1))
3945 .toString();
3946 }
3947
3948 /**
3949 * <p>Capitalizes a String changing the first letter to title case as
3950 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
3951 *
3952 * @param str the String to capitalize, may be null
3953 * @return the capitalized String, <code>null</code> if null String input
3954 * @deprecated Use the standardly named {@link #capitalize(String)}.
3955 * Method will be removed in Commons Lang 3.0.
3956 */
3957 public static String capitalise(String str)
3958 {
3959 return capitalize(str);
3960 }
3961
3962 /**
3963 * <p>Uncapitalizes a String changing the first letter to title case as
3964 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
3965 * <p/>
3966 * <p>For a word based algorithm, see {@link WordUtils#uncapitalize(String)}.
3967 * A <code>null</code> input String returns <code>null</code>.</p>
3968 * <p/>
3969 * <pre>
3970 * StringUtils.uncapitalize(null) = null
3971 * StringUtils.uncapitalize("") = ""
3972 * StringUtils.uncapitalize("Cat") = "cat"
3973 * StringUtils.uncapitalize("CAT") = "cAT"
3974 * </pre>
3975 *
3976 * @param str the String to uncapitalize, may be null
3977 * @return the uncapitalized String, <code>null</code> if null String input
3978 * @see WordUtils#uncapitalize(String)
3979 * @see #capitalize(String)
3980 * @since 2.0
3981 */
3982 public static String uncapitalize(String str)
3983 {
3984 int strLen;
3985 if (str == null || (strLen = str.length()) == 0)
3986 {
3987 return str;
3988 }
3989 return new StringBuffer(strLen)
3990 .append(Character.toLowerCase(str.charAt(0)))
3991 .append(str.substring(1))
3992 .toString();
3993 }
3994
3995 /**
3996 * <p>Uncapitalizes a String changing the first letter to title case as
3997 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
3998 *
3999 * @param str the String to uncapitalize, may be null
4000 * @return the uncapitalized String, <code>null</code> if null String input
4001 * @deprecated Use the standardly named {@link #uncapitalize(String)}.
4002 * Method will be removed in Commons Lang 3.0.
4003 */
4004 public static String uncapitalise(String str)
4005 {
4006 return uncapitalize(str);
4007 }
4008
4009 /**
4010 * <p>Swaps the case of a String changing upper and title case to
4011 * lower case, and lower case to upper case.</p>
4012 * <p/>
4013 * <ul>
4014 * <li>Upper case character converts to Lower case</li>
4015 * <li>Title case character converts to Lower case</li>
4016 * <li>Lower case character converts to Upper case</li>
4017 * </ul>
4018 * <p/>
4019 * <p>For a word based algorithm, see {@link WordUtils#swapCase(String)}.
4020 * A <code>null</code> input String returns <code>null</code>.</p>
4021 * <p/>
4022 * <pre>
4023 * StringUtils.swapCase(null) = null
4024 * StringUtils.swapCase("") = ""
4025 * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
4026 * </pre>
4027 * <p/>
4028 * <p>NOTE: This method changed in Lang version 2.0.
4029 * It no longer performs a word based algorithm.
4030 * If you only use ASCII, you will notice no change.
4031 * That functionality is available in WordUtils.</p>
4032 *
4033 * @param str the String to swap case, may be null
4034 * @return the changed String, <code>null</code> if null String input
4035 */
4036 public static String swapCase(String str)
4037 {
4038 int strLen;
4039 if (str == null || (strLen = str.length()) == 0)
4040 {
4041 return str;
4042 }
4043 StringBuffer buffer = new StringBuffer(strLen);
4044
4045 char ch = 0;
4046 for (int i = 0; i < strLen; i++)
4047 {
4048 ch = str.charAt(i);
4049 if (Character.isUpperCase(ch))
4050 {
4051 ch = Character.toLowerCase(ch);
4052 } else if (Character.isTitleCase(ch))
4053 {
4054 ch = Character.toLowerCase(ch);
4055 } else if (Character.isLowerCase(ch))
4056 {
4057 ch = Character.toUpperCase(ch);
4058 }
4059 buffer.append(ch);
4060 }
4061 return buffer.toString();
4062 }
4063
4064 // Count matches
4065 //-----------------------------------------------------------------------
4066
4067 /**
4068 * <p>Counts how many times the substring appears in the larger String.</p>
4069 * <p/>
4070 * <p>A <code>null</code> or empty ("") String input returns <code>0</code>.</ p>
4071 * <p/>
4072 * <pre>
4073 * StringUtils.countMatches(null, *) = 0
4074 * StringUtils.countMatches("", *) = 0
4075 * StringUtils.countMatches("abba", null) = 0
4076 * StringUtils.countMatches("abba", "") = 0
4077 * StringUtils.countMatches("abba", "a") = 2
4078 * StringUtils.countMatches("abba", "ab") = 1
4079 * StringUtils.countMatches("abba", "xxx") = 0
4080 * </pre>
4081 *
4082 * @param str the String to check, may be null
4083 * @param sub the substring to count, may be null
4084 * @return the number of occurrences, 0 if either String is <code>null</code>
4085 */
4086 public static int countMatches(String str, String sub)
4087 {
4088 if (isEmpty(str) || isEmpty(sub))
4089 {
4090 return 0;
4091 }
4092 int count = 0;
4093 int idx = 0;
4094 while ((idx = str.indexOf(sub, idx)) != -1)
4095 {
4096 count++;
4097 idx += sub.length();
4098 }
4099 return count;
4100 }
4101
4102 // Character Tests
4103 //-----------------------------------------------------------------------
4104
4105 /**
4106 * <p>Checks if the String contains only unicode letters.</p>
4107 * <p/>
4108 * <p><code>null</code> will return <code>false</code>.
4109 * An empty String ("") will return <code>true</code>.</p>
4110 * <p/>
4111 * <pre>
4112 * StringUtils.isAlpha(null) = false
4113 * StringUtils.isAlpha("") = true
4114 * StringUtils.isAlpha(" ") = false
4115 * StringUtils.isAlpha("abc") = true
4116 * StringUtils.isAlpha("ab2c") = false
4117 * StringUtils.isAlpha("ab-c") = false
4118 * </pre>
4119 *
4120 * @param str the String to check, may be null
4121 * @return <code>true</code> if only contains letters, and is non-null
4122 */
4123 public static boolean isAlpha(String str)
4124 {
4125 if (str == null)
4126 {
4127 return false;
4128 }
4129 int sz = str.length();
4130 for (int i = 0; i < sz; i++)
4131 {
4132 if (Character.isLetter(str.charAt(i)) == false)
4133 {
4134 return false;
4135 }
4136 }
4137 return true;
4138 }
4139
4140 /**
4141 * <p>Checks if the String contains only unicode letters and
4142 * space (' ').</p>
4143 * <p/>
4144 * <p><code>null</code> will return <code>false</code>
4145 * An empty String ("") will return <code>true</code>.</p>
4146 * <p/>
4147 * <pre>
4148 * StringUtils.isAlphaSpace(null) = false
4149 * StringUtils.isAlphaSpace("") = true
4150 * StringUtils.isAlphaSpace(" ") = true
4151 * StringUtils.isAlphaSpace("abc") = true
4152 * StringUtils.isAlphaSpace("ab c") = true
4153 * StringUtils.isAlphaSpace("ab2c") = false
4154 * StringUtils.isAlphaSpace("ab-c") = false
4155 * </pre>
4156 *
4157 * @param str the String to check, may be null
4158 * @return <code>true</code> if only contains letters and space,
4159 * and is non-null
4160 */
4161 public static boolean isAlphaSpace(String str)
4162 {
4163 if (str == null)
4164 {
4165 return false;
4166 }
4167 int sz = str.length();
4168 for (int i = 0; i < sz; i++)
4169 {
4170 if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) != ' ') )
4171 {
4172 return false;
4173 }
4174 }
4175 return true;
4176 }
4177
4178 /**
4179 * <p>Checks if the String contains only unicode letters or digits.</p>
4180 * <p/>
4181 * <p><code>null</code> will return <code>false</code>.
4182 * An empty String ("") will return <code>true</code>.</p>
4183 * <p/>
4184 * <pre>
4185 * StringUtils.isAlphanumeric(null) = false
4186 * StringUtils.isAlphanumeric("") = true
4187 * StringUtils.isAlphanumeric(" ") = false
4188 * StringUtils.isAlphanumeric("abc") = true
4189 * StringUtils.isAlphanumeric("ab c") = false
4190 * StringUtils.isAlphanumeric("ab2c") = true
4191 * StringUtils.isAlphanumeric("ab-c") = false
4192 * </pre>
4193 *
4194 * @param str the String to check, may be null
4195 * @return <code>true</code> if only contains letters or digits,
4196 * and is non-null
4197 */
4198 public static boolean isAlphanumeric(String str)
4199 {
4200 if (str == null)
4201 {
4202 return false;
4203 }
4204 int sz = str.length();
4205 for (int i = 0; i < sz; i++)
4206 {
4207 if (Character.isLetterOrDigit(str.charAt(i)) == false)
4208 {
4209 return false;
4210 }
4211 }
4212 return true;
4213 }
4214
4215 /**
4216 * <p>Checks if the String contains only unicode letters, digits
4217 * or space (<code>' '</code>).</p>
4218 * <p/>
4219 * <p><code>null</code> will return <code>false</code>.
4220 * An empty String ("") will return <code>true</code>.</p>
4221 * <p/>
4222 * <pre>
4223 * StringUtils.isAlphanumeric(null) = false
4224 * StringUtils.isAlphanumeric("") = true
4225 * StringUtils.isAlphanumeric(" ") = true
4226 * StringUtils.isAlphanumeric("abc") = true
4227 * StringUtils.isAlphanumeric("ab c") = true
4228 * StringUtils.isAlphanumeric("ab2c") = true
4229 * StringUtils.isAlphanumeric("ab-c") = false
4230 * </pre>
4231 *
4232 * @param str the String to check, may be null
4233 * @return <code>true</code> if only contains letters, digits or space,
4234 * and is non-null
4235 */
4236 public static boolean isAlphanumericSpace(String str)
4237 {
4238 if (str == null)
4239 {
4240 return false;
4241 }
4242 int sz = str.length();
4243 for (int i = 0; i < sz; i++)
4244 {
4245 if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.charAt(i) != ' '))
4246 {
4247 return false;
4248 }
4249 }
4250 return true;
4251 }
4252
4253 /**
4254 * <p>Checks if the string contains only ASCII printable characters.</p>
4255 * <p/>
4256 * <p><code>null</code> will return <code>false</code>.
4257 * An empty String ("") will return <code>true</code>.</p>
4258 * <p/>
4259 * <pre>
4260 * StringUtils.isAsciiPrintable(null) = false
4261 * StringUtils.isAsciiPrintable("") = true
4262 * StringUtils.isAsciiPrintable(" ") = true
4263 * StringUtils.isAsciiPrintable("Ceki") = true
4264 * StringUtils.isAsciiPrintable("ab2c") = true
4265 * StringUtils.isAsciiPrintable("!ab-c~") = true
4266 * StringUtils.isAsciiPrintable("\u0020") = true
4267 * StringUtils.isAsciiPrintable("\u0021") = true
4268 * StringUtils.isAsciiPrintable("\u007e") = true
4269 * StringUtils.isAsciiPrintable("\u007f") = false
4270 * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
4271 * </pre>
4272 *
4273 * @param str the string to check, may be null
4274 * @return <code>true</code> if every character is in the range
4275 * 32 thru 126
4276 * @since 2.1
4277 */
4278 public static boolean isAsciiPrintable(String str)
4279 {
4280 if (str == null)
4281 {
4282 return false;
4283 }
4284 int sz = str.length();
4285 for (int i = 0; i < sz; i++)
4286 {
4287 if (CharUtils.isAsciiPrintable(str.charAt(i)) == false)
4288 {
4289 return false;
4290 }
4291 }
4292 return true;
4293 }
4294
4295 /**
4296 * <p>Checks if the String contains only unicode digits.
4297 * A decimal point is not a unicode digit and returns false.</p>
4298 * <p/>
4299 * <p><code>null</code> will return <code>false</code>.
4300 * An empty String ("") will return <code>true</code>.</p>
4301 * <p/>
4302 * <pre>
4303 * StringUtils.isNumeric(null) = false
4304 * StringUtils.isNumeric("") = true
4305 * StringUtils.isNumeric(" ") = false
4306 * StringUtils.isNumeric("123") = true
4307 * StringUtils.isNumeric("12 3") = false
4308 * StringUtils.isNumeric("ab2c") = false
4309 * StringUtils.isNumeric("12-3") = false
4310 * StringUtils.isNumeric("12.3") = false
4311 * </pre>
4312 *
4313 * @param str the String to check, may be null
4314 * @return <code>true</code> if only contains digits, and is non-null
4315 */
4316 public static boolean isNumeric(String str)
4317 {
4318 if (str == null)
4319 {
4320 return false;
4321 }
4322 int sz = str.length();
4323 for (int i = 0; i < sz; i++)
4324 {
4325 if (Character.isDigit(str.charAt(i)) == false)
4326 {
4327 return false;
4328 }
4329 }
4330 return true;
4331 }
4332
4333 /**
4334 * <p>Checks if the String contains only unicode digits or space
4335 * (<code>' '</code>).
4336 * A decimal point is not a unicode digit and returns false.</p>
4337 * <p/>
4338 * <p><code>null</code> will return <code>false</code>.
4339 * An empty String ("") will return <code>true</code>.</p>
4340 * <p/>
4341 * <pre>
4342 * StringUtils.isNumeric(null) = false
4343 * StringUtils.isNumeric("") = true
4344 * StringUtils.isNumeric(" ") = true
4345 * StringUtils.isNumeric("123") = true
4346 * StringUtils.isNumeric("12 3") = true
4347 * StringUtils.isNumeric("ab2c") = false
4348 * StringUtils.isNumeric("12-3") = false
4349 * StringUtils.isNumeric("12.3") = false
4350 * </pre>
4351 *
4352 * @param str the String to check, may be null
4353 * @return <code>true</code> if only contains digits or space,
4354 * and is non-null
4355 */
4356 public static boolean isNumericSpace(String str)
4357 {
4358 if (str == null)
4359 {
4360 return false;
4361 }
4362 int sz = str.length();
4363 for (int i = 0; i < sz; i++)
4364 {
4365 if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' '))
4366 {
4367 return false;
4368 }
4369 }
4370 return true;
4371 }
4372
4373 /**
4374 * <p>Checks if the String contains only whitespace.</p>
4375 * <p/>
4376 * <p><code>null</code> will return <code>false</code>.
4377 * An empty String ("") will return <code>true</code>.</p>
4378 * <p/>
4379 * <pre>
4380 * StringUtils.isWhitespace(null) = false
4381 * StringUtils.isWhitespace("") = true
4382 * StringUtils.isWhitespace(" ") = true
4383 * StringUtils.isWhitespace("abc") = false
4384 * StringUtils.isWhitespace("ab2c") = false
4385 * StringUtils.isWhitespace("ab-c") = false
4386 * </pre>
4387 *
4388 * @param str the String to check, may be null
4389 * @return <code>true</code> if only contains whitespace, and is non-null
4390 * @since 2.0
4391 */
4392 public static boolean isWhitespace(String str)
4393 {
4394 if (str == null)
4395 {
4396 return false;
4397 }
4398 int sz = str.length();
4399 for (int i = 0; i < sz; i++)
4400 {
4401 if ((Character.isWhitespace(str.charAt(i)) == false))
4402 {
4403 return false;
4404 }
4405 }
4406 return true;
4407 }
4408
4409 // Defaults
4410 //-----------------------------------------------------------------------
4411
4412 /**
4413 * <p>Returns either the passed in String,
4414 * or if the String is <code>null</code>, an empty String ("").</p>
4415 * <p/>
4416 * <pre>
4417 * StringUtils.defaultString(null) = ""
4418 * StringUtils.defaultString("") = ""
4419 * StringUtils.defaultString("bat") = "bat"
4420 * </pre>
4421 *
4422 * @param str the String to check, may be null
4423 * @return the passed in String, or the empty String if it
4424 * was <code>null</code>
4425 * @see ObjectUtils#toString(Object)
4426 * @see String#valueOf(Object)
4427 */
4428 public static String defaultString(String str)
4429 {
4430 return str == null ? EMPTY : str;
4431 }
4432
4433 /**
4434 * <p>Returns either the passed in String, or if the String is
4435 * <code>null</code>, the value of <code>defaultStr</code>.</p>
4436 * <p/>
4437 * <pre>
4438 * StringUtils.defaultString(null, "NULL") = "NULL"
4439 * StringUtils.defaultString("", "NULL") = ""
4440 * StringUtils.defaultString("bat", "NULL") = "bat"
4441 * </pre>
4442 *
4443 * @param str the String to check, may be null
4444 * @param defaultStr the default String to return
4445 * if the input is <code>null</code>, may be null
4446 * @return the passed in String, or the default if it was <code>null</code>
4447 * @see ObjectUtils#toString(Object, String)
4448 * @see String#valueOf(Object)
4449 */
4450 public static String defaultString(String str, String defaultStr)
4451 {
4452 return str == null ? defaultStr : str;
4453 }
4454
4455 /**
4456 * <p>Returns either the passed in String, or if the String is
4457 * empty or <code>null</code>, the value of <code>defaultStr</code>.</p>
4458 * <p/>
4459 * <pre>
4460 * StringUtils.defaultIfEmpty(null, "NULL") = "NULL"
4461 * StringUtils.defaultIfEmpty("", "NULL") = "NULL"
4462 * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
4463 * </pre>
4464 *
4465 * @param str the String to check, may be null
4466 * @param defaultStr the default String to return
4467 * if the input is empty ("") or <code>null</code>, may be n ull
4468 * @return the passed in String, or the default
4469 * @see StringUtils#defaultString(String, String)
4470 */
4471 public static String defaultIfEmpty(String str, String defaultStr)
4472 {
4473 return StringUtils.isEmpty(str) ? defaultStr : str;
4474 }
4475
4476 // Reversing
4477 //-----------------------------------------------------------------------
4478
4479 /**
4480 * <p>Reverses a String as per {@link StringBuffer#reverse()}.</p>
4481 * <p/>
4482 * <p>A <code>null</code> String returns <code>null</code>.</p>
4483 * <p/>
4484 * <pre>
4485 * StringUtils.reverse(null) = null
4486 * StringUtils.reverse("") = ""
4487 * StringUtils.reverse("bat") = "tab"
4488 * </pre>
4489 *
4490 * @param str the String to reverse, may be null
4491 * @return the reversed String, <code>null</code> if null String input
4492 */
4493 public static String reverse(String str)
4494 {
4495 if (str == null)
4496 {
4497 return null;
4498 }
4499 return new StringBuffer(str).reverse().toString();
4500 }
4501
4502 // Abbreviating
4503 //-----------------------------------------------------------------------
4504
4505 /**
4506 * <p>Abbreviates a String using ellipses. This will turn
4507 * "Now is the time for all good men" into "Now is the time for..."</p>
4508 * <p/>
4509 * <p>Specifically:
4510 * <ul>
4511 * <li>If <code>str</code> is less than <code>maxWidth</code> characters
4512 * long, return it.</li>
4513 * <li>Else abbreviate it to <code>(substring(str, 0, max-3) + "...")</code>.< /li>
4514 * <li>If <code>maxWidth</code> is less than <code>4</code>, throw an
4515 * <code>IllegalArgumentException</code>.</li>
4516 * <li>In no case will it return a String of length greater than
4517 * <code>maxWidth</code>.</li>
4518 * </ul>
4519 * </p>
4520 * <p/>
4521 * <pre>
4522 * StringUtils.abbreviate(null, *) = null
4523 * StringUtils.abbreviate("", 4) = ""
4524 * StringUtils.abbreviate("abcdefg", 6) = "abc..."
4525 * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
4526 * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
4527 * StringUtils.abbreviate("abcdefg", 4) = "a..."
4528 * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
4529 * </pre>
4530 *
4531 * @param str the String to check, may be null
4532 * @param maxWidth maximum length of result String, must be at least 4
4533 * @return abbreviated String, <code>null</code> if null String input
4534 * @throws IllegalArgumentException if the width is too small
4535 * @since 2.0
4536 */
4537 public static String abbreviate(String str, int maxWidth)
4538 {
4539 return abbreviate(str, 0, maxWidth);
4540 }
4541
4542 /**
4543 * <p>Abbreviates a String using ellipses. This will turn
4544 * "Now is the time for all good men" into "...is the time for..."</p>
4545 * <p/>
4546 * <p>Works like <code>abbreviate(String, int)</code>, but allows you to speci fy
4547 * a "left edge" offset. Note that this left edge is not necessarily going to
4548 * be the leftmost character in the result, or the first character following t he
4549 * ellipses, but it will appear somewhere in the result.
4550 * <p/>
4551 * <p>In no case will it return a String of length greater than
4552 * <code>maxWidth</code>.</p>
4553 * <p/>
4554 * <pre>
4555 * StringUtils.abbreviate(null, *, *) = null
4556 * StringUtils.abbreviate("", 0, 4) = ""
4557 * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
4558 * StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..."
4559 * StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..."
4560 * StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..."
4561 * StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..."
4562 * StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..."
4563 * StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno"
4564 * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
4565 * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
4566 * StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentExceptio n
4567 * StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentExceptio n
4568 * </pre>
4569 *
4570 * @param str the String to check, may be null
4571 * @param offset left edge of source String
4572 * @param maxWidth maximum length of result String, must be at least 4
4573 * @return abbreviated String, <code>null</code> if null String input
4574 * @throws IllegalArgumentException if the width is too small
4575 * @since 2.0
4576 */
4577 public static String abbreviate(String str, int offset, int maxWidth)
4578 {
4579 if (str == null)
4580 {
4581 return null;
4582 }
4583 if (maxWidth < 4)
4584 {
4585 throw new IllegalArgumentException("Minimum abbreviation width is 4");
4586 }
4587 if (str.length() <= maxWidth)
4588 {
4589 return str;
4590 }
4591 if (offset > str.length())
4592 {
4593 offset = str.length();
4594 }
4595 if ((str.length() - offset) < (maxWidth - 3))
4596 {
4597 offset = str.length() - (maxWidth - 3);
4598 }
4599 if (offset <= 4)
4600 {
4601 return str.substring(0, maxWidth - 3) + "...";
4602 }
4603 if (maxWidth < 7)
4604 {
4605 throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
4606 }
4607 if ((offset + (maxWidth - 3)) < str.length())
4608 {
4609 return "..." + abbreviate(str.substring(offset), maxWidth - 3);
4610 }
4611 return "..." + str.substring(str.length() - (maxWidth - 3));
4612 }
4613
4614 // Difference
4615 //-----------------------------------------------------------------------
4616
4617 /**
4618 * <p>Compares two Strings, and returns the portion where they differ.
4619 * (More precisely, return the remainder of the second String,
4620 * starting from where it's different from the first.)</p>
4621 * <p/>
4622 * <p>For example,
4623 * <code>difference("i am a machine", "i am a robot") -> "robot"</code>.</p>
4624 * <p/>
4625 * <pre>
4626 * StringUtils.difference(null, null) = null
4627 * StringUtils.difference("", "") = ""
4628 * StringUtils.difference("", "abc") = "abc"
4629 * StringUtils.difference("abc", "") = ""
4630 * StringUtils.difference("abc", "abc") = ""
4631 * StringUtils.difference("ab", "abxyz") = "xyz"
4632 * StringUtils.difference("abcde", "abxyz") = "xyz"
4633 * StringUtils.difference("abcde", "xyz") = "xyz"
4634 * </pre>
4635 *
4636 * @param str1 the first String, may be null
4637 * @param str2 the second String, may be null
4638 * @return the portion of str2 where it differs from str1; returns the
4639 * empty String if they are equal
4640 * @since 2.0
4641 */
4642 public static String difference(String str1, String str2)
4643 {
4644 if (str1 == null)
4645 {
4646 return str2;
4647 }
4648 if (str2 == null)
4649 {
4650 return str1;
4651 }
4652 int at = indexOfDifference(str1, str2);
4653 if (at == -1)
4654 {
4655 return EMPTY;
4656 }
4657 return str2.substring(at);
4658 }
4659
4660 /**
4661 * <p>Compares two Strings, and returns the index at which the
4662 * Strings begin to differ.</p>
4663 * <p/>
4664 * <p>For example,
4665 * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code></p>
4666 * <p/>
4667 * <pre>
4668 * StringUtils.indexOfDifference(null, null) = -1
4669 * StringUtils.indexOfDifference("", "") = -1
4670 * StringUtils.indexOfDifference("", "abc") = 0
4671 * StringUtils.indexOfDifference("abc", "") = 0
4672 * StringUtils.indexOfDifference("abc", "abc") = -1
4673 * StringUtils.indexOfDifference("ab", "abxyz") = 2
4674 * StringUtils.indexOfDifference("abcde", "abxyz") = 2
4675 * StringUtils.indexOfDifference("abcde", "xyz") = 0
4676 * </pre>
4677 *
4678 * @param str1 the first String, may be null
4679 * @param str2 the second String, may be null
4680 * @return the index where str2 and str1 begin to differ; -1 if they are equal
4681 * @since 2.0
4682 */
4683 public static int indexOfDifference(String str1, String str2)
4684 {
4685 if (str1 == str2)
4686 {
4687 return -1;
4688 }
4689 if (str1 == null || str2 == null)
4690 {
4691 return 0;
4692 }
4693 int i;
4694 for (i = 0; i < str1.length() && i < str2.length(); ++i)
4695 {
4696 if (str1.charAt(i) != str2.charAt(i))
4697 {
4698 break;
4699 }
4700 }
4701 if (i < str2.length() || i < str1.length())
4702 {
4703 return i;
4704 }
4705 return -1;
4706 }
4707
4708 /**
4709 * <p>Compares all Strings in an array and returns the index at which the
4710 * Strings begin to differ.</p>
4711 * <p/>
4712 * <p>For example,
4713 * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
4714 * <p/>
4715 * <pre>
4716 * StringUtils.indexOfDifference(null) = -1
4717 * StringUtils.indexOfDifference(new String[] {}) = -1
4718 * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
4719 * StringUtils.indexOfDifference(new String[] {null, null}) = -1
4720 * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
4721 * StringUtils.indexOfDifference(new String[] {"", null}) = 0
4722 * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
4723 * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
4724 * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
4725 * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
4726 * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
4727 * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
4728 * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
4729 * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
4730 * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
4731 * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
4732 * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot "}) = 7
4733 * </pre>
4734 *
4735 * @param strs array of strings, entries may be null
4736 * @return the index where the strings begin to differ; -1 if they are all equ al
4737 * @since 2.4
4738 */
4739 public static int indexOfDifference(String[] strs)
4740 {
4741 if (strs == null || strs.length <= 1)
4742 {
4743 return -1;
4744 }
4745 boolean anyStringNull = false;
4746 boolean allStringsNull = true;
4747 int arrayLen = strs.length;
4748 int shortestStrLen = Integer.MAX_VALUE;
4749 int longestStrLen = 0;
4750
4751 // find the min and max string lengths; this avoids checking to make
4752 // sure we are not exceeding the length of the string each time through
4753 // the bottom loop.
4754 for (int i = 0; i < arrayLen; i++)
4755 {
4756 if (strs[i] == null)
4757 {
4758 anyStringNull = true;
4759 shortestStrLen = 0;
4760 } else
4761 {
4762 allStringsNull = false;
4763 shortestStrLen = Math.min(strs[i].length(), shortestStrLen);
4764 longestStrLen = Math.max(strs[i].length(), longestStrLen);
4765 }
4766 }
4767
4768 // handle lists containing all nulls or all empty strings
4769 if (allStringsNull || (longestStrLen == 0 && !anyStringNull))
4770 {
4771 return -1;
4772 }
4773
4774 // handle lists containing some nulls or some empty strings
4775 if (shortestStrLen == 0)
4776 {
4777 return 0;
4778 }
4779
4780 // find the position with the first difference across all strings
4781 int firstDiff = -1;
4782 for (int stringPos = 0; stringPos < shortestStrLen; stringPos++)
4783 {
4784 char comparisonChar = strs[0].charAt(stringPos);
4785 for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++)
4786 {
4787 if (strs[arrayPos].charAt(stringPos) != comparisonChar)
4788 {
4789 firstDiff = stringPos;
4790 break;
4791 }
4792 }
4793 if (firstDiff != -1)
4794 {
4795 break;
4796 }
4797 }
4798
4799 if (firstDiff == -1 && shortestStrLen != longestStrLen)
4800 {
4801 // we compared all of the characters up to the length of the
4802 // shortest string and didn't find a match, but the string lengths
4803 // vary, so return the length of the shortest string.
4804 return shortestStrLen;
4805 }
4806 return firstDiff;
4807 }
4808
4809 /**
4810 * <p>Compares all Strings in an array and returns the initial sequence of
4811 * characters that is common to all of them.</p>
4812 * <p/>
4813 * <p>For example,
4814 * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> " i am a "</code></p>
4815 * <p/>
4816 * <pre>
4817 * StringUtils.getCommonPrefix(null) = ""
4818 * StringUtils.getCommonPrefix(new String[] {}) = ""
4819 * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
4820 * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
4821 * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
4822 * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
4823 * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
4824 * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
4825 * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
4826 * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
4827 * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
4828 * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
4829 * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
4830 * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
4831 * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
4832 * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
4833 * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"} ) = "i am a "
4834 * </pre>
4835 *
4836 * @param strs array of String objects, entries may be null
4837 * @return the initial sequence of characters that are common to all Strings
4838 * in the array; empty String if the array is null, the elements are all null
4839 * or if there is no common prefix.
4840 * @since 2.4
4841 */
4842 public static String getCommonPrefix(String[] strs)
4843 {
4844 if (strs == null || strs.length == 0)
4845 {
4846 return EMPTY;
4847 }
4848 int smallestIndexOfDiff = indexOfDifference(strs);
4849 if (smallestIndexOfDiff == -1)
4850 {
4851 // all strings were identical
4852 if (strs[0] == null)
4853 {
4854 return EMPTY;
4855 }
4856 return strs[0];
4857 } else if (smallestIndexOfDiff == 0)
4858 {
4859 // there were no common initial characters
4860 return EMPTY;
4861 } else
4862 {
4863 // we found a common initial character sequence
4864 return strs[0].substring(0, smallestIndexOfDiff);
4865 }
4866 }
4867
4868 // Misc
4869 //-----------------------------------------------------------------------
4870
4871 /**
4872 * <p>Find the Levenshtein distance between two Strings.</p>
4873 * <p/>
4874 * <p>This is the number of changes needed to change one String into
4875 * another, where each change is a single character modification (deletion,
4876 * insertion or substitution).</p>
4877 * <p/>
4878 * <p>The previous implementation of the Levenshtein distance algorithm
4879 * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark .com/ld.htm</a></p>
4880 * <p/>
4881 * <p>Chas Emerick has written an implementation in Java, which avoids an OutO fMemoryError
4882 * which can occur when my Java implementation is used with very large strings .<br>
4883 * This implementation of the Levenshtein distance algorithm
4884 * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriamp ark.com/ldjava.htm</a></p>
4885 * <p/>
4886 * <pre>
4887 * StringUtils.getLevenshteinDistance(null, *) = IllegalArgumentEx ception
4888 * StringUtils.getLevenshteinDistance(*, null) = IllegalArgumentEx ception
4889 * StringUtils.getLevenshteinDistance("","") = 0
4890 * StringUtils.getLevenshteinDistance("","a") = 1
4891 * StringUtils.getLevenshteinDistance("aaapppp", "") = 7
4892 * StringUtils.getLevenshteinDistance("frog", "fog") = 1
4893 * StringUtils.getLevenshteinDistance("fly", "ant") = 3
4894 * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
4895 * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
4896 * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
4897 * StringUtils.getLevenshteinDistance("hello", "hallo") = 1
4898 * </pre>
4899 *
4900 * @param s the first String, must not be null
4901 * @param t the second String, must not be null
4902 * @return result distance
4903 * @throws IllegalArgumentException if either String input <code>null</code>
4904 */
4905 public static int getLevenshteinDistance(String s, String t)
4906 {
4907 if (s == null || t == null)
4908 {
4909 throw new IllegalArgumentException("Strings must not be null");
4910 }
4911
4912 /*
4913 The difference between this impl. and the previous is that, rather
4914 than creating and retaining a matrix of size s.length()+1 by t.length ()+1,
4915 we maintain two single-dimensional arrays of length s.length()+1. Th e first, d,
4916 is the 'current working' distance array that maintains the newest dis tance cost
4917 counts as we iterate through the characters of String s. Each time w e increment
4918 the index of String t we are comparing, d is copied to p, the second int[]. Doing so
4919 allows us to retain the previous cost counts as required by the algor ithm (taking
4920 the minimum of the cost count to the left, up one, and diagonally up and to the left
4921 of the current cost count being calculated). (Note that the arrays a ren't really
4922 copied anymore, just switched...this is clearly much better than clon ing an array
4923 or doing a System.arraycopy() each time through the outer loop.)
4924
4925 Effectively, the difference between the two implementations is this o ne does not
4926 cause an out of memory condition when calculating the LD over two ver y large strings.
4927 */
4928
4929 int n = s.length(); // length of s
4930 int m = t.length(); // length of t
4931
4932 if (n == 0)
4933 {
4934 return m;
4935 } else if (m == 0)
4936 {
4937 return n;
4938 }
4939
4940 if (n > m)
4941 {
4942 // swap the input strings to consume less memory
4943 String tmp = s;
4944 s = t;
4945 t = tmp;
4946 n = m;
4947 m = t.length();
4948 }
4949
4950 int p[] = new int[n + 1]; //'previous' cost array, horizontally
4951 int d[] = new int[n + 1]; // cost array, horizontally
4952 int _d[]; //placeholder to assist in swapping p and d
4953
4954 // indexes into strings s and t
4955 int i; // iterates through s
4956 int j; // iterates through t
4957
4958 char t_j; // jth character of t
4959
4960 int cost; // cost
4961
4962 for (i = 0; i <= n; i++)
4963 {
4964 p[i] = i;
4965 }
4966
4967 for (j = 1; j <= m; j++)
4968 {
4969 t_j = t.charAt(j - 1);
4970 d[0] = j;
4971
4972 for (i = 1; i <= n; i++)
4973 {
4974 cost = s.charAt(i - 1) == t_j ? 0 : 1;
4975 // minimum of cell to the left+1, to the top+1, diagonally left and up + cost
4976 d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
4977 }
4978
4979 // copy current distance counts to 'previous row' distance counts
4980 _d = p;
4981 p = d;
4982 d = _d;
4983 }
4984
4985 // our last action in the above loop was to switch d and p, so p now
4986 // actually has the most recent cost counts
4987 return p[n];
4988 }
4989
4990 /**
4991 * <p>Gets the minimum of three <code>int</code> values.</p>
4992 *
4993 * @param a value 1
4994 * @param b value 2
4995 * @param c value 3
4996 * @return the smallest of the values
4997 */
4998 /*
4999 private static int min(int a, int b, int c) {
5000 // Method copied from NumberUtils to avoid dependency on subpackage
5001 if (b < a) {
5002 a = b;
5003 }
5004 if (c < a) {
5005 a = c;
5006 }
5007 return a;
5008 }
5009 */
5010
5011 // startsWith
5012 //-----------------------------------------------------------------------
5013
5014 /**
5015 * <p>Check if a String starts with a specified prefix.</p>
5016 * <p/>
5017 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
5018 * references are considered to be equal. The comparison is case sensitive.</p >
5019 * <p/>
5020 * <pre>
5021 * StringUtils.startsWith(null, null) = true
5022 * StringUtils.startsWith(null, "abcdef") = false
5023 * StringUtils.startsWith("abc", null) = false
5024 * StringUtils.startsWith("abc", "abcdef") = true
5025 * StringUtils.startsWith("abc", "ABCDEF") = false
5026 * </pre>
5027 *
5028 * @param str the String to check, may be null
5029 * @param prefix the prefix to find, may be null
5030 * @return <code>true</code> if the String starts with the prefix, case sensit ive, or
5031 * both <code>null</code>
5032 * @see java.lang.String#startsWith(String)
5033 * @since 2.4
5034 */
5035 public static boolean startsWith(String str, String prefix)
5036 {
5037 return startsWith(str, prefix, false);
5038 }
5039
5040 /**
5041 * <p>Case insensitive check if a String starts with a specified prefix.</p>
5042 * <p/>
5043 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
5044 * references are considered to be equal. The comparison is case insensitive.< /p>
5045 * <p/>
5046 * <pre>
5047 * StringUtils.startsWithIgnoreCase(null, null) = true
5048 * StringUtils.startsWithIgnoreCase(null, "abcdef") = false
5049 * StringUtils.startsWithIgnoreCase("abc", null) = false
5050 * StringUtils.startsWithIgnoreCase("abc", "abcdef") = true
5051 * StringUtils.startsWithIgnoreCase("abc", "ABCDEF") = true
5052 * </pre>
5053 *
5054 * @param str the String to check, may be null
5055 * @param prefix the prefix to find, may be null
5056 * @return <code>true</code> if the String starts with the prefix, case insens itive, or
5057 * both <code>null</code>
5058 * @see java.lang.String#startsWith(String)
5059 * @since 2.4
5060 */
5061 public static boolean startsWithIgnoreCase(String str, String prefix)
5062 {
5063 return startsWith(str, prefix, true);
5064 }
5065
5066 /**
5067 * <p>Check if a String starts with a specified prefix (optionally case insens itive).</p>
5068 *
5069 * @param str the String to check, may be null
5070 * @param prefix the prefix to find, may be null
5071 * @param ignoreCase inidicates whether the compare should ignore case
5072 * (case insensitive) or not.
5073 * @return <code>true</code> if the String starts with the prefix or
5074 * both <code>null</code>
5075 * @see java.lang.String#startsWith(String)
5076 */
5077 private static boolean startsWith(String str, String prefix, boolean ignoreCas e)
5078 {
5079 if (str == null || prefix == null)
5080 {
5081 return (str == null && prefix == null);
5082 }
5083 if (prefix.length() > str.length())
5084 {
5085 return false;
5086 }
5087 return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
5088 }
5089
5090 // endsWith
5091 //-----------------------------------------------------------------------
5092
5093 /**
5094 * <p>Check if a String ends with a specified suffix.</p>
5095 * <p/>
5096 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
5097 * references are considered to be equal. The comparison is case sensitive.</p >
5098 * <p/>
5099 * <pre>
5100 * StringUtils.endsWith(null, null) = true
5101 * StringUtils.endsWith(null, "abcdef") = false
5102 * StringUtils.endsWith("def", null) = false
5103 * StringUtils.endsWith("def", "abcdef") = true
5104 * StringUtils.endsWith("def", "ABCDEF") = false
5105 * </pre>
5106 *
5107 * @param str the String to check, may be null
5108 * @param suffix the suffix to find, may be null
5109 * @return <code>true</code> if the String ends with the suffix, case sensitiv e, or
5110 * both <code>null</code>
5111 * @see java.lang.String#endsWith(String)
5112 * @since 2.4
5113 */
5114 public static boolean endsWith(String str, String suffix)
5115 {
5116 return endsWith(str, suffix, false);
5117 }
5118
5119 /**
5120 * <p>Case insensitive check if a String ends with a specified suffix.</p>
5121 * <p/>
5122 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
5123 * references are considered to be equal. The comparison is case insensitive.< /p>
5124 * <p/>
5125 * <pre>
5126 * StringUtils.endsWithIgnoreCase(null, null) = true
5127 * StringUtils.endsWithIgnoreCase(null, "abcdef") = false
5128 * StringUtils.endsWithIgnoreCase("def", null) = false
5129 * StringUtils.endsWithIgnoreCase("def", "abcdef") = true
5130 * StringUtils.endsWithIgnoreCase("def", "ABCDEF") = false
5131 * </pre>
5132 *
5133 * @param str the String to check, may be null
5134 * @param suffix the suffix to find, may be null
5135 * @return <code>true</code> if the String ends with the suffix, case insensit ive, or
5136 * both <code>null</code>
5137 * @see java.lang.String#endsWith(String)
5138 * @since 2.4
5139 */
5140 public static boolean endsWithIgnoreCase(String str, String suffix)
5141 {
5142 return endsWith(str, suffix, true);
5143 }
5144
5145 /**
5146 * <p>Check if a String ends with a specified suffix (optionally case insensit ive).</p>
5147 *
5148 * @param str the String to check, may be null
5149 * @param suffix the suffix to find, may be null
5150 * @param ignoreCase inidicates whether the compare should ignore case
5151 * (case insensitive) or not.
5152 * @return <code>true</code> if the String starts with the prefix or
5153 * both <code>null</code>
5154 * @see java.lang.String#endsWith(String)
5155 */
5156 private static boolean endsWith(String str, String suffix, boolean ignoreCase)
5157 {
5158 if (str == null || suffix == null)
5159 {
5160 return (str == null && suffix == null);
5161 }
5162 if (suffix.length() > str.length())
5163 {
5164 return false;
5165 }
5166 int strOffset = str.length() - suffix.length();
5167 return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
5168 }
5169
5170 }
OLDNEW

Powered by Google App Engine
This is Rietveld