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