1 /* ==================================================================== 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 2002 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, if 20 * any, must include the following acknowledgement: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.codehaus.org/)." 23 * Alternately, this acknowledgement may appear in the software itself, 24 * if and wherever such third-party acknowledgements normally appear. 25 * 26 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 27 * Foundation" must not be used to endorse or promote products derived 28 * from this software without prior written permission. For written 29 * permission, please contact codehaus@codehaus.org. 30 * 31 * 5. Products derived from this software may not be called "Apache" 32 * nor may "Apache" appear in their names without prior written 33 * permission of the Apache Software Foundation. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.codehaus.org/>. 53 */ 54 package org.codehaus.plexus.util; 55 56 import java.util.Arrays; 57 import java.util.Iterator; 58 import java.util.Locale; 59 import java.util.Map; 60 import java.util.Objects; 61 import java.util.StringTokenizer; 62 63 /** 64 * <p> 65 * Common <code>String</code> manipulation routines. 66 * </p> 67 * <p> 68 * Originally from <a href="http://jakarta.apache.org/turbine/">Turbine</a> and the GenerationJavaCore library. 69 * </p> 70 * 71 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 72 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 73 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a> 74 * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a> 75 * @author <a href="mailto:ed@codehaus.org">Ed Korthof</a> 76 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a> 77 * @author Stephen Colebourne 78 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a> 79 * @author Holger Krauth 80 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a> 81 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> 82 * @since 1.0 83 * 84 */ 85 public class StringUtils { 86 /** 87 * <p> 88 * <code>StringUtils</code> instances should NOT be constructed in standard programming. Instead, the class should 89 * be used as <code>StringUtils.trim(" foo ");</code>. 90 * </p> 91 * <p> 92 * This constructor is public to permit tools that require a JavaBean manager to operate. 93 * </p> 94 */ 95 public StringUtils() {} 96 97 // Empty 98 // -------------------------------------------------------------------------- 99 100 /** 101 * <p> 102 * Removes control characters, including whitespace, from both ends of this String, handling <code>null</code> by 103 * returning an empty String. 104 * </p> 105 * 106 * @see java.lang.String#trim() 107 * @param str the String to check 108 * @return the trimmed text (never <code>null</code>) 109 */ 110 public static String clean(String str) { 111 return (str == null ? "" : str.trim()); 112 } 113 114 /** 115 * <p> 116 * Removes control characters, including whitespace, from both ends of this String, handling <code>null</code> by 117 * returning <code>null</code>. 118 * </p> 119 * 120 * @see java.lang.String#trim() 121 * @param str the String to check 122 * @return the trimmed text (or <code>null</code>) 123 */ 124 public static String trim(String str) { 125 return (str == null ? null : str.trim()); 126 } 127 128 /** 129 * <p> 130 * Deletes all whitespaces from a String. 131 * </p> 132 * <p> 133 * Whitespace is defined by {@link Character#isWhitespace(char)}. 134 * </p> 135 * 136 * @param str String target to delete whitespace from 137 * @return the String without whitespaces 138 */ 139 public static String deleteWhitespace(String str) { 140 StringBuilder buffer = new StringBuilder(); 141 int sz = str.length(); 142 for (int i = 0; i < sz; i++) { 143 if (!Character.isWhitespace(str.charAt(i))) { 144 buffer.append(str.charAt(i)); 145 } 146 } 147 return buffer.toString(); 148 } 149 150 /** 151 * Checks if a String is non <code>null</code> and is not empty (<code>length > 0</code>). 152 * 153 * @param str the String to check 154 * @return true if the String is non-null, and not length zero 155 */ 156 public static boolean isNotEmpty(String str) { 157 return ((str != null) && (!str.isEmpty())); 158 } 159 160 /** 161 * Checks if a String is <code>null</code> or empty. 162 * <p> 163 * <strong>Note:</strong> In releases prior 3.5.0, this method trimmed the input string such that it worked 164 * the same as {@link #isBlank(String)}. Since release 3.5.0 it no longer returns {@code true} for strings 165 * containing only whitespace characters. 166 * 167 * @param str the String to check 168 * @return <code>true</code> if the String is <code>null</code>, or length zero 169 */ 170 public static boolean isEmpty(String str) { 171 return ((str == null) || (str.isEmpty())); 172 } 173 174 /** 175 * <p> 176 * Checks if a String is whitespace, empty ("") or null. 177 * </p> 178 * 179 * <pre> 180 * StringUtils.isBlank(null) = true 181 * StringUtils.isBlank("") = true 182 * StringUtils.isBlank(" ") = true 183 * StringUtils.isBlank("bob") = false 184 * StringUtils.isBlank(" bob ") = false 185 * </pre> 186 * 187 * @param str the String to check, may be null 188 * @return <code>true</code> if the String is null, empty or whitespace 189 * @since 1.5.2 190 */ 191 public static boolean isBlank(String str) { 192 int strLen; 193 if (str == null || (strLen = str.length()) == 0) { 194 return true; 195 } 196 for (int i = 0; i < strLen; i++) { 197 if (!Character.isWhitespace(str.charAt(i))) { 198 return false; 199 } 200 } 201 return true; 202 } 203 204 /** 205 * <p> 206 * Checks if a String is not empty (""), not null and not whitespace only. 207 * </p> 208 * 209 * <pre> 210 * StringUtils.isNotBlank(null) = false 211 * StringUtils.isNotBlank("") = false 212 * StringUtils.isNotBlank(" ") = false 213 * StringUtils.isNotBlank("bob") = true 214 * StringUtils.isNotBlank(" bob ") = true 215 * </pre> 216 * 217 * @param str the String to check, may be null 218 * @return <code>true</code> if the String is not empty and not null and not whitespace 219 * @since 1.5.2 220 */ 221 public static boolean isNotBlank(String str) { 222 return !StringUtils.isBlank(str); 223 } 224 225 // Equals and IndexOf 226 // -------------------------------------------------------------------------- 227 228 /** 229 * <p> 230 * Compares two Strings, returning <code>true</code> if they are equal. 231 * </p> 232 * <p> 233 * <code>null</code>s are handled without exceptions. Two <code>null</code> references are considered to be equal. 234 * The comparison is case sensitive. 235 * </p> 236 * 237 * @see java.lang.String#equals(Object) 238 * @param str1 the first string 239 * @param str2 the second string 240 * @return <code>true</code> if the Strings are equal, case sensitive, or both <code>null</code> 241 * @see Objects#equals(Object, Object) 242 */ 243 @Deprecated 244 public static boolean equals(String str1, String str2) { 245 return Objects.equals(str1, str2); 246 } 247 248 /** 249 * <p> 250 * Compares two Strings, returning <code>true</code> if they are equal ignoring the case. 251 * </p> 252 * <p> 253 * <code>Nulls</code> are handled without exceptions. Two <code>null</code> references are considered equal. 254 * Comparison is case insensitive. 255 * </p> 256 * 257 * @see java.lang.String#equalsIgnoreCase(String) 258 * @param str1 the first string 259 * @param str2 the second string 260 * @return <code>true</code> if the Strings are equal, case insensitive, or both <code>null</code> 261 */ 262 public static boolean equalsIgnoreCase(String str1, String str2) { 263 return (str1 == null ? str2 == null : str1.equalsIgnoreCase(str2)); 264 } 265 266 /** 267 * <p> 268 * Find the first index of any of a set of potential substrings. 269 * </p> 270 * <p> 271 * <code>null</code> String will return <code>-1</code>. 272 * </p> 273 * 274 * @param str the String to check 275 * @param searchStrs the Strings to search for 276 * @return the first index of any of the searchStrs in str 277 * @throws NullPointerException if any of searchStrs[i] is <code>null</code> 278 */ 279 public static int indexOfAny(String str, String[] searchStrs) { 280 if ((str == null) || (searchStrs == null)) { 281 return -1; 282 } 283 int sz = searchStrs.length; 284 285 // String's can't have a MAX_VALUEth index. 286 int ret = Integer.MAX_VALUE; 287 288 int tmp; 289 for (String searchStr : searchStrs) { 290 tmp = str.indexOf(searchStr); 291 if (tmp == -1) { 292 continue; 293 } 294 295 if (tmp < ret) { 296 ret = tmp; 297 } 298 } 299 300 return (ret == Integer.MAX_VALUE) ? -1 : ret; 301 } 302 303 /** 304 * <p> 305 * Find the latest index of any of a set of potential substrings. 306 * </p> 307 * <p> 308 * <code>null</code> string will return <code>-1</code>. 309 * </p> 310 * 311 * @param str the String to check 312 * @param searchStrs the Strings to search for 313 * @return the last index of any of the Strings 314 * @throws NullPointerException if any of searchStrs[i] is <code>null</code> 315 */ 316 public static int lastIndexOfAny(String str, String[] searchStrs) { 317 if ((str == null) || (searchStrs == null)) { 318 return -1; 319 } 320 int ret = -1; 321 int tmp; 322 for (String searchStr : searchStrs) { 323 tmp = str.lastIndexOf(searchStr); 324 if (tmp > ret) { 325 ret = tmp; 326 } 327 } 328 return ret; 329 } 330 331 // Substring 332 // -------------------------------------------------------------------------- 333 334 /** 335 * <p> 336 * Gets a substring from the specified string avoiding exceptions. 337 * </p> 338 * <p> 339 * A negative start position can be used to start <code>n</code> characters from the end of the String. 340 * </p> 341 * 342 * @param str the String to get the substring from 343 * @param start the position to start from, negative means count back from the end of the String by this many 344 * characters 345 * @return substring from start position 346 */ 347 public static String substring(String str, int start) { 348 if (str == null) { 349 return null; 350 } 351 352 // handle negatives, which means last n characters 353 if (start < 0) { 354 start = str.length() + start; // remember start is negative 355 } 356 357 if (start < 0) { 358 start = 0; 359 } 360 if (start > str.length()) { 361 return ""; 362 } 363 364 return str.substring(start); 365 } 366 367 /** 368 * <p> 369 * Gets a substring from the specified String avoiding exceptions. 370 * </p> 371 * <p> 372 * A negative start position can be used to start/end <code>n</code> characters from the end of the String. 373 * </p> 374 * 375 * @param str the String to get the substring from 376 * @param start the position to start from, negative means count back from the end of the string by this many 377 * characters 378 * @param end the position to end at (exclusive), negative means count back from the end of the String by this many 379 * characters 380 * @return substring from start position to end position 381 */ 382 public static String substring(String str, int start, int end) { 383 if (str == null) { 384 return null; 385 } 386 387 // handle negatives 388 if (end < 0) { 389 end = str.length() + end; // remember end is negative 390 } 391 if (start < 0) { 392 start = str.length() + start; // remember start is negative 393 } 394 395 // check length next 396 if (end > str.length()) { 397 // check this works. 398 end = str.length(); 399 } 400 401 // if start is greater than end, return "" 402 if (start > end) { 403 return ""; 404 } 405 406 if (start < 0) { 407 start = 0; 408 } 409 if (end < 0) { 410 end = 0; 411 } 412 413 return str.substring(start, end); 414 } 415 416 /** 417 * <p> 418 * Gets the leftmost <code>n</code> characters of a String. 419 * </p> 420 * <p> 421 * If <code>n</code> characters are not available, or the String is <code>null</code>, the String will be returned 422 * without an exception. 423 * </p> 424 * 425 * @param str the String to get the leftmost characters from 426 * @param len the length of the required String 427 * @return the leftmost characters 428 * @throws IllegalArgumentException if len is less than zero 429 */ 430 public static String left(String str, int len) { 431 if (len < 0) { 432 throw new IllegalArgumentException("Requested String length " + len + " is less than zero"); 433 } 434 if ((str == null) || (str.length() <= len)) { 435 return str; 436 } else { 437 return str.substring(0, len); 438 } 439 } 440 441 /** 442 * <p> 443 * Gets the rightmost <code>n</code> characters of a String. 444 * </p> 445 * <p> 446 * If <code>n</code> characters are not available, or the String is <code>null</code>, the String will be returned 447 * without an exception. 448 * </p> 449 * 450 * @param str the String to get the rightmost characters from 451 * @param len the length of the required String 452 * @return the leftmost characters 453 * @throws IllegalArgumentException if len is less than zero 454 */ 455 public static String right(String str, int len) { 456 if (len < 0) { 457 throw new IllegalArgumentException("Requested String length " + len + " is less than zero"); 458 } 459 if ((str == null) || (str.length() <= len)) { 460 return str; 461 } else { 462 return str.substring(str.length() - len); 463 } 464 } 465 466 /** 467 * <p> 468 * Gets <code>n</code> characters from the middle of a String. 469 * </p> 470 * <p> 471 * If <code>n</code> characters are not available, the remainder of the String will be returned without an 472 * exception. If the String is <code>null</code>, <code>null</code> will be returned. 473 * </p> 474 * 475 * @param str the String to get the characters from 476 * @param pos the position to start from 477 * @param len the length of the required String 478 * @return the leftmost characters 479 * @throws IndexOutOfBoundsException if pos is out of bounds 480 * @throws IllegalArgumentException if len is less than zero 481 */ 482 public static String mid(String str, int pos, int len) { 483 if ((pos < 0) || ((str != null) && (pos > str.length()))) { 484 throw new StringIndexOutOfBoundsException("String index " + pos + " is out of bounds"); 485 } 486 if (len < 0) { 487 throw new IllegalArgumentException("Requested String length " + len + " is less than zero"); 488 } 489 if (str == null) { 490 return null; 491 } 492 if (str.length() <= (pos + len)) { 493 return str.substring(pos); 494 } else { 495 return str.substring(pos, pos + len); 496 } 497 } 498 499 // Splitting 500 // -------------------------------------------------------------------------- 501 502 /** 503 * <p> 504 * Splits the provided text into a array, using whitespace as the separator. 505 * </p> 506 * <p> 507 * The separator is not included in the returned String array. 508 * </p> 509 * 510 * @param str the String to parse 511 * @return an array of parsed Strings 512 */ 513 public static String[] split(String str) { 514 return split(str, null, -1); 515 } 516 517 /** 518 * @param text The string to parse. 519 * @param separator Characters used as the delimiters. If <code>null</code>, splits on whitespace. 520 * @return an array of parsed Strings 521 */ 522 public static String[] split(String text, String separator) { 523 return split(text, separator, -1); 524 } 525 526 /** 527 * <p> 528 * Splits the provided text into a array, based on a given separator. 529 * </p> 530 * <p> 531 * The separator is not included in the returned String array. The maximum number of splits to perform can be 532 * controlled. A <code>null</code> separator will cause parsing to be on whitespace. 533 * </p> 534 * <p> 535 * This is useful for quickly splitting a String directly into an array of tokens, instead of an enumeration of 536 * tokens (as <code>StringTokenizer</code> does). 537 * </p> 538 * 539 * @param str The string to parse. 540 * @param separator Characters used as the delimiters. If <code>null</code>, splits on whitespace. 541 * @param max The maximum number of elements to include in the array. A zero or negative value implies no limit. 542 * @return an array of parsed Strings 543 */ 544 public static String[] split(String str, String separator, int max) { 545 StringTokenizer tok; 546 if (separator == null) { 547 // Null separator means we're using StringTokenizer's default 548 // delimiter, which comprises all whitespace characters. 549 tok = new StringTokenizer(str); 550 } else { 551 tok = new StringTokenizer(str, separator); 552 } 553 554 int listSize = tok.countTokens(); 555 if ((max > 0) && (listSize > max)) { 556 listSize = max; 557 } 558 559 String[] list = new String[listSize]; 560 int i = 0; 561 int lastTokenBegin; 562 int lastTokenEnd = 0; 563 while (tok.hasMoreTokens()) { 564 if ((max > 0) && (i == listSize - 1)) { 565 // In the situation where we hit the max yet have 566 // tokens left over in our input, the last list 567 // element gets all remaining text. 568 String endToken = tok.nextToken(); 569 lastTokenBegin = str.indexOf(endToken, lastTokenEnd); 570 list[i] = str.substring(lastTokenBegin); 571 break; 572 } else { 573 list[i] = tok.nextToken(); 574 lastTokenBegin = str.indexOf(list[i], lastTokenEnd); 575 lastTokenEnd = lastTokenBegin + list[i].length(); 576 } 577 i++; 578 } 579 return list; 580 } 581 582 // Joining 583 // -------------------------------------------------------------------------- 584 /** 585 * <p> 586 * Concatenates elements of an array into a single String. 587 * </p> 588 * <p> 589 * The difference from join is that concatenate has no delimiter. 590 * </p> 591 * 592 * @param array the array of values to concatenate. 593 * @return the concatenated string. 594 */ 595 public static String concatenate(Object[] array) { 596 return join(array, ""); 597 } 598 599 /** 600 * <p> 601 * Joins the elements of the provided array into a single String containing the provided list of elements. 602 * </p> 603 * <p> 604 * No delimiter is added before or after the list. A <code>null</code> separator is the same as a blank String. 605 * </p> 606 * 607 * @param array the array of values to join together 608 * @param separator the separator character to use 609 * @return the joined String 610 */ 611 public static String join(Object[] array, String separator) { 612 if (separator == null) { 613 separator = ""; 614 } 615 int arraySize = array.length; 616 int bufSize = (arraySize == 0 ? 0 : (array[0].toString().length() + separator.length()) * arraySize); 617 StringBuilder buf = new StringBuilder(bufSize); 618 619 for (int i = 0; i < arraySize; i++) { 620 if (i > 0) { 621 buf.append(separator); 622 } 623 buf.append(array[i]); 624 } 625 return buf.toString(); 626 } 627 628 /** 629 * <p> 630 * Joins the elements of the provided <code>Iterator</code> into a single String containing the provided elements. 631 * </p> 632 * <p> 633 * No delimiter is added before or after the list. A <code>null</code> separator is the same as a blank String. 634 * </p> 635 * 636 * @param iterator the <code>Iterator</code> of values to join together 637 * @param separator the separator character to use 638 * @return the joined String 639 */ 640 public static String join(Iterator<?> iterator, String separator) { 641 if (separator == null) { 642 separator = ""; 643 } 644 StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small 645 while (iterator.hasNext()) { 646 buf.append(iterator.next()); 647 if (iterator.hasNext()) { 648 buf.append(separator); 649 } 650 } 651 return buf.toString(); 652 } 653 654 // Replacing 655 // -------------------------------------------------------------------------- 656 657 /** 658 * <p> 659 * Replace a char with another char inside a larger String, once. 660 * </p> 661 * <p> 662 * A <code>null</code> reference passed to this method is a no-op. 663 * </p> 664 * 665 * @see #replace(String text, char repl, char with, int max) 666 * @param text text to search and replace in 667 * @param repl char to search for 668 * @param with char to replace with 669 * @return the text with any replacements processed 670 */ 671 public static String replaceOnce(String text, char repl, char with) { 672 return replace(text, repl, with, 1); 673 } 674 675 /** 676 * <p> 677 * Replace all occurrences of a char within another char. 678 * </p> 679 * <p> 680 * A <code>null</code> reference passed to this method is a no-op. 681 * </p> 682 * 683 * @see #replace(String text, char repl, char with, int max) 684 * @param text text to search and replace in 685 * @param repl char to search for 686 * @param with char to replace with 687 * @return the text with any replacements processed 688 */ 689 public static String replace(String text, char repl, char with) { 690 return replace(text, repl, with, -1); 691 } 692 693 /** 694 * <p> 695 * Replace a char with another char inside a larger String, for the first <code>max</code> values of the search 696 * char. 697 * </p> 698 * <p> 699 * A <code>null</code> reference passed to this method is a no-op. 700 * </p> 701 * 702 * @param text text to search and replace in 703 * @param repl char to search for 704 * @param with char to replace with 705 * @param max maximum number of values to replace, or <code>-1</code> if no maximum 706 * @return the text with any replacements processed 707 */ 708 public static String replace(String text, char repl, char with, int max) { 709 return replace(text, String.valueOf(repl), String.valueOf(with), max); 710 } 711 712 /** 713 * <p> 714 * Replace a String with another String inside a larger String, once. 715 * </p> 716 * <p> 717 * A <code>null</code> reference passed to this method is a no-op. 718 * </p> 719 * 720 * @see #replace(String text, String repl, String with, int max) 721 * @param text text to search and replace in 722 * @param repl String to search for 723 * @param with String to replace with 724 * @return the text with any replacements processed 725 */ 726 public static String replaceOnce(String text, String repl, String with) { 727 return replace(text, repl, with, 1); 728 } 729 730 /** 731 * <p> 732 * Replace all occurrences of a String within another String. 733 * </p> 734 * <p> 735 * A <code>null</code> reference passed to this method is a no-op. 736 * </p> 737 * 738 * @see #replace(String text, String repl, String with, int max) 739 * @param text text to search and replace in 740 * @param repl String to search for 741 * @param with String to replace with 742 * @return the text with any replacements processed 743 */ 744 public static String replace(String text, String repl, String with) { 745 return replace(text, repl, with, -1); 746 } 747 748 /** 749 * <p> 750 * Replace a String with another String inside a larger String, for the first <code>max</code> values of the search 751 * String. 752 * </p> 753 * <p> 754 * A <code>null</code> reference passed to this method is a no-op. 755 * </p> 756 * 757 * @param text text to search and replace in 758 * @param repl String to search for 759 * @param with String to replace with 760 * @param max maximum number of values to replace, or <code>-1</code> if no maximum 761 * @return the text with any replacements processed 762 */ 763 public static String replace(String text, String repl, String with, int max) { 764 if ((text == null) || (repl == null) || (with == null) || (repl.length() == 0)) { 765 return text; 766 } 767 768 StringBuilder buf = new StringBuilder(text.length()); 769 int start = 0, end; 770 while ((end = text.indexOf(repl, start)) != -1) { 771 buf.append(text, start, end).append(with); 772 start = end + repl.length(); 773 774 if (--max == 0) { 775 break; 776 } 777 } 778 buf.append(text, start, text.length()); 779 return buf.toString(); 780 } 781 782 /** 783 * <p> 784 * Overlay a part of a String with another String. 785 * </p> 786 * 787 * @param text String to do overlaying in 788 * @param overlay String to overlay 789 * @param start int to start overlaying at 790 * @param end int to stop overlaying before 791 * @return String with overlayed text 792 * @throws NullPointerException if text or overlay is <code>null</code> 793 */ 794 public static String overlayString(String text, String overlay, int start, int end) { 795 return new StringBuilder(start + overlay.length() + text.length() - end + 1) 796 .append(text, 0, start) 797 .append(overlay) 798 .append(text, end, text.length()) 799 .toString(); 800 } 801 802 // Centering 803 // -------------------------------------------------------------------------- 804 805 /** 806 * <p> 807 * Center a String in a larger String of size <code>n</code>. 808 * </p> 809 * <p> 810 * Uses spaces as the value to buffer the String with. Equivalent to <code>center(str, size, " ")</code>. 811 * </p> 812 * 813 * @param str String to center 814 * @param size int size of new String 815 * @return String containing centered String 816 * @throws NullPointerException if str is <code>null</code> 817 */ 818 public static String center(String str, int size) { 819 return center(str, size, " "); 820 } 821 822 /** 823 * <p> 824 * Center a String in a larger String of size <code>n</code>. 825 * </p> 826 * <p> 827 * Uses a supplied String as the value to buffer the String with. 828 * </p> 829 * 830 * @param str String to center 831 * @param size int size of new String 832 * @param delim String to buffer the new String with 833 * @return String containing centered String 834 * @throws NullPointerException if str or delim is <code>null</code> 835 * @throws ArithmeticException if delim is the empty String 836 */ 837 public static String center(String str, int size, String delim) { 838 int sz = str.length(); 839 int p = size - sz; 840 if (p < 1) { 841 return str; 842 } 843 str = leftPad(str, sz + p / 2, delim); 844 str = rightPad(str, size, delim); 845 return str; 846 } 847 848 // Chomping 849 // -------------------------------------------------------------------------- 850 851 /** 852 * <p> 853 * Remove the last newline, and everything after it from a String. 854 * </p> 855 * 856 * @param str String to chomp the newline from 857 * @return String without chomped newline 858 * @throws NullPointerException if str is <code>null</code> 859 */ 860 public static String chomp(String str) { 861 return chomp(str, "\n"); 862 } 863 864 /** 865 * <p> 866 * Remove the last value of a supplied String, and everything after it from a String. 867 * </p> 868 * 869 * @param str String to chomp from 870 * @param sep String to chomp 871 * @return String without chomped ending 872 * @throws NullPointerException if str or sep is <code>null</code> 873 */ 874 public static String chomp(String str, String sep) { 875 int idx = str.lastIndexOf(sep); 876 if (idx != -1) { 877 return str.substring(0, idx); 878 } else { 879 return str; 880 } 881 } 882 883 /** 884 * <p> 885 * Remove a newline if and only if it is at the end of the supplied String. 886 * </p> 887 * 888 * @param str String to chomp from 889 * @return String without chomped ending 890 * @throws NullPointerException if str is <code>null</code> 891 */ 892 public static String chompLast(String str) { 893 return chompLast(str, "\n"); 894 } 895 896 /** 897 * <p> 898 * Remove a value if and only if the String ends with that value. 899 * </p> 900 * 901 * @param str String to chomp from 902 * @param sep String to chomp 903 * @return String without chomped ending 904 * @throws NullPointerException if str or sep is <code>null</code> 905 */ 906 public static String chompLast(String str, String sep) { 907 if (str.length() == 0) { 908 return str; 909 } 910 String sub = str.substring(str.length() - sep.length()); 911 if (sep.equals(sub)) { 912 return str.substring(0, str.length() - sep.length()); 913 } else { 914 return str; 915 } 916 } 917 918 /** 919 * <p> 920 * Remove everything and return the last value of a supplied String, and everything after it from a String. 921 * </p> 922 * 923 * @param str String to chomp from 924 * @param sep String to chomp 925 * @return String chomped 926 * @throws NullPointerException if str or sep is <code>null</code> 927 */ 928 public static String getChomp(String str, String sep) { 929 int idx = str.lastIndexOf(sep); 930 if (idx == str.length() - sep.length()) { 931 return sep; 932 } else if (idx != -1) { 933 return str.substring(idx); 934 } else { 935 return ""; 936 } 937 } 938 939 /** 940 * <p> 941 * Remove the first value of a supplied String, and everything before it from a String. 942 * </p> 943 * 944 * @param str String to chomp from 945 * @param sep String to chomp 946 * @return String without chomped beginning 947 * @throws NullPointerException if str or sep is <code>null</code> 948 */ 949 public static String prechomp(String str, String sep) { 950 int idx = str.indexOf(sep); 951 if (idx != -1) { 952 return str.substring(idx + sep.length()); 953 } else { 954 return str; 955 } 956 } 957 958 /** 959 * <p> 960 * Remove and return everything before the first value of a supplied String from another String. 961 * </p> 962 * 963 * @param str String to chomp from 964 * @param sep String to chomp 965 * @return String prechomped 966 * @throws NullPointerException if str or sep is <code>null</code> 967 */ 968 public static String getPrechomp(String str, String sep) { 969 int idx = str.indexOf(sep); 970 if (idx != -1) { 971 return str.substring(0, idx + sep.length()); 972 } else { 973 return ""; 974 } 975 } 976 977 // Chopping 978 // -------------------------------------------------------------------------- 979 980 /** 981 * <p> 982 * Remove the last character from a String. 983 * </p> 984 * <p> 985 * If the String ends in <code>\r\n</code>, then remove both of them. 986 * </p> 987 * 988 * @param str String to chop last character from 989 * @return String without last character 990 * @throws NullPointerException if str is <code>null</code> 991 */ 992 public static String chop(String str) { 993 if ("".equals(str)) { 994 return ""; 995 } 996 if (str.length() == 1) { 997 return ""; 998 } 999 int lastIdx = str.length() - 1; 1000 String ret = str.substring(0, lastIdx); 1001 char last = str.charAt(lastIdx); 1002 if (last == '\n') { 1003 if (ret.charAt(lastIdx - 1) == '\r') { 1004 return ret.substring(0, lastIdx - 1); 1005 } 1006 } 1007 return ret; 1008 } 1009 1010 /** 1011 * <p> 1012 * Remove <code>\n</code> from end of a String if it's there. If a <code>\r</code> precedes it, then remove that 1013 * too. 1014 * </p> 1015 * 1016 * @param str String to chop a newline from 1017 * @return String without newline 1018 * @throws NullPointerException if str is <code>null</code> 1019 */ 1020 public static String chopNewline(String str) { 1021 int lastIdx = str.length() - 1; 1022 char last = str.charAt(lastIdx); 1023 if (last == '\n') { 1024 if (str.charAt(lastIdx - 1) == '\r') { 1025 lastIdx--; 1026 } 1027 } else { 1028 lastIdx++; 1029 } 1030 return str.substring(0, lastIdx); 1031 } 1032 1033 // Conversion 1034 // -------------------------------------------------------------------------- 1035 1036 // spec 3.10.6 1037 /** 1038 * <p> 1039 * Escapes any values it finds into their String form. 1040 * </p> 1041 * <p> 1042 * So a tab becomes the characters <code>'\\'</code> and <code>'t'</code>. 1043 * </p> 1044 * 1045 * @param str String to escape values in 1046 * @return String with escaped values 1047 * @throws NullPointerException if str is <code>null</code> 1048 */ 1049 public static String escape(String str) { 1050 // improved with code from cybertiger@cyberiantiger.org 1051 // unicode from him, and default for < 32's. 1052 int sz = str.length(); 1053 StringBuilder buffer = new StringBuilder(2 * sz); 1054 for (int i = 0; i < sz; i++) { 1055 char ch = str.charAt(i); 1056 1057 // handle unicode 1058 if (ch > 0xfff) { 1059 buffer.append("\\u" + Integer.toHexString(ch)); 1060 } else if (ch > 0xff) { 1061 buffer.append("\\u0" + Integer.toHexString(ch)); 1062 } else if (ch > 0x7f) { 1063 buffer.append("\\u00" + Integer.toHexString(ch)); 1064 } else if (ch < 32) { 1065 switch (ch) { 1066 case '\b': 1067 buffer.append('\\'); 1068 buffer.append('b'); 1069 break; 1070 case '\n': 1071 buffer.append('\\'); 1072 buffer.append('n'); 1073 break; 1074 case '\t': 1075 buffer.append('\\'); 1076 buffer.append('t'); 1077 break; 1078 case '\f': 1079 buffer.append('\\'); 1080 buffer.append('f'); 1081 break; 1082 case '\r': 1083 buffer.append('\\'); 1084 buffer.append('r'); 1085 break; 1086 default: 1087 if (ch > 0xf) { 1088 buffer.append("\\u00" + Integer.toHexString(ch)); 1089 } else { 1090 buffer.append("\\u000" + Integer.toHexString(ch)); 1091 } 1092 break; 1093 } 1094 } else { 1095 switch (ch) { 1096 case '\'': 1097 buffer.append('\\'); 1098 buffer.append('\''); 1099 break; 1100 case '"': 1101 buffer.append('\\'); 1102 buffer.append('"'); 1103 break; 1104 case '\\': 1105 buffer.append('\\'); 1106 buffer.append('\\'); 1107 break; 1108 default: 1109 buffer.append(ch); 1110 break; 1111 } 1112 } 1113 } 1114 return buffer.toString(); 1115 } 1116 1117 // Padding 1118 // -------------------------------------------------------------------------- 1119 1120 /** 1121 * <p> 1122 * Repeat a String <code>n</code> times to form a new string. 1123 * </p> 1124 * 1125 * @param str String to repeat 1126 * @param repeat number of times to repeat str 1127 * @return String with repeated String 1128 * @throws NegativeArraySizeException if <code>repeat < 0</code> 1129 * @throws NullPointerException if str is <code>null</code> 1130 */ 1131 public static String repeat(String str, int repeat) { 1132 StringBuilder buffer = new StringBuilder(repeat * str.length()); 1133 for (int i = 0; i < repeat; i++) { 1134 buffer.append(str); 1135 } 1136 return buffer.toString(); 1137 } 1138 1139 /** 1140 * <p> 1141 * Right pad a String with spaces. 1142 * </p> 1143 * <p> 1144 * The String is padded to the size of <code>n</code>. 1145 * </p> 1146 * 1147 * @param str String to repeat 1148 * @param size number of times to repeat str 1149 * @return right padded String 1150 * @throws NullPointerException if str is <code>null</code> 1151 */ 1152 public static String rightPad(String str, int size) { 1153 return rightPad(str, size, " "); 1154 } 1155 1156 /** 1157 * <p> 1158 * Right pad a String with a specified string. 1159 * </p> 1160 * <p> 1161 * The String is padded to the size of <code>n</code>. 1162 * </p> 1163 * 1164 * @param str String to pad out 1165 * @param size size to pad to 1166 * @param delim String to pad with 1167 * @return right padded String 1168 * @throws NullPointerException if str or delim is <code>null</code> 1169 * @throws ArithmeticException if delim is the empty String 1170 */ 1171 public static String rightPad(String str, int size, String delim) { 1172 size = (size - str.length()) / delim.length(); 1173 if (size > 0) { 1174 str += repeat(delim, size); 1175 } 1176 return str; 1177 } 1178 1179 /** 1180 * <p> 1181 * Left pad a String with spaces. 1182 * </p> 1183 * <p> 1184 * The String is padded to the size of <code>n</code>. 1185 * </p> 1186 * 1187 * @param str String to pad out 1188 * @param size size to pad to 1189 * @return left padded String 1190 * @throws NullPointerException if str or delim is <code>null</code> 1191 */ 1192 public static String leftPad(String str, int size) { 1193 return leftPad(str, size, " "); 1194 } 1195 1196 /** 1197 * Left pad a String with a specified string. Pad to a size of n. 1198 * 1199 * @param str String to pad out 1200 * @param size size to pad to 1201 * @param delim String to pad with 1202 * @return left padded String 1203 * @throws NullPointerException if str or delim is null 1204 * @throws ArithmeticException if delim is the empty string 1205 */ 1206 public static String leftPad(String str, int size, String delim) { 1207 size = (size - str.length()) / delim.length(); 1208 if (size > 0) { 1209 str = repeat(delim, size) + str; 1210 } 1211 return str; 1212 } 1213 1214 // Stripping 1215 // -------------------------------------------------------------------------- 1216 1217 /** 1218 * <p> 1219 * Remove whitespace from the front and back of a String. 1220 * </p> 1221 * 1222 * @param str the String to remove whitespace from 1223 * @return the stripped String 1224 */ 1225 public static String strip(String str) { 1226 return strip(str, null); 1227 } 1228 1229 /** 1230 * <p> 1231 * Remove a specified String from the front and back of a String. 1232 * </p> 1233 * <p> 1234 * If whitespace is wanted to be removed, used the {@link #strip(java.lang.String)} method. 1235 * </p> 1236 * 1237 * @param str the String to remove a string from 1238 * @param delim the String to remove at start and end 1239 * @return the stripped String 1240 */ 1241 public static String strip(String str, String delim) { 1242 str = stripStart(str, delim); 1243 return stripEnd(str, delim); 1244 } 1245 1246 /** 1247 * <p> 1248 * Strip whitespace from the front and back of every String in the array. 1249 * </p> 1250 * 1251 * @param strs the Strings to remove whitespace from 1252 * @return the stripped Strings 1253 */ 1254 public static String[] stripAll(String[] strs) { 1255 return stripAll(strs, null); 1256 } 1257 1258 /** 1259 * <p> 1260 * Strip the specified delimiter from the front and back of every String in the array. 1261 * </p> 1262 * 1263 * @param strs the Strings to remove a String from 1264 * @param delimiter the String to remove at start and end 1265 * @return the stripped Strings 1266 */ 1267 public static String[] stripAll(String[] strs, String delimiter) { 1268 if ((strs == null) || (strs.length == 0)) { 1269 return strs; 1270 } 1271 int sz = strs.length; 1272 String[] newArr = new String[sz]; 1273 for (int i = 0; i < sz; i++) { 1274 newArr[i] = strip(strs[i], delimiter); 1275 } 1276 return newArr; 1277 } 1278 1279 /** 1280 * <p> 1281 * Strip any of a supplied String from the end of a String. 1282 * </p> 1283 * <p> 1284 * If the strip String is <code>null</code>, whitespace is stripped. 1285 * </p> 1286 * 1287 * @param str the String to remove characters from 1288 * @param strip the String to remove 1289 * @return the stripped String 1290 */ 1291 public static String stripEnd(String str, String strip) { 1292 if (str == null) { 1293 return null; 1294 } 1295 int end = str.length(); 1296 1297 if (strip == null) { 1298 while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) { 1299 end--; 1300 } 1301 } else { 1302 while ((end != 0) && (strip.indexOf(str.charAt(end - 1)) != -1)) { 1303 end--; 1304 } 1305 } 1306 return str.substring(0, end); 1307 } 1308 1309 /** 1310 * <p> 1311 * Strip any of a supplied String from the start of a String. 1312 * </p> 1313 * <p> 1314 * If the strip String is <code>null</code>, whitespace is stripped. 1315 * </p> 1316 * 1317 * @param str the String to remove characters from 1318 * @param strip the String to remove 1319 * @return the stripped String 1320 */ 1321 public static String stripStart(String str, String strip) { 1322 if (str == null) { 1323 return null; 1324 } 1325 1326 int start = 0; 1327 1328 int sz = str.length(); 1329 1330 if (strip == null) { 1331 while ((start != sz) && Character.isWhitespace(str.charAt(start))) { 1332 start++; 1333 } 1334 } else { 1335 while ((start != sz) && (strip.indexOf(str.charAt(start)) != -1)) { 1336 start++; 1337 } 1338 } 1339 return str.substring(start); 1340 } 1341 1342 // Case conversion 1343 // -------------------------------------------------------------------------- 1344 1345 /** 1346 * <p> 1347 * Convert a String to upper case, <code>null</code> String returns <code>null</code>. 1348 * </p> 1349 * 1350 * @param str the String to uppercase 1351 * @return the upper cased String 1352 */ 1353 public static String upperCase(String str) { 1354 if (str == null) { 1355 return null; 1356 } 1357 return str.toUpperCase(); 1358 } 1359 1360 /** 1361 * <p> 1362 * Convert a String to lower case, <code>null</code> String returns <code>null</code>. 1363 * </p> 1364 * 1365 * @param str the string to lowercase 1366 * @return the lower cased String 1367 */ 1368 public static String lowerCase(String str) { 1369 if (str == null) { 1370 return null; 1371 } 1372 return str.toLowerCase(); 1373 } 1374 1375 /** 1376 * <p> 1377 * Uncapitalise a String. 1378 * </p> 1379 * <p> 1380 * That is, convert the first character into lower-case. <code>null</code> is returned as <code>null</code>. 1381 * </p> 1382 * 1383 * @param str the String to uncapitalise 1384 * @return uncapitalised String 1385 */ 1386 public static String uncapitalise(String str) { 1387 if (str == null) { 1388 return null; 1389 } else if (str.length() == 0) { 1390 return ""; 1391 } else { 1392 return new StringBuilder(str.length()) 1393 .append(Character.toLowerCase(str.charAt(0))) 1394 .append(str, 1, str.length()) 1395 .toString(); 1396 } 1397 } 1398 1399 /** 1400 * <p> 1401 * Capitalise a String. 1402 * </p> 1403 * <p> 1404 * That is, convert the first character into title-case. <code>null</code> is returned as <code>null</code>. 1405 * </p> 1406 * 1407 * @param str the String to capitalise 1408 * @return capitalised String 1409 */ 1410 public static String capitalise(String str) { 1411 if (str == null) { 1412 return null; 1413 } else if (str.length() == 0) { 1414 return ""; 1415 } else { 1416 return new StringBuilder(str.length()) 1417 .append(Character.toTitleCase(str.charAt(0))) 1418 .append(str, 1, str.length()) 1419 .toString(); 1420 } 1421 } 1422 1423 /** 1424 * <p> 1425 * Swaps the case of String. 1426 * </p> 1427 * <p> 1428 * Properly looks after making sure the start of words are Titlecase and not Uppercase. 1429 * </p> 1430 * <p> 1431 * <code>null</code> is returned as <code>null</code>. 1432 * </p> 1433 * 1434 * @param str the String to swap the case of 1435 * @return the modified String 1436 */ 1437 public static String swapCase(String str) { 1438 if (str == null) { 1439 return null; 1440 } 1441 int sz = str.length(); 1442 StringBuilder buffer = new StringBuilder(sz); 1443 1444 boolean whitespace = false; 1445 char ch; 1446 char tmp; 1447 1448 for (int i = 0; i < sz; i++) { 1449 ch = str.charAt(i); 1450 if (Character.isUpperCase(ch)) { 1451 tmp = Character.toLowerCase(ch); 1452 } else if (Character.isTitleCase(ch)) { 1453 tmp = Character.toLowerCase(ch); 1454 } else if (Character.isLowerCase(ch)) { 1455 if (whitespace) { 1456 tmp = Character.toTitleCase(ch); 1457 } else { 1458 tmp = Character.toUpperCase(ch); 1459 } 1460 } else { 1461 tmp = ch; 1462 } 1463 buffer.append(tmp); 1464 whitespace = Character.isWhitespace(ch); 1465 } 1466 return buffer.toString(); 1467 } 1468 1469 /** 1470 * <p> 1471 * Capitalise all the words in a String. 1472 * </p> 1473 * <p> 1474 * Uses {@link Character#isWhitespace(char)} as a separator between words. 1475 * </p> 1476 * <p> 1477 * <code>null</code> will return <code>null</code>. 1478 * </p> 1479 * 1480 * @param str the String to capitalise 1481 * @return capitalised String 1482 */ 1483 public static String capitaliseAllWords(String str) { 1484 if (str == null) { 1485 return null; 1486 } 1487 int sz = str.length(); 1488 StringBuilder buffer = new StringBuilder(sz); 1489 boolean space = true; 1490 for (int i = 0; i < sz; i++) { 1491 char ch = str.charAt(i); 1492 if (Character.isWhitespace(ch)) { 1493 buffer.append(ch); 1494 space = true; 1495 } else if (space) { 1496 buffer.append(Character.toTitleCase(ch)); 1497 space = false; 1498 } else { 1499 buffer.append(ch); 1500 } 1501 } 1502 return buffer.toString(); 1503 } 1504 1505 /** 1506 * <p> 1507 * Uncapitalise all the words in a string. 1508 * </p> 1509 * <p> 1510 * Uses {@link Character#isWhitespace(char)} as a separator between words. 1511 * </p> 1512 * <p> 1513 * <code>null</code> will return <code>null</code>. 1514 * </p> 1515 * 1516 * @param str the string to uncapitalise 1517 * @return uncapitalised string 1518 */ 1519 public static String uncapitaliseAllWords(String str) { 1520 if (str == null) { 1521 return null; 1522 } 1523 int sz = str.length(); 1524 StringBuilder buffer = new StringBuilder(sz); 1525 boolean space = true; 1526 for (int i = 0; i < sz; i++) { 1527 char ch = str.charAt(i); 1528 if (Character.isWhitespace(ch)) { 1529 buffer.append(ch); 1530 space = true; 1531 } else if (space) { 1532 buffer.append(Character.toLowerCase(ch)); 1533 space = false; 1534 } else { 1535 buffer.append(ch); 1536 } 1537 } 1538 return buffer.toString(); 1539 } 1540 1541 // Nested extraction 1542 // -------------------------------------------------------------------------- 1543 1544 /** 1545 * <p> 1546 * Get the String that is nested in between two instances of the same String. 1547 * </p> 1548 * <p> 1549 * If <code>str</code> is <code>null</code>, will return <code>null</code>. 1550 * </p> 1551 * 1552 * @param str the String containing nested-string 1553 * @param tag the String before and after nested-string 1554 * @return the String that was nested, or <code>null</code> 1555 * @throws NullPointerException if tag is <code>null</code> 1556 */ 1557 public static String getNestedString(String str, String tag) { 1558 return getNestedString(str, tag, tag); 1559 } 1560 1561 /** 1562 * <p> 1563 * Get the String that is nested in between two Strings. 1564 * </p> 1565 * 1566 * @param str the String containing nested-string 1567 * @param open the String before nested-string 1568 * @param close the String after nested-string 1569 * @return the String that was nested, or <code>null</code> 1570 * @throws NullPointerException if open or close is <code>null</code> 1571 */ 1572 public static String getNestedString(String str, String open, String close) { 1573 if (str == null) { 1574 return null; 1575 } 1576 int start = str.indexOf(open); 1577 if (start != -1) { 1578 int end = str.indexOf(close, start + open.length()); 1579 if (end != -1) { 1580 return str.substring(start + open.length(), end); 1581 } 1582 } 1583 return null; 1584 } 1585 1586 /** 1587 * <p> 1588 * How many times is the substring in the larger String. 1589 * </p> 1590 * <p> 1591 * <code>null</code> returns <code>0</code>. 1592 * </p> 1593 * 1594 * @param str the String to check 1595 * @param sub the substring to count 1596 * @return the number of occurrences, 0 if the String is <code>null</code> 1597 * @throws NullPointerException if sub is <code>null</code> 1598 */ 1599 public static int countMatches(String str, String sub) { 1600 if (sub.equals("")) { 1601 return 0; 1602 } 1603 if (str == null) { 1604 return 0; 1605 } 1606 int count = 0; 1607 int idx = 0; 1608 while ((idx = str.indexOf(sub, idx)) != -1) { 1609 count++; 1610 idx += sub.length(); 1611 } 1612 return count; 1613 } 1614 1615 // Character Tests 1616 // -------------------------------------------------------------------------- 1617 1618 /** 1619 * <p> 1620 * Checks if the String contains only unicode letters. 1621 * </p> 1622 * <p> 1623 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1624 * </p> 1625 * 1626 * @param str the String to check 1627 * @return <code>true</code> if only contains letters, and is non-null 1628 */ 1629 public static boolean isAlpha(String str) { 1630 if (str == null) { 1631 return false; 1632 } 1633 int sz = str.length(); 1634 for (int i = 0; i < sz; i++) { 1635 if (Character.isLetter(str.charAt(i)) == false) { 1636 return false; 1637 } 1638 } 1639 return true; 1640 } 1641 1642 /** 1643 * <p> 1644 * Checks if the String contains only whitespace. 1645 * </p> 1646 * <p> 1647 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1648 * </p> 1649 * 1650 * @param str the String to check 1651 * @return <code>true</code> if only contains whitespace, and is non-null 1652 */ 1653 public static boolean isWhitespace(String str) { 1654 if (str == null) { 1655 return false; 1656 } 1657 int sz = str.length(); 1658 for (int i = 0; i < sz; i++) { 1659 if ((Character.isWhitespace(str.charAt(i)) == false)) { 1660 return false; 1661 } 1662 } 1663 return true; 1664 } 1665 1666 /** 1667 * <p> 1668 * Checks if the String contains only unicode letters and space (<code>' '</code>). 1669 * </p> 1670 * <p> 1671 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1672 * </p> 1673 * 1674 * @param str the String to check 1675 * @return <code>true</code> if only contains letters and space, and is non-null 1676 */ 1677 public static boolean isAlphaSpace(String str) { 1678 if (str == null) { 1679 return false; 1680 } 1681 int sz = str.length(); 1682 for (int i = 0; i < sz; i++) { 1683 if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) != ' ')) { 1684 return false; 1685 } 1686 } 1687 return true; 1688 } 1689 1690 /** 1691 * <p> 1692 * Checks if the String contains only unicode letters or digits. 1693 * </p> 1694 * <p> 1695 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1696 * </p> 1697 * 1698 * @param str the String to check 1699 * @return <code>true</code> if only contains letters or digits, and is non-null 1700 */ 1701 public static boolean isAlphanumeric(String str) { 1702 if (str == null) { 1703 return false; 1704 } 1705 int sz = str.length(); 1706 for (int i = 0; i < sz; i++) { 1707 if (Character.isLetterOrDigit(str.charAt(i)) == false) { 1708 return false; 1709 } 1710 } 1711 return true; 1712 } 1713 1714 /** 1715 * <p> 1716 * Checks if the String contains only unicode letters, digits or space (<code>' '</code>). 1717 * </p> 1718 * <p> 1719 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1720 * </p> 1721 * 1722 * @param str the String to check 1723 * @return <code>true</code> if only contains letters, digits or space, and is non-null 1724 */ 1725 public static boolean isAlphanumericSpace(String str) { 1726 if (str == null) { 1727 return false; 1728 } 1729 int sz = str.length(); 1730 for (int i = 0; i < sz; i++) { 1731 if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) { 1732 return false; 1733 } 1734 } 1735 return true; 1736 } 1737 1738 /** 1739 * <p> 1740 * Checks if the String contains only unicode digits. 1741 * </p> 1742 * <p> 1743 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1744 * </p> 1745 * 1746 * @param str the String to check 1747 * @return <code>true</code> if only contains digits, and is non-null 1748 */ 1749 public static boolean isNumeric(String str) { 1750 if (str == null) { 1751 return false; 1752 } 1753 int sz = str.length(); 1754 for (int i = 0; i < sz; i++) { 1755 if (Character.isDigit(str.charAt(i)) == false) { 1756 return false; 1757 } 1758 } 1759 return true; 1760 } 1761 1762 /** 1763 * <p> 1764 * Checks if the String contains only unicode digits or space (<code>' '</code>). 1765 * </p> 1766 * <p> 1767 * <code>null</code> will return <code>false</code>. An empty String will return <code>true</code>. 1768 * </p> 1769 * 1770 * @param str the String to check 1771 * @return <code>true</code> if only contains digits or space, and is non-null 1772 */ 1773 public static boolean isNumericSpace(String str) { 1774 if (str == null) { 1775 return false; 1776 } 1777 int sz = str.length(); 1778 for (int i = 0; i < sz; i++) { 1779 if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) { 1780 return false; 1781 } 1782 } 1783 return true; 1784 } 1785 1786 // Defaults 1787 // -------------------------------------------------------------------------- 1788 1789 /** 1790 * <p> 1791 * Returns either the passed in <code>Object</code> as a String, or, if the <code>Object</code> is 1792 * <code>null</code>, an empty String. 1793 * </p> 1794 * 1795 * @param obj the Object to check 1796 * @return the passed in Object's toString, or blank if it was <code>null</code> 1797 * @see Objects#toString(Object, String) 1798 */ 1799 @Deprecated 1800 public static String defaultString(Object obj) { 1801 return defaultString(obj, ""); 1802 } 1803 1804 /** 1805 * <p> 1806 * Returns either the passed in <code>Object</code> as a String, or, if the <code>Object</code> is 1807 * <code>null</code>, a passed in default String. 1808 * </p> 1809 * 1810 * @param obj the Object to check 1811 * @param defaultString the default String to return if str is <code>null</code> 1812 * @return the passed in string, or the default if it was <code>null</code> 1813 * @see Objects#toString(Object, String) 1814 */ 1815 @Deprecated 1816 public static String defaultString(Object obj, String defaultString) { 1817 return Objects.toString(obj, defaultString); 1818 } 1819 1820 // Reversing 1821 // -------------------------------------------------------------------------- 1822 1823 /** 1824 * <p> 1825 * Reverse a String. 1826 * </p> 1827 * <p> 1828 * <code>null</code> String returns <code>null</code>. 1829 * </p> 1830 * 1831 * @param str the String to reverse 1832 * @return the reversed String 1833 */ 1834 public static String reverse(String str) { 1835 if (str == null) { 1836 return null; 1837 } 1838 return new StringBuilder(str).reverse().toString(); 1839 } 1840 1841 /** 1842 * <p> 1843 * Reverses a String that is delimited by a specific character. 1844 * </p> 1845 * <p> 1846 * The Strings between the delimiters are not reversed. Thus java.lang.String becomes String.lang.java (if the 1847 * delimiter is <code>'.'</code>). 1848 * </p> 1849 * 1850 * @param str the String to reverse 1851 * @param delimiter the delimiter to use 1852 * @return the reversed String 1853 */ 1854 public static String reverseDelimitedString(String str, String delimiter) { 1855 // could implement manually, but simple way is to reuse other, 1856 // probably slower, methods. 1857 String[] strs = split(str, delimiter); 1858 reverseArray(strs); 1859 return join(strs, delimiter); 1860 } 1861 1862 /** 1863 * <p> 1864 * Reverses an array. 1865 * </p> 1866 * <p> 1867 * TAKEN FROM CollectionsUtils. 1868 * </p> 1869 * 1870 * @param array the array to reverse 1871 */ 1872 private static void reverseArray(Object[] array) { 1873 int i = 0; 1874 int j = array.length - 1; 1875 Object tmp; 1876 1877 while (j > i) { 1878 tmp = array[j]; 1879 array[j] = array[i]; 1880 array[i] = tmp; 1881 j--; 1882 i++; 1883 } 1884 } 1885 1886 // Abbreviating 1887 // -------------------------------------------------------------------------- 1888 1889 /** 1890 * @return Turn "Now is the time for all good men" into "Now is the time for..." 1891 * <p> 1892 * Specifically: 1893 * <p> 1894 * If str is less than max characters long, return it. Else abbreviate it to (substring(str, 0, max-3) + "..."). If 1895 * maxWidth is less than 3, throw an IllegalArgumentException. In no case will it return a string of length greater 1896 * than maxWidth. 1897 * @param s string 1898 * @param maxWidth maximum length of result string 1899 **/ 1900 public static String abbreviate(String s, int maxWidth) { 1901 return abbreviate(s, 0, maxWidth); 1902 } 1903 1904 /** 1905 * @return Turn "Now is the time for all good men" into "...is the time for..." 1906 * 1907 * Works like abbreviate(String, int), but allows you to specify a "left edge" offset. Note that this left edge is 1908 * not necessarily going to be the leftmost character in the result, or the first character following the ellipses, 1909 * but it will appear somewhere in the result. In no case will it return a string of length greater than maxWidth. 1910 * @param s string 1911 * @param offset left edge of source string 1912 * @param maxWidth maximum length of result string 1913 **/ 1914 public static String abbreviate(String s, int offset, int maxWidth) { 1915 if (maxWidth < 4) { 1916 throw new IllegalArgumentException("Minimum abbreviation width is 4"); 1917 } 1918 if (s.length() <= maxWidth) { 1919 return s; 1920 } 1921 if (offset > s.length()) { 1922 offset = s.length(); 1923 } 1924 if ((s.length() - offset) < (maxWidth - 3)) { 1925 offset = s.length() - (maxWidth - 3); 1926 } 1927 if (offset <= 4) { 1928 return s.substring(0, maxWidth - 3) + "..."; 1929 } 1930 if (maxWidth < 7) { 1931 throw new IllegalArgumentException("Minimum abbreviation width with offset is 7"); 1932 } 1933 if ((offset + (maxWidth - 3)) < s.length()) { 1934 return "..." + abbreviate(s.substring(offset), maxWidth - 3); 1935 } 1936 return "..." + s.substring(s.length() - (maxWidth - 3)); 1937 } 1938 1939 // Difference 1940 // -------------------------------------------------------------------------- 1941 1942 /** 1943 * Compare two strings, and return the portion where they differ. (More precisely, return the remainder of the 1944 * second string, starting from where it's different from the first.) 1945 * <p> 1946 * E.g. strdiff("i am a machine", "i am a robot") -> "robot" 1947 * @param s1 string 1948 * @param s2 string 1949 * @return the portion of s2 where it differs from s1; returns the empty string ("") if they are equal 1950 **/ 1951 public static String difference(String s1, String s2) { 1952 int at = differenceAt(s1, s2); 1953 if (at == -1) { 1954 return ""; 1955 } 1956 return s2.substring(at); 1957 } 1958 1959 /** 1960 * Compare two strings, and return the index at which the strings begin to differ. 1961 * <p> 1962 * E.g. strdiff("i am a machine", "i am a robot") -> 7 1963 * </p> 1964 * @param s1 string 1965 * @param s2 string 1966 * @return the index where s2 and s1 begin to differ; -1 if they are equal 1967 **/ 1968 public static int differenceAt(String s1, String s2) { 1969 int i; 1970 for (i = 0; (i < s1.length()) && (i < s2.length()); ++i) { 1971 if (s1.charAt(i) != s2.charAt(i)) { 1972 break; 1973 } 1974 } 1975 if ((i < s2.length()) || (i < s1.length())) { 1976 return i; 1977 } 1978 return -1; 1979 } 1980 1981 public static String interpolate(String text, Map<?, ?> namespace) { 1982 Iterator<?> keys = namespace.keySet().iterator(); 1983 1984 while (keys.hasNext()) { 1985 String key = keys.next().toString(); 1986 1987 Object obj = namespace.get(key); 1988 1989 if (obj == null) { 1990 throw new NullPointerException("The value of the key '" + key + "' is null."); 1991 } 1992 1993 String value = obj.toString(); 1994 1995 text = replace(text, "${" + key + "}", value); 1996 1997 if (!key.contains(" ")) { 1998 text = replace(text, "$" + key, value); 1999 } 2000 } 2001 return text; 2002 } 2003 2004 public static String removeAndHump(String data, String replaceThis) { 2005 String temp; 2006 2007 StringBuilder out = new StringBuilder(); 2008 2009 temp = data; 2010 2011 StringTokenizer st = new StringTokenizer(temp, replaceThis); 2012 2013 while (st.hasMoreTokens()) { 2014 String element = (String) st.nextElement(); 2015 2016 out.append(capitalizeFirstLetter(element)); 2017 } 2018 2019 return out.toString(); 2020 } 2021 2022 public static String capitalizeFirstLetter(String data) { 2023 char firstLetter = Character.toTitleCase(data.substring(0, 1).charAt(0)); 2024 2025 String restLetters = data.substring(1); 2026 2027 return firstLetter + restLetters; 2028 } 2029 2030 public static String lowercaseFirstLetter(String data) { 2031 char firstLetter = Character.toLowerCase(data.substring(0, 1).charAt(0)); 2032 2033 String restLetters = data.substring(1); 2034 2035 return firstLetter + restLetters; 2036 } 2037 2038 public static String addAndDeHump(String view) { 2039 StringBuilder sb = new StringBuilder(); 2040 2041 for (int i = 0; i < view.length(); i++) { 2042 if ((i != 0) && Character.isUpperCase(view.charAt(i))) { 2043 sb.append('-'); 2044 } 2045 2046 sb.append(view.charAt(i)); 2047 } 2048 2049 return sb.toString().trim().toLowerCase(Locale.ENGLISH); 2050 } 2051 2052 /** 2053 * <p> 2054 * Quote and escape a String with the given character, handling <code>null</code>. 2055 * </p> 2056 * 2057 * <pre> 2058 * StringUtils.quoteAndEscape(null, *) = null 2059 * StringUtils.quoteAndEscape("", *) = "" 2060 * StringUtils.quoteAndEscape("abc", '"') = abc 2061 * StringUtils.quoteAndEscape("a\"bc", '"') = "a\"bc" 2062 * StringUtils.quoteAndEscape("a\"bc", '\'') = 'a\"bc' 2063 * </pre> 2064 * 2065 * @param source the source String 2066 * @param quoteChar the char used to quote 2067 * @return the String quoted and escaped 2068 * @since 1.5.1 2069 * @see #quoteAndEscape(String, char, char[], char[], char, boolean) 2070 */ 2071 public static String quoteAndEscape(String source, char quoteChar) { 2072 return quoteAndEscape(source, quoteChar, new char[] {quoteChar}, new char[] {' '}, '\\', false); 2073 } 2074 2075 /** 2076 * <p> 2077 * Quote and escape a String with the given character, handling <code>null</code>. 2078 * </p> 2079 * 2080 * @param source the source String 2081 * @param quoteChar the char used to quote 2082 * @param quotingTriggers chars generating a quote 2083 * @return the String quoted and escaped 2084 * @since 1.5.1 2085 * @see #quoteAndEscape(String, char, char[], char[], char, boolean) 2086 */ 2087 public static String quoteAndEscape(String source, char quoteChar, char[] quotingTriggers) { 2088 return quoteAndEscape(source, quoteChar, new char[] {quoteChar}, quotingTriggers, '\\', false); 2089 } 2090 2091 /** 2092 * @param source the source String 2093 * @param quoteChar the char used to quote 2094 * @param escapedChars chars to escape 2095 * @param escapeChar char used for escaping 2096 * @param force force the quoting 2097 * @return the String quoted and escaped 2098 * @since 1.5.1 2099 * @see #quoteAndEscape(String, char, char[], char[], char, boolean) 2100 */ 2101 public static String quoteAndEscape( 2102 String source, char quoteChar, final char[] escapedChars, char escapeChar, boolean force) { 2103 return quoteAndEscape(source, quoteChar, escapedChars, new char[] {' '}, escapeChar, force); 2104 } 2105 2106 /** 2107 * @param source the source String 2108 * @param quoteChar the char used to quote 2109 * @param escapedChars chars to escape 2110 * @param quotingTriggers chars generating a quote 2111 * @param escapeChar char used for escaping 2112 * @param force force the quoting 2113 * @return the String quoted and escaped 2114 * @since 1.5.1 2115 */ 2116 public static String quoteAndEscape( 2117 String source, 2118 char quoteChar, 2119 final char[] escapedChars, 2120 final char[] quotingTriggers, 2121 char escapeChar, 2122 boolean force) { 2123 return quoteAndEscape(source, quoteChar, escapedChars, quotingTriggers, escapeChar + "%s", force); 2124 } 2125 2126 /** 2127 * @param source the source String 2128 * @param quoteChar the char used to quote 2129 * @param escapedChars chars to escape 2130 * @param quotingTriggers chars generating a quote 2131 * @param escapePattern pattern used for escaping 2132 * @param force force the quoting 2133 * @return the String quoted and escaped 2134 * @since 3.0.4 2135 */ 2136 public static String quoteAndEscape( 2137 String source, 2138 char quoteChar, 2139 final char[] escapedChars, 2140 final char[] quotingTriggers, 2141 String escapePattern, 2142 boolean force) { 2143 if (source == null) { 2144 return null; 2145 } 2146 2147 if (!force 2148 && source.startsWith(Character.toString(quoteChar)) 2149 && source.endsWith(Character.toString(quoteChar))) { 2150 return source; 2151 } 2152 2153 String escaped = escape(source, escapedChars, escapePattern); 2154 2155 boolean quote = false; 2156 if (force) { 2157 quote = true; 2158 } else if (!escaped.equals(source)) { 2159 quote = true; 2160 } else { 2161 for (char quotingTrigger : quotingTriggers) { 2162 if (escaped.indexOf(quotingTrigger) > -1) { 2163 quote = true; 2164 break; 2165 } 2166 } 2167 } 2168 2169 if (quote) { 2170 return quoteChar + escaped + quoteChar; 2171 } 2172 2173 return escaped; 2174 } 2175 2176 /** 2177 * @param source the source String 2178 * @param escapedChars chars to escape 2179 * @param escapeChar char used for escaping 2180 * @return the String escaped 2181 * @since 1.5.1 2182 */ 2183 public static String escape(String source, final char[] escapedChars, char escapeChar) { 2184 return escape(source, escapedChars, escapeChar + "%s"); 2185 } 2186 2187 /** 2188 * @param source the source String 2189 * @param escapedChars chars to escape 2190 * @param escapePattern pattern used for escaping 2191 * @return the String escaped 2192 * @since 3.0.4 2193 */ 2194 public static String escape(String source, final char[] escapedChars, String escapePattern) { 2195 if (source == null) { 2196 return null; 2197 } 2198 2199 char[] eqc = new char[escapedChars.length]; 2200 System.arraycopy(escapedChars, 0, eqc, 0, escapedChars.length); 2201 Arrays.sort(eqc); 2202 2203 StringBuilder buffer = new StringBuilder(source.length()); 2204 2205 for (int i = 0; i < source.length(); i++) { 2206 final char c = source.charAt(i); 2207 int result = Arrays.binarySearch(eqc, c); 2208 2209 if (result > -1) { 2210 buffer.append(String.format(escapePattern, c)); 2211 } else { 2212 buffer.append(c); 2213 } 2214 } 2215 2216 return buffer.toString(); 2217 } 2218 2219 /** 2220 * Remove all duplicate whitespace characters and line terminators are replaced with a single space. 2221 * 2222 * @param s a not null String 2223 * @return a string with unique whitespace. 2224 * @since 1.5.7 2225 */ 2226 public static String removeDuplicateWhitespace(String s) { 2227 StringBuilder result = new StringBuilder(); 2228 int length = s.length(); 2229 boolean isPreviousWhiteSpace = false; 2230 for (int i = 0; i < length; i++) { 2231 char c = s.charAt(i); 2232 boolean thisCharWhiteSpace = Character.isWhitespace(c); 2233 if (!(isPreviousWhiteSpace && thisCharWhiteSpace)) { 2234 result.append(c); 2235 } 2236 isPreviousWhiteSpace = thisCharWhiteSpace; 2237 } 2238 return result.toString(); 2239 } 2240 2241 /** 2242 * Parses the given String and replaces all occurrences of '\n', '\r' and '\r\n' with the system line separator. 2243 * 2244 * @param s a not null String 2245 * @return a String that contains only System line separators. 2246 * @see #unifyLineSeparators(String, String) 2247 * @since 1.5.7 2248 */ 2249 public static String unifyLineSeparators(String s) { 2250 return unifyLineSeparators(s, System.getProperty("line.separator")); 2251 } 2252 2253 /** 2254 * Parses the given String and replaces all occurrences of '\n', '\r' and '\r\n' with the system line separator. 2255 * 2256 * @param s a not null String 2257 * @param ls the wanted line separator ("\n" on UNIX), if null using the System line separator. 2258 * @return a String that contains only System line separators. 2259 * @throws IllegalArgumentException if ls is not '\n', '\r' and '\r\n' characters. 2260 * @since 1.5.7 2261 */ 2262 public static String unifyLineSeparators(String s, String ls) { 2263 if (s == null) { 2264 return null; 2265 } 2266 2267 if (ls == null) { 2268 ls = System.getProperty("line.separator"); 2269 } 2270 2271 if (!(ls.equals("\n") || ls.equals("\r") || ls.equals("\r\n"))) { 2272 throw new IllegalArgumentException("Requested line separator is invalid."); 2273 } 2274 2275 int length = s.length(); 2276 2277 StringBuilder buffer = new StringBuilder(length); 2278 for (int i = 0; i < length; i++) { 2279 if (s.charAt(i) == '\r') { 2280 if ((i + 1) < length && s.charAt(i + 1) == '\n') { 2281 i++; 2282 } 2283 2284 buffer.append(ls); 2285 } else if (s.charAt(i) == '\n') { 2286 buffer.append(ls); 2287 } else { 2288 buffer.append(s.charAt(i)); 2289 } 2290 } 2291 2292 return buffer.toString(); 2293 } 2294 2295 /** 2296 * <p> 2297 * Checks if String contains a search character, handling <code>null</code>. This method uses 2298 * {@link String#indexOf(int)}. 2299 * </p> 2300 * <p> 2301 * A <code>null</code> or empty ("") String will return <code>false</code>. 2302 * </p> 2303 * 2304 * <pre> 2305 * StringUtils.contains(null, *) = false 2306 * StringUtils.contains("", *) = false 2307 * StringUtils.contains("abc", 'a') = true 2308 * StringUtils.contains("abc", 'z') = false 2309 * </pre> 2310 * 2311 * @param str the String to check, may be null 2312 * @param searchChar the character to find 2313 * @return true if the String contains the search character, false if not or <code>null</code> string input 2314 * @since 1.5.7 2315 */ 2316 public static boolean contains(String str, char searchChar) { 2317 if (isEmpty(str)) { 2318 return false; 2319 } 2320 return str.indexOf(searchChar) >= 0; 2321 } 2322 2323 /** 2324 * <p> 2325 * Checks if String contains a search String, handling <code>null</code>. This method uses 2326 * {@link String#indexOf(int)}. 2327 * </p> 2328 * <p> 2329 * A <code>null</code> String will return <code>false</code>. 2330 * </p> 2331 * 2332 * <pre> 2333 * StringUtils.contains(null, *) = false 2334 * StringUtils.contains(*, null) = false 2335 * StringUtils.contains("", "") = true 2336 * StringUtils.contains("abc", "") = true 2337 * StringUtils.contains("abc", "a") = true 2338 * StringUtils.contains("abc", "z") = false 2339 * </pre> 2340 * 2341 * @param str the String to check, may be null 2342 * @param searchStr the String to find, may be null 2343 * @return true if the String contains the search String, false if not or <code>null</code> string input 2344 * @since 1.5.7 2345 */ 2346 public static boolean contains(String str, String searchStr) { 2347 if (str == null || searchStr == null) { 2348 return false; 2349 } 2350 return str.contains(searchStr); 2351 } 2352 }