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