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

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

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

Powered by Google App Engine
This is Rietveld