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