[分享]一个String工具类,也许你的项目中会用得到

简介: 每次做项目都会遇到字符串的处理,每次都会去写一个StringUtil,完成一些功能。 但其实每次要的功能都差不多: 1.判断类(包括NULL和空串、是否是空白字符串等) 2.默认值 3.去空白(trim) 4.比较 5.字符类型判断(是否只包含数字、字母) 6.大小写转换(首字母大小写等) 7.字符串分割 8.字符串连接 9.字符串查找 10.取子串 11.删除字符 12.字符串比较 下面是一个字符串的工具类,涵盖了上面列的功能,算是比较完整的。

每次做项目都会遇到字符串的处理,每次都会去写一个StringUtil,完成一些功能。

但其实每次要的功能都差不多:

1.判断类(包括NULL和空串、是否是空白字符串等)

2.默认值

3.去空白(trim)

4.比较

5.字符类型判断(是否只包含数字、字母)

6.大小写转换(首字母大小写等)

7.字符串分割

8.字符串连接

9.字符串查找

10.取子串

11.删除字符

12.字符串比较

下面是一个字符串的工具类,涵盖了上面列的功能,算是比较完整的。

   1 /**
   2  * 有关字符串处理的工具类。
   3  *
   4  * <p>
   5  * 这个类中的每个方法都可以“安全”地处理<code>null</code>,而不会抛出<code>NullPointerException</code>。
   6  * </p>
   7  *
   8  */
   9 public class StringUtil {
  10     /* ============================================================================ */
  11     /*  常量和singleton。                                                           */
  12     /* ============================================================================ */
  13 
  14     /** 空字符串。 */
  15     public static final String EMPTY_STRING = "";
  16 
  17     /* ============================================================================ */
  18     /*  判空函数。                                                                  */
  19     /*                                                                              */
  20     /*  以下方法用来判定一个字符串是否为:                                          */
  21     /*  1. null                                                                     */
  22     /*  2. empty - ""                                                               */
  23     /*  3. blank - "全部是空白" - 空白由Character.isWhitespace所定义。              */
  24     /* ============================================================================ */
  25 
  26     /**
  27      * 检查字符串是否为<code>null</code>或空字符串<code>""</code>。
  28      * <pre>
  29      * StringUtil.isEmpty(null)      = true
  30      * StringUtil.isEmpty("")        = true
  31      * StringUtil.isEmpty(" ")       = false
  32      * StringUtil.isEmpty("bob")     = false
  33      * StringUtil.isEmpty("  bob  ") = false
  34      * </pre>
  35      *
  36      * @param str 要检查的字符串
  37      *
  38      * @return 如果为空, 则返回<code>true</code>
  39      */
  40     public static boolean isEmpty(String str) {
  41         return ((str == null) || (str.length() == 0));
  42     }
  43 
  44     /**
  45      * 检查字符串是否不是<code>null</code>和空字符串<code>""</code>。
  46      * <pre>
  47      * StringUtil.isEmpty(null)      = false
  48      * StringUtil.isEmpty("")        = false
  49      * StringUtil.isEmpty(" ")       = true
  50      * StringUtil.isEmpty("bob")     = true
  51      * StringUtil.isEmpty("  bob  ") = true
  52      * </pre>
  53      *
  54      * @param str 要检查的字符串
  55      *
  56      * @return 如果不为空, 则返回<code>true</code>
  57      */
  58     public static boolean isNotEmpty(String str) {
  59         return ((str != null) && (str.length() > 0));
  60     }
  61 
  62     /**
  63      * 检查字符串是否是空白:<code>null</code>、空字符串<code>""</code>或只有空白字符。
  64      * <pre>
  65      * StringUtil.isBlank(null)      = true
  66      * StringUtil.isBlank("")        = true
  67      * StringUtil.isBlank(" ")       = true
  68      * StringUtil.isBlank("bob")     = false
  69      * StringUtil.isBlank("  bob  ") = false
  70      * </pre>
  71      *
  72      * @param str 要检查的字符串
  73      *
  74      * @return 如果为空白, 则返回<code>true</code>
  75      */
  76     public static boolean isBlank(String str) {
  77         int length;
  78 
  79         if ((str == null) || ((length = str.length()) == 0)) {
  80             return true;
  81         }
  82 
  83         for (int i = 0; i < length; i++) {
  84             if (!Character.isWhitespace(str.charAt(i))) {
  85                 return false;
  86             }
  87         }
  88 
  89         return true;
  90     }
  91 
  92     /**
  93      * 检查字符串是否不是空白:<code>null</code>、空字符串<code>""</code>或只有空白字符。
  94      * <pre>
  95      * StringUtil.isBlank(null)      = false
  96      * StringUtil.isBlank("")        = false
  97      * StringUtil.isBlank(" ")       = false
  98      * StringUtil.isBlank("bob")     = true
  99      * StringUtil.isBlank("  bob  ") = true
 100      * </pre>
 101      *
 102      * @param str 要检查的字符串
 103      *
 104      * @return 如果为空白, 则返回<code>true</code>
 105      */
 106     public static boolean isNotBlank(String str) {
 107         int length;
 108 
 109         if ((str == null) || ((length = str.length()) == 0)) {
 110             return false;
 111         }
 112 
 113         for (int i = 0; i < length; i++) {
 114             if (!Character.isWhitespace(str.charAt(i))) {
 115                 return true;
 116             }
 117         }
 118 
 119         return false;
 120     }
 121 
 122     /* ============================================================================ */
 123     /*  默认值函数。                                                                */
 124     /*                                                                              */
 125     /*  当字符串为null、empty或blank时,将字符串转换成指定的默认字符串。            */
 126     /* ============================================================================ */
 127 
 128     /**
 129      * 如果字符串是<code>null</code>,则返回空字符串<code>""</code>,否则返回字符串本身。
 130      * <pre>
 131      * StringUtil.defaultIfNull(null)  = ""
 132      * StringUtil.defaultIfNull("")    = ""
 133      * StringUtil.defaultIfNull("  ")  = "  "
 134      * StringUtil.defaultIfNull("bat") = "bat"
 135      * </pre>
 136      *
 137      * @param str 要转换的字符串
 138      *
 139      * @return 字符串本身或空字符串<code>""</code>
 140      */
 141     public static String defaultIfNull(String str) {
 142         return (str == null) ? EMPTY_STRING : str;
 143     }
 144 
 145     /**
 146      * 如果字符串是<code>null</code>,则返回指定默认字符串,否则返回字符串本身。
 147      * <pre>
 148      * StringUtil.defaultIfNull(null, "default")  = "default"
 149      * StringUtil.defaultIfNull("", "default")    = ""
 150      * StringUtil.defaultIfNull("  ", "default")  = "  "
 151      * StringUtil.defaultIfNull("bat", "default") = "bat"
 152      * </pre>
 153      *
 154      * @param str 要转换的字符串
 155      * @param defaultStr 默认字符串
 156      *
 157      * @return 字符串本身或指定的默认字符串
 158      */
 159     public static String defaultIfNull(String str, String defaultStr) {
 160         return (str == null) ? defaultStr : str;
 161     }
 162 
 163     /**
 164      * 如果字符串是<code>null</code>或空字符串<code>""</code>,则返回空字符串<code>""</code>,否则返回字符串本身。
 165      *
 166      * <p>
 167      * 此方法实际上和<code>defaultIfNull(String)</code>等效。
 168      * <pre>
 169      * StringUtil.defaultIfEmpty(null)  = ""
 170      * StringUtil.defaultIfEmpty("")    = ""
 171      * StringUtil.defaultIfEmpty("  ")  = "  "
 172      * StringUtil.defaultIfEmpty("bat") = "bat"
 173      * </pre>
 174      * </p>
 175      *
 176      * @param str 要转换的字符串
 177      *
 178      * @return 字符串本身或空字符串<code>""</code>
 179      */
 180     public static String defaultIfEmpty(String str) {
 181         return (str == null) ? EMPTY_STRING : str;
 182     }
 183 
 184     /**
 185      * 如果字符串是<code>null</code>或空字符串<code>""</code>,则返回指定默认字符串,否则返回字符串本身。
 186      * <pre>
 187      * StringUtil.defaultIfEmpty(null, "default")  = "default"
 188      * StringUtil.defaultIfEmpty("", "default")    = "default"
 189      * StringUtil.defaultIfEmpty("  ", "default")  = "  "
 190      * StringUtil.defaultIfEmpty("bat", "default") = "bat"
 191      * </pre>
 192      *
 193      * @param str 要转换的字符串
 194      * @param defaultStr 默认字符串
 195      *
 196      * @return 字符串本身或指定的默认字符串
 197      */
 198     public static String defaultIfEmpty(String str, String defaultStr) {
 199         return ((str == null) || (str.length() == 0)) ? defaultStr : str;
 200     }
 201 
 202     /**
 203      * 如果字符串是空白:<code>null</code>、空字符串<code>""</code>或只有空白字符,则返回空字符串<code>""</code>,否则返回字符串本身。
 204      * <pre>
 205      * StringUtil.defaultIfBlank(null)  = ""
 206      * StringUtil.defaultIfBlank("")    = ""
 207      * StringUtil.defaultIfBlank("  ")  = ""
 208      * StringUtil.defaultIfBlank("bat") = "bat"
 209      * </pre>
 210      *
 211      * @param str 要转换的字符串
 212      *
 213      * @return 字符串本身或空字符串<code>""</code>
 214      */
 215     public static String defaultIfBlank(String str) {
 216         return isBlank(str) ? EMPTY_STRING : str;
 217     }
 218 
 219     /**
 220      * 如果字符串是<code>null</code>或空字符串<code>""</code>,则返回指定默认字符串,否则返回字符串本身。
 221      * <pre>
 222      * StringUtil.defaultIfBlank(null, "default")  = "default"
 223      * StringUtil.defaultIfBlank("", "default")    = "default"
 224      * StringUtil.defaultIfBlank("  ", "default")  = "default"
 225      * StringUtil.defaultIfBlank("bat", "default") = "bat"
 226      * </pre>
 227      *
 228      * @param str 要转换的字符串
 229      * @param defaultStr 默认字符串
 230      *
 231      * @return 字符串本身或指定的默认字符串
 232      */
 233     public static String defaultIfBlank(String str, String defaultStr) {
 234         return isBlank(str) ? defaultStr : str;
 235     }
 236 
 237     /* ============================================================================ */
 238     /*  去空白(或指定字符)的函数。                                                */
 239     /*                                                                              */
 240     /*  以下方法用来除去一个字串中的空白或指定字符。                                */
 241     /* ============================================================================ */
 242 
 243     /**
 244      * 除去字符串头尾部的空白,如果字符串是<code>null</code>,依然返回<code>null</code>。
 245      *
 246      * <p>
 247      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 248      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 249      * <pre>
 250      * StringUtil.trim(null)          = null
 251      * StringUtil.trim("")            = ""
 252      * StringUtil.trim("     ")       = ""
 253      * StringUtil.trim("abc")         = "abc"
 254      * StringUtil.trim("    abc    ") = "abc"
 255      * </pre>
 256      * </p>
 257      *
 258      * @param str 要处理的字符串
 259      *
 260      * @return 除去空白的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
 261      */
 262     public static String trim(String str) {
 263         return trim(str, null, 0);
 264     }
 265 
 266     /**
 267      * 除去字符串头尾部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
 268      * <pre>
 269      * StringUtil.trim(null, *)          = null
 270      * StringUtil.trim("", *)            = ""
 271      * StringUtil.trim("abc", null)      = "abc"
 272      * StringUtil.trim("  abc", null)    = "abc"
 273      * StringUtil.trim("abc  ", null)    = "abc"
 274      * StringUtil.trim(" abc ", null)    = "abc"
 275      * StringUtil.trim("  abcyx", "xyz") = "  abc"
 276      * </pre>
 277      *
 278      * @param str 要处理的字符串
 279      * @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
 280      *
 281      * @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
 282      */
 283     public static String trim(String str, String stripChars) {
 284         return trim(str, stripChars, 0);
 285     }
 286 
 287     /**
 288      * 除去字符串头部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
 289      *
 290      * <p>
 291      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 292      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 293      * <pre>
 294      * StringUtil.trimStart(null)         = null
 295      * StringUtil.trimStart("")           = ""
 296      * StringUtil.trimStart("abc")        = "abc"
 297      * StringUtil.trimStart("  abc")      = "abc"
 298      * StringUtil.trimStart("abc  ")      = "abc  "
 299      * StringUtil.trimStart(" abc ")      = "abc "
 300      * </pre>
 301      * </p>
 302      *
 303      * @param str 要处理的字符串
 304      *
 305      * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回<code>null</code>
 306      */
 307     public static String trimStart(String str) {
 308         return trim(str, null, -1);
 309     }
 310 
 311     /**
 312      * 除去字符串头部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
 313      * <pre>
 314      * StringUtil.trimStart(null, *)          = null
 315      * StringUtil.trimStart("", *)            = ""
 316      * StringUtil.trimStart("abc", "")        = "abc"
 317      * StringUtil.trimStart("abc", null)      = "abc"
 318      * StringUtil.trimStart("  abc", null)    = "abc"
 319      * StringUtil.trimStart("abc  ", null)    = "abc  "
 320      * StringUtil.trimStart(" abc ", null)    = "abc "
 321      * StringUtil.trimStart("yxabc  ", "xyz") = "abc  "
 322      * </pre>
 323      *
 324      * @param str 要处理的字符串
 325      * @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
 326      *
 327      * @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
 328      */
 329     public static String trimStart(String str, String stripChars) {
 330         return trim(str, stripChars, -1);
 331     }
 332 
 333     /**
 334      * 除去字符串尾部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
 335      *
 336      * <p>
 337      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 338      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 339      * <pre>
 340      * StringUtil.trimEnd(null)       = null
 341      * StringUtil.trimEnd("")         = ""
 342      * StringUtil.trimEnd("abc")      = "abc"
 343      * StringUtil.trimEnd("  abc")    = "  abc"
 344      * StringUtil.trimEnd("abc  ")    = "abc"
 345      * StringUtil.trimEnd(" abc ")    = " abc"
 346      * </pre>
 347      * </p>
 348      *
 349      * @param str 要处理的字符串
 350      *
 351      * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回<code>null</code>
 352      */
 353     public static String trimEnd(String str) {
 354         return trim(str, null, 1);
 355     }
 356 
 357     /**
 358      * 除去字符串尾部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
 359      * <pre>
 360      * StringUtil.trimEnd(null, *)          = null
 361      * StringUtil.trimEnd("", *)            = ""
 362      * StringUtil.trimEnd("abc", "")        = "abc"
 363      * StringUtil.trimEnd("abc", null)      = "abc"
 364      * StringUtil.trimEnd("  abc", null)    = "  abc"
 365      * StringUtil.trimEnd("abc  ", null)    = "abc"
 366      * StringUtil.trimEnd(" abc ", null)    = " abc"
 367      * StringUtil.trimEnd("  abcyx", "xyz") = "  abc"
 368      * </pre>
 369      *
 370      * @param str 要处理的字符串
 371      * @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
 372      *
 373      * @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
 374      */
 375     public static String trimEnd(String str, String stripChars) {
 376         return trim(str, stripChars, 1);
 377     }
 378 
 379     /**
 380      * 除去字符串头尾部的空白,如果结果字符串是空字符串<code>""</code>,则返回<code>null</code>。
 381      *
 382      * <p>
 383      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 384      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 385      * <pre>
 386      * StringUtil.trimToNull(null)          = null
 387      * StringUtil.trimToNull("")            = null
 388      * StringUtil.trimToNull("     ")       = null
 389      * StringUtil.trimToNull("abc")         = "abc"
 390      * StringUtil.trimToNull("    abc    ") = "abc"
 391      * </pre>
 392      * </p>
 393      *
 394      * @param str 要处理的字符串
 395      *
 396      * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回<code>null</code>
 397      */
 398     public static String trimToNull(String str) {
 399         return trimToNull(str, null);
 400     }
 401 
 402     /**
 403      * 除去字符串头尾部的空白,如果结果字符串是空字符串<code>""</code>,则返回<code>null</code>。
 404      *
 405      * <p>
 406      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 407      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 408      * <pre>
 409      * StringUtil.trim(null, *)          = null
 410      * StringUtil.trim("", *)            = null
 411      * StringUtil.trim("abc", null)      = "abc"
 412      * StringUtil.trim("  abc", null)    = "abc"
 413      * StringUtil.trim("abc  ", null)    = "abc"
 414      * StringUtil.trim(" abc ", null)    = "abc"
 415      * StringUtil.trim("  abcyx", "xyz") = "  abc"
 416      * </pre>
 417      * </p>
 418      *
 419      * @param str 要处理的字符串
 420      * @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
 421      *
 422      * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回<code>null</code>
 423      */
 424     public static String trimToNull(String str, String stripChars) {
 425         String result = trim(str, stripChars);
 426 
 427         if ((result == null) || (result.length() == 0)) {
 428             return null;
 429         }
 430 
 431         return result;
 432     }
 433 
 434     /**
 435      * 除去字符串头尾部的空白,如果字符串是<code>null</code>,则返回空字符串<code>""</code>。
 436      *
 437      * <p>
 438      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 439      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 440      * <pre>
 441      * StringUtil.trimToEmpty(null)          = ""
 442      * StringUtil.trimToEmpty("")            = ""
 443      * StringUtil.trimToEmpty("     ")       = ""
 444      * StringUtil.trimToEmpty("abc")         = "abc"
 445      * StringUtil.trimToEmpty("    abc    ") = "abc"
 446      * </pre>
 447      * </p>
 448      *
 449      * @param str 要处理的字符串
 450      *
 451      * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回<code>null</code>
 452      */
 453     public static String trimToEmpty(String str) {
 454         return trimToEmpty(str, null);
 455     }
 456 
 457     /**
 458      * 除去字符串头尾部的空白,如果字符串是<code>null</code>,则返回空字符串<code>""</code>。
 459      *
 460      * <p>
 461      * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code>来判定空白,
 462      * 因而可以除去英文字符集之外的其它空白,如中文空格。
 463      * <pre>
 464      * StringUtil.trim(null, *)          = ""
 465      * StringUtil.trim("", *)            = ""
 466      * StringUtil.trim("abc", null)      = "abc"
 467      * StringUtil.trim("  abc", null)    = "abc"
 468      * StringUtil.trim("abc  ", null)    = "abc"
 469      * StringUtil.trim(" abc ", null)    = "abc"
 470      * StringUtil.trim("  abcyx", "xyz") = "  abc"
 471      * </pre>
 472      * </p>
 473      *
 474      * @param str 要处理的字符串
 475      *
 476      * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回<code>null</code>
 477      */
 478     public static String trimToEmpty(String str, String stripChars) {
 479         String result = trim(str, stripChars);
 480 
 481         if (result == null) {
 482             return EMPTY_STRING;
 483         }
 484 
 485         return result;
 486     }
 487 
 488     /**
 489      * 除去字符串头尾部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
 490      * <pre>
 491      * StringUtil.trim(null, *)          = null
 492      * StringUtil.trim("", *)            = ""
 493      * StringUtil.trim("abc", null)      = "abc"
 494      * StringUtil.trim("  abc", null)    = "abc"
 495      * StringUtil.trim("abc  ", null)    = "abc"
 496      * StringUtil.trim(" abc ", null)    = "abc"
 497      * StringUtil.trim("  abcyx", "xyz") = "  abc"
 498      * </pre>
 499      *
 500      * @param str 要处理的字符串
 501      * @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
 502      * @param mode <code>-1</code>表示trimStart,<code>0</code>表示trim全部,<code>1</code>表示trimEnd
 503      *
 504      * @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
 505      */
 506     private static String trim(String str, String stripChars, int mode) {
 507         if (str == null) {
 508             return null;
 509         }
 510 
 511         int length = str.length();
 512         int start = 0;
 513         int end = length;
 514 
 515         // 扫描字符串头部
 516         if (mode <= 0) {
 517             if (stripChars == null) {
 518                 while ((start < end) && (Character.isWhitespace(str.charAt(start)))) {
 519                     start++;
 520                 }
 521             } else if (stripChars.length() == 0) {
 522                 return str;
 523             } else {
 524                 while ((start < end) && (stripChars.indexOf(str.charAt(start)) != -1)) {
 525                     start++;
 526                 }
 527             }
 528         }
 529 
 530         // 扫描字符串尾部
 531         if (mode >= 0) {
 532             if (stripChars == null) {
 533                 while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) {
 534                     end--;
 535                 }
 536             } else if (stripChars.length() == 0) {
 537                 return str;
 538             } else {
 539                 while ((start < end) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
 540                     end--;
 541                 }
 542             }
 543         }
 544 
 545         if ((start > 0) || (end < length)) {
 546             return str.substring(start, end);
 547         }
 548 
 549         return str;
 550     }
 551 
 552     /* ============================================================================ */
 553     /*  比较函数。                                                                  */
 554     /*                                                                              */
 555     /*  以下方法用来比较两个字符串是否相同。                                        */
 556     /* ============================================================================ */
 557 
 558     /**
 559      * 比较两个字符串(大小写敏感)。
 560      * <pre>
 561      * StringUtil.equals(null, null)   = true
 562      * StringUtil.equals(null, "abc")  = false
 563      * StringUtil.equals("abc", null)  = false
 564      * StringUtil.equals("abc", "abc") = true
 565      * StringUtil.equals("abc", "ABC") = false
 566      * </pre>
 567      *
 568      * @param str1 要比较的字符串1
 569      * @param str2 要比较的字符串2
 570      *
 571      * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
 572      */
 573     public static boolean equals(String str1, String str2) {
 574         if (str1 == null) {
 575             return str2 == null;
 576         }
 577 
 578         return str1.equals(str2);
 579     }
 580 
 581     /**
 582      * 比较两个字符串(大小写不敏感)。
 583      * <pre>
 584      * StringUtil.equalsIgnoreCase(null, null)   = true
 585      * StringUtil.equalsIgnoreCase(null, "abc")  = false
 586      * StringUtil.equalsIgnoreCase("abc", null)  = false
 587      * StringUtil.equalsIgnoreCase("abc", "abc") = true
 588      * StringUtil.equalsIgnoreCase("abc", "ABC") = true
 589      * </pre>
 590      *
 591      * @param str1 要比较的字符串1
 592      * @param str2 要比较的字符串2
 593      *
 594      * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
 595      */
 596     public static boolean equalsIgnoreCase(String str1, String str2) {
 597         if (str1 == null) {
 598             return str2 == null;
 599         }
 600 
 601         return str1.equalsIgnoreCase(str2);
 602     }
 603 
 604     /* ============================================================================ */
 605     /*  字符串类型判定函数。                                                        */
 606     /*                                                                              */
 607     /*  判定字符串的类型是否为:字母、数字、空白等                                  */
 608     /* ============================================================================ */
 609 
 610     /**
 611      * 判断字符串是否只包含unicode字母。
 612      *
 613      * <p>
 614      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 615      * </p>
 616      * <pre>
 617      * StringUtil.isAlpha(null)   = false
 618      * StringUtil.isAlpha("")     = true
 619      * StringUtil.isAlpha("  ")   = false
 620      * StringUtil.isAlpha("abc")  = true
 621      * StringUtil.isAlpha("ab2c") = false
 622      * StringUtil.isAlpha("ab-c") = false
 623      * </pre>
 624      *
 625      * @param str 要检查的字符串
 626      *
 627      * @return 如果字符串非<code>null</code>并且全由unicode字母组成,则返回<code>true</code>
 628      */
 629     public static boolean isAlpha(String str) {
 630         if (str == null) {
 631             return false;
 632         }
 633 
 634         int length = str.length();
 635 
 636         for (int i = 0; i < length; i++) {
 637             if (!Character.isLetter(str.charAt(i))) {
 638                 return false;
 639             }
 640         }
 641 
 642         return true;
 643     }
 644 
 645     /**
 646      * 判断字符串是否只包含unicode字母和空格<code>' '</code>。
 647      *
 648      * <p>
 649      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 650      * </p>
 651      * <pre>
 652      * StringUtil.isAlphaSpace(null)   = false
 653      * StringUtil.isAlphaSpace("")     = true
 654      * StringUtil.isAlphaSpace("  ")   = true
 655      * StringUtil.isAlphaSpace("abc")  = true
 656      * StringUtil.isAlphaSpace("ab c") = true
 657      * StringUtil.isAlphaSpace("ab2c") = false
 658      * StringUtil.isAlphaSpace("ab-c") = false
 659      * </pre>
 660      *
 661      * @param str 要检查的字符串
 662      *
 663      * @return 如果字符串非<code>null</code>并且全由unicode字母和空格组成,则返回<code>true</code>
 664      */
 665     public static boolean isAlphaSpace(String str) {
 666         if (str == null) {
 667             return false;
 668         }
 669 
 670         int length = str.length();
 671 
 672         for (int i = 0; i < length; i++) {
 673             if (!Character.isLetter(str.charAt(i)) && (str.charAt(i) != ' ')) {
 674                 return false;
 675             }
 676         }
 677 
 678         return true;
 679     }
 680 
 681     /**
 682      * 判断字符串是否只包含unicode字母和数字。
 683      *
 684      * <p>
 685      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 686      * </p>
 687      * <pre>
 688      * StringUtil.isAlphanumeric(null)   = false
 689      * StringUtil.isAlphanumeric("")     = true
 690      * StringUtil.isAlphanumeric("  ")   = false
 691      * StringUtil.isAlphanumeric("abc")  = true
 692      * StringUtil.isAlphanumeric("ab c") = false
 693      * StringUtil.isAlphanumeric("ab2c") = true
 694      * StringUtil.isAlphanumeric("ab-c") = false
 695      * </pre>
 696      *
 697      * @param str 要检查的字符串
 698      *
 699      * @return 如果字符串非<code>null</code>并且全由unicode字母数字组成,则返回<code>true</code>
 700      */
 701     public static boolean isAlphanumeric(String str) {
 702         if (str == null) {
 703             return false;
 704         }
 705 
 706         int length = str.length();
 707 
 708         for (int i = 0; i < length; i++) {
 709             if (!Character.isLetterOrDigit(str.charAt(i))) {
 710                 return false;
 711             }
 712         }
 713 
 714         return true;
 715     }
 716 
 717     /**
 718      * 判断字符串是否只包含unicode字母数字和空格<code>' '</code>。
 719      *
 720      * <p>
 721      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 722      * </p>
 723      * <pre>
 724      * StringUtil.isAlphanumericSpace(null)   = false
 725      * StringUtil.isAlphanumericSpace("")     = true
 726      * StringUtil.isAlphanumericSpace("  ")   = true
 727      * StringUtil.isAlphanumericSpace("abc")  = true
 728      * StringUtil.isAlphanumericSpace("ab c") = true
 729      * StringUtil.isAlphanumericSpace("ab2c") = true
 730      * StringUtil.isAlphanumericSpace("ab-c") = false
 731      * </pre>
 732      *
 733      * @param str 要检查的字符串
 734      *
 735      * @return 如果字符串非<code>null</code>并且全由unicode字母数字和空格组成,则返回<code>true</code>
 736      */
 737     public static boolean isAlphanumericSpace(String str) {
 738         if (str == null) {
 739             return false;
 740         }
 741 
 742         int length = str.length();
 743 
 744         for (int i = 0; i < length; i++) {
 745             if (!Character.isLetterOrDigit(str.charAt(i)) && (str.charAt(i) != ' ')) {
 746                 return false;
 747             }
 748         }
 749 
 750         return true;
 751     }
 752 
 753     /**
 754      * 判断字符串是否只包含unicode数字。
 755      *
 756      * <p>
 757      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 758      * </p>
 759      * <pre>
 760      * StringUtil.isNumeric(null)   = false
 761      * StringUtil.isNumeric("")     = true
 762      * StringUtil.isNumeric("  ")   = false
 763      * StringUtil.isNumeric("123")  = true
 764      * StringUtil.isNumeric("12 3") = false
 765      * StringUtil.isNumeric("ab2c") = false
 766      * StringUtil.isNumeric("12-3") = false
 767      * StringUtil.isNumeric("12.3") = false
 768      * </pre>
 769      *
 770      * @param str 要检查的字符串
 771      *
 772      * @return 如果字符串非<code>null</code>并且全由unicode数字组成,则返回<code>true</code>
 773      */
 774     public static boolean isNumeric(String str) {
 775         if (str == null) {
 776             return false;
 777         }
 778 
 779         int length = str.length();
 780 
 781         for (int i = 0; i < length; i++) {
 782             if (!Character.isDigit(str.charAt(i))) {
 783                 return false;
 784             }
 785         }
 786 
 787         return true;
 788     }
 789 
 790     /**
 791      * 判断字符串是否只包含unicode数字,包括小数。
 792      *
 793      * <p>
 794      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 795      * </p>
 796      * <pre>
 797      * StringUtil.isNumeric(null)   = false
 798      * StringUtil.isNumeric("")     = false
 799      * StringUtil.isNumeric("  ")   = false
 800      * StringUtil.isNumeric("123")  = true
 801      * StringUtil.isNumeric("12 3") = false
 802      * StringUtil.isNumeric("ab2c") = false
 803      * StringUtil.isNumeric("12-3") = false
 804      * StringUtil.isNumeric("12.3") = true
 805      * </pre>
 806      *
 807      * @param str 要检查的字符串
 808      *
 809      * @return 如果字符串非<code>null</code>并且全由unicode数字组成,则返回<code>true</code>
 810      */
 811     public static boolean isNumber(String str) {
 812         if (isBlank(str)) {
 813             return false;
 814         }
 815         int index = str.indexOf(".");
 816         if (index < 0) {
 817             return isNumeric(str);
 818         } else {
 819             String num1 = str.substring(0, index);
 820             String num2 = str.substring(index + 1);
 821             return isNumeric(num1) && isNumeric(num2);
 822         }
 823     }
 824 
 825 
 826     /**
 827      * 判断字符串是否只包含unicode数字和空格<code>' '</code>。
 828      *
 829      * <p>
 830      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 831      * </p>
 832      * <pre>
 833      * StringUtil.isNumericSpace(null)   = false
 834      * StringUtil.isNumericSpace("")     = true
 835      * StringUtil.isNumericSpace("  ")   = true
 836      * StringUtil.isNumericSpace("123")  = true
 837      * StringUtil.isNumericSpace("12 3") = true
 838      * StringUtil.isNumericSpace("ab2c") = false
 839      * StringUtil.isNumericSpace("12-3") = false
 840      * StringUtil.isNumericSpace("12.3") = false
 841      * </pre>
 842      *
 843      * @param str 要检查的字符串
 844      *
 845      * @return 如果字符串非<code>null</code>并且全由unicode数字和空格组成,则返回<code>true</code>
 846      */
 847     public static boolean isNumericSpace(String str) {
 848         if (str == null) {
 849             return false;
 850         }
 851 
 852         int length = str.length();
 853 
 854         for (int i = 0; i < length; i++) {
 855             if (!Character.isDigit(str.charAt(i)) && (str.charAt(i) != ' ')) {
 856                 return false;
 857             }
 858         }
 859 
 860         return true;
 861     }
 862 
 863     /**
 864      * 判断字符串是否只包含unicode空白。
 865      *
 866      * <p>
 867      * <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回<code>true</code>。
 868      * </p>
 869      * <pre>
 870      * StringUtil.isWhitespace(null)   = false
 871      * StringUtil.isWhitespace("")     = true
 872      * StringUtil.isWhitespace("  ")   = true
 873      * StringUtil.isWhitespace("abc")  = false
 874      * StringUtil.isWhitespace("ab2c") = false
 875      * StringUtil.isWhitespace("ab-c") = false
 876      * </pre>
 877      *
 878      * @param str 要检查的字符串
 879      *
 880      * @return 如果字符串非<code>null</code>并且全由unicode空白组成,则返回<code>true</code>
 881      */
 882     public static boolean isWhitespace(String str) {
 883         if (str == null) {
 884             return false;
 885         }
 886 
 887         int length = str.length();
 888 
 889         for (int i = 0; i < length; i++) {
 890             if (!Character.isWhitespace(str.charAt(i))) {
 891                 return false;
 892             }
 893         }
 894 
 895         return true;
 896     }
 897 
 898     /* ============================================================================ */
 899     /*  大小写转换。                                                                */
 900     /* ============================================================================ */
 901 
 902     /**
 903      * 将字符串转换成大写。
 904      *
 905      * <p>
 906      * 如果字符串是<code>null</code>则返回<code>null</code>。
 907      * <pre>
 908      * StringUtil.toUpperCase(null)  = null
 909      * StringUtil.toUpperCase("")    = ""
 910      * StringUtil.toUpperCase("aBc") = "ABC"
 911      * </pre>
 912      * </p>
 913      *
 914      * @param str 要转换的字符串
 915      *
 916      * @return 大写字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
 917      */
 918     public static String toUpperCase(String str) {
 919         if (str == null) {
 920             return null;
 921         }
 922 
 923         return str.toUpperCase();
 924     }
 925 
 926     /**
 927      * 将字符串转换成小写。
 928      *
 929      * <p>
 930      * 如果字符串是<code>null</code>则返回<code>null</code>。
 931      * <pre>
 932      * StringUtil.toLowerCase(null)  = null
 933      * StringUtil.toLowerCase("")    = ""
 934      * StringUtil.toLowerCase("aBc") = "abc"
 935      * </pre>
 936      * </p>
 937      *
 938      * @param str 要转换的字符串
 939      *
 940      * @return 大写字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
 941      */
 942     public static String toLowerCase(String str) {
 943         if (str == null) {
 944             return null;
 945         }
 946 
 947         return str.toLowerCase();
 948     }
 949 
 950     /**
 951      * 将字符串的首字符转成大写(<code>Character.toTitleCase</code>),其它字符不变。
 952      *
 953      * <p>
 954      * 如果字符串是<code>null</code>则返回<code>null</code>。
 955      * <pre>
 956      * StringUtil.capitalize(null)  = null
 957      * StringUtil.capitalize("")    = ""
 958      * StringUtil.capitalize("cat") = "Cat"
 959      * StringUtil.capitalize("cAt") = "CAt"
 960      * </pre>
 961      * </p>
 962      *
 963      * @param str 要转换的字符串
 964      *
 965      * @return 首字符为大写的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
 966      */
 967     public static String capitalize(String str) {
 968         int strLen;
 969 
 970         if ((str == null) || ((strLen = str.length()) == 0)) {
 971             return str;
 972         }
 973 
 974         return new StringBuffer(strLen).append(Character.toTitleCase(str.charAt(0))).append(
 975             str.substring(1)).toString();
 976     }
 977 
 978     /**
 979      * 将字符串的首字符转成小写,其它字符不变。
 980      *
 981      * <p>
 982      * 如果字符串是<code>null</code>则返回<code>null</code>。
 983      * <pre>
 984      * StringUtil.uncapitalize(null)  = null
 985      * StringUtil.uncapitalize("")    = ""
 986      * StringUtil.uncapitalize("Cat") = "cat"
 987      * StringUtil.uncapitalize("CAT") = "cAT"
 988      * </pre>
 989      * </p>
 990      *
 991      * @param str 要转换的字符串
 992      *
 993      * @return 首字符为小写的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
 994      */
 995     public static String uncapitalize(String str) {
 996         int strLen;
 997 
 998         if ((str == null) || ((strLen = str.length()) == 0)) {
 999             return str;
1000         }
1001 
1002         return new StringBuffer(strLen).append(Character.toLowerCase(str.charAt(0))).append(
1003             str.substring(1)).toString();
1004     }
1005 
1006     /**
1007      * 反转字符串的大小写。
1008      *
1009      * <p>
1010      * 如果字符串是<code>null</code>则返回<code>null</code>。
1011      * <pre>
1012      * StringUtil.swapCase(null)                 = null
1013      * StringUtil.swapCase("")                   = ""
1014      * StringUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
1015      * </pre>
1016      * </p>
1017      *
1018      * @param str 要转换的字符串
1019      *
1020      * @return 大小写被反转的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
1021      */
1022     public static String swapCase(String str) {
1023         int strLen;
1024 
1025         if ((str == null) || ((strLen = str.length()) == 0)) {
1026             return str;
1027         }
1028 
1029         StringBuffer buffer = new StringBuffer(strLen);
1030 
1031         char ch = 0;
1032 
1033         for (int i = 0; i < strLen; i++) {
1034             ch = str.charAt(i);
1035 
1036             if (Character.isUpperCase(ch)) {
1037                 ch = Character.toLowerCase(ch);
1038             } else if (Character.isTitleCase(ch)) {
1039                 ch = Character.toLowerCase(ch);
1040             } else if (Character.isLowerCase(ch)) {
1041                 ch = Character.toUpperCase(ch);
1042             }
1043 
1044             buffer.append(ch);
1045         }
1046 
1047         return buffer.toString();
1048     }
1049 
1050     /**
1051      * 将字符串转换成camel case。
1052      *
1053      * <p>
1054      * 如果字符串是<code>null</code>则返回<code>null</code>。
1055      * <pre>
1056      * StringUtil.toCamelCase(null)  = null
1057      * StringUtil.toCamelCase("")    = ""
1058      * StringUtil.toCamelCase("aBc") = "aBc"
1059      * StringUtil.toCamelCase("aBc def") = "aBcDef"
1060      * StringUtil.toCamelCase("aBc def_ghi") = "aBcDefGhi"
1061      * StringUtil.toCamelCase("aBc def_ghi 123") = "aBcDefGhi123"
1062      * </pre>
1063      * </p>
1064      *
1065      * <p>
1066      * 此方法会保留除了下划线和空白以外的所有分隔符。
1067      * </p>
1068      *
1069      * @param str 要转换的字符串
1070      *
1071      * @return camel case字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
1072      */
1073     public static String toCamelCase(String str) {
1074         return CAMEL_CASE_TOKENIZER.parse(str);
1075     }
1076 
1077     /**
1078      * 将字符串转换成pascal case。
1079      *
1080      * <p>
1081      * 如果字符串是<code>null</code>则返回<code>null</code>。
1082      * <pre>
1083      * StringUtil.toPascalCase(null)  = null
1084      * StringUtil.toPascalCase("")    = ""
1085      * StringUtil.toPascalCase("aBc") = "ABc"
1086      * StringUtil.toPascalCase("aBc def") = "ABcDef"
1087      * StringUtil.toPascalCase("aBc def_ghi") = "ABcDefGhi"
1088      * StringUtil.toPascalCase("aBc def_ghi 123") = "aBcDefGhi123"
1089      * </pre>
1090      * </p>
1091      *
1092      * <p>
1093      * 此方法会保留除了下划线和空白以外的所有分隔符。
1094      * </p>
1095      *
1096      * @param str 要转换的字符串
1097      *
1098      * @return pascal case字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
1099      */
1100     public static String toPascalCase(String str) {
1101         return PASCAL_CASE_TOKENIZER.parse(str);
1102     }
1103 
1104     /**
1105      * 将字符串转换成下划线分隔的大写字符串。
1106      *
1107      * <p>
1108      * 如果字符串是<code>null</code>则返回<code>null</code>。
1109      * <pre>
1110      * StringUtil.toUpperCaseWithUnderscores(null)  = null
1111      * StringUtil.toUpperCaseWithUnderscores("")    = ""
1112      * StringUtil.toUpperCaseWithUnderscores("aBc") = "A_BC"
1113      * StringUtil.toUpperCaseWithUnderscores("aBc def") = "A_BC_DEF"
1114      * StringUtil.toUpperCaseWithUnderscores("aBc def_ghi") = "A_BC_DEF_GHI"
1115      * StringUtil.toUpperCaseWithUnderscores("aBc def_ghi 123") = "A_BC_DEF_GHI_123"
1116      * StringUtil.toUpperCaseWithUnderscores("__a__Bc__") = "__A__BC__"
1117      * </pre>
1118      * </p>
1119      *
1120      * <p>
1121      * 此方法会保留除了空白以外的所有分隔符。
1122      * </p>
1123      *
1124      * @param str 要转换的字符串
1125      *
1126      * @return 下划线分隔的大写字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
1127      */
1128     public static String toUpperCaseWithUnderscores(String str) {
1129         return UPPER_CASE_WITH_UNDERSCORES_TOKENIZER.parse(str);
1130     }
1131 
1132     /**
1133      * 将字符串转换成下划线分隔的小写字符串。
1134      *
1135      * <p>
1136      * 如果字符串是<code>null</code>则返回<code>null</code>。
1137      * <pre>
1138      * StringUtil.toLowerCaseWithUnderscores(null)  = null
1139      * StringUtil.toLowerCaseWithUnderscores("")    = ""
1140      * StringUtil.toLowerCaseWithUnderscores("aBc") = "a_bc"
1141      * StringUtil.toLowerCaseWithUnderscores("aBc def") = "a_bc_def"
1142      * StringUtil.toLowerCaseWithUnderscores("aBc def_ghi") = "a_bc_def_ghi"
1143      * StringUtil.toLowerCaseWithUnderscores("aBc def_ghi 123") = "a_bc_def_ghi_123"
1144      * StringUtil.toLowerCaseWithUnderscores("__a__Bc__") = "__a__bc__"
1145      * </pre>
1146      * </p>
1147      *
1148      * <p>
1149      * 此方法会保留除了空白以外的所有分隔符。
1150      * </p>
1151      *
1152      * @param str 要转换的字符串
1153      *
1154      * @return 下划线分隔的小写字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
1155      */
1156     public static String toLowerCaseWithUnderscores(String str) {
1157         return LOWER_CASE_WITH_UNDERSCORES_TOKENIZER.parse(str);
1158     }
1159 
1160     /** 解析单词的解析器。 */
1161     private static final WordTokenizer CAMEL_CASE_TOKENIZER                  = new WordTokenizer() {
1162                                                                                  protected void startSentence(
1163                                                                                                               StringBuffer buffer,
1164                                                                                                               char ch) {
1165                                                                                      buffer
1166                                                                                          .append(Character
1167                                                                                              .toLowerCase(ch));
1168                                                                                  }
1169 
1170                                                                                  protected void startWord(
1171                                                                                                           StringBuffer buffer,
1172                                                                                                           char ch) {
1173                                                                                      if (!isDelimiter(buffer
1174                                                                                          .charAt(buffer
1175                                                                                              .length() - 1))) {
1176                                                                                          buffer
1177                                                                                              .append(Character
1178                                                                                                  .toUpperCase(ch));
1179                                                                                      } else {
1180                                                                                          buffer
1181                                                                                              .append(Character
1182                                                                                                  .toLowerCase(ch));
1183                                                                                      }
1184                                                                                  }
1185 
1186                                                                                  protected void inWord(
1187                                                                                                        StringBuffer buffer,
1188                                                                                                        char ch) {
1189                                                                                      buffer
1190                                                                                          .append(Character
1191                                                                                              .toLowerCase(ch));
1192                                                                                  }
1193 
1194                                                                                  protected void startDigitSentence(
1195                                                                                                                    StringBuffer buffer,
1196                                                                                                                    char ch) {
1197                                                                                      buffer
1198                                                                                          .append(ch);
1199                                                                                  }
1200 
1201                                                                                  protected void startDigitWord(
1202                                                                                                                StringBuffer buffer,
1203                                                                                                                char ch) {
1204                                                                                      buffer
1205                                                                                          .append(ch);
1206                                                                                  }
1207 
1208                                                                                  protected void inDigitWord(
1209                                                                                                             StringBuffer buffer,
1210                                                                                                             char ch) {
1211                                                                                      buffer
1212                                                                                          .append(ch);
1213                                                                                  }
1214 
1215                                                                                  protected void inDelimiter(
1216                                                                                                             StringBuffer buffer,
1217                                                                                                             char ch) {
1218                                                                                      if (ch != UNDERSCORE) {
1219                                                                                          buffer
1220                                                                                              .append(ch);
1221                                                                                      }
1222                                                                                  }
1223                                                                              };
1224 
1225     private static final WordTokenizer PASCAL_CASE_TOKENIZER                 = new WordTokenizer() {
1226                                                                                  protected void startSentence(
1227                                                                                                               StringBuffer buffer,
1228                                                                                                               char ch) {
1229                                                                                      buffer
1230                                                                                          .append(Character
1231                                                                                              .toUpperCase(ch));
1232                                                                                  }
1233 
1234                                                                                  protected void startWord(
1235                                                                                                           StringBuffer buffer,
1236                                                                                                           char ch) {
1237                                                                                      buffer
1238                                                                                          .append(Character
1239                                                                                              .toUpperCase(ch));
1240                                                                                  }
1241 
1242                                                                                  protected void inWord(
1243                                                                                                        StringBuffer buffer,
1244                                                                                                        char ch) {
1245                                                                                      buffer
1246                                                                                          .append(Character
1247                                                                                              .toLowerCase(ch));
1248                                                                                  }
1249 
1250                                                                                  protected void startDigitSentence(
1251                                                                                                                    StringBuffer buffer,
1252                                                                                                                    char ch) {
1253                                                                                      buffer
1254                                                                                          .append(ch);
1255                                                                                  }
1256 
1257                                                                                  protected void startDigitWord(
1258                                                                                                                StringBuffer buffer,
1259                                                                                                                char ch) {
1260                                                                                      buffer
1261                                                                                          .append(ch);
1262                                                                                  }
1263 
1264                                                                                  protected void inDigitWord(
1265                                                                                                             StringBuffer buffer,
1266                                                                                                             char ch) {
1267                                                                                      buffer
1268                                                                                          .append(ch);
1269                                                                                  }
1270 
1271                                                                                  protected void inDelimiter(
1272                                                                                                             StringBuffer buffer,
1273                                                                                                             char ch) {
1274                                                                                      if (ch != UNDERSCORE) {
1275                                                                                          buffer
1276                                                                                              .append(ch);
1277                                                                                      }
1278                                                                                  }
1279                                                                              };
1280 
1281     private static final WordTokenizer UPPER_CASE_WITH_UNDERSCORES_TOKENIZER = new WordTokenizer() {
1282                                                                                  protected void startSentence(
1283                                                                                                               StringBuffer buffer,
1284                                                                                                               char ch) {
1285                                                                                      buffer
1286                                                                                          .append(Character
1287                                                                                              .toUpperCase(ch));
1288                                                                                  }
1289 
1290                                                                                  protected void startWord(
1291                                                                                                           StringBuffer buffer,
1292                                                                                                           char ch) {
1293                                                                                      if (!isDelimiter(buffer
1294                                                                                          .charAt(buffer
1295                                                                                              .length() - 1))) {
1296                                                                                          buffer
1297                                                                                              .append(UNDERSCORE);
1298                                                                                      }
1299 
1300                                                                                      buffer
1301                                                                                          .append(Character
1302                                                                                              .toUpperCase(ch));
1303                                                                                  }
1304 
1305                                                                                  protected void inWord(
1306                                                                                                        StringBuffer buffer,
1307                                                                                                        char ch) {
1308                                                                                      buffer
1309                                                                                          .append(Character
1310                                                                                              .toUpperCase(ch));
1311                                                                                  }
1312 
1313                                                                                  protected void startDigitSentence(
1314                                                                                                                    StringBuffer buffer,
1315                                                                                                                    char ch) {
1316                                                                                      buffer
1317                                                                                          .append(ch);
1318                                                                                  }
1319 
1320                                                                                  protected void startDigitWord(
1321                                                                                                                StringBuffer buffer,
1322                                                                                                                char ch) {
1323                                                                                      if (!isDelimiter(buffer
1324                                                                                          .charAt(buffer
1325                                                                                              .length() - 1))) {
1326                                                                                          buffer
1327                                                                                              .append(UNDERSCORE);
1328                                                                                      }
1329 
1330                                                                                      buffer
1331                                                                                          .append(ch);
1332                                                                                  }
1333 
1334                                                                                  protected void inDigitWord(
1335                                                                                                             StringBuffer buffer,
1336                                                                                                             char ch) {
1337                                                                                      buffer
1338                                                                                          .append(ch);
1339                                                                                  }
1340 
1341                                                                                  protected void inDelimiter(
1342                                                                                                             StringBuffer buffer,
1343                                                                                                             char ch) {
1344                                                                                      buffer
1345                                                                                          .append(ch);
1346                                                                                  }
1347                                                                              };
1348 
1349     private static final WordTokenizer LOWER_CASE_WITH_UNDERSCORES_TOKENIZER = new WordTokenizer() {
1350                                                                                  protected void startSentence(
1351                                                                                                               StringBuffer buffer,
1352                                                                                                               char ch) {
1353                                                                                      buffer
1354                                                                                          .append(Character
1355                                                                                              .toLowerCase(ch));
1356                                                                                  }
1357 
1358                                                                                  protected void startWord(
1359                                                                                                           StringBuffer buffer,
1360                                                                                                           char ch) {
1361                                                                                      if (!isDelimiter(buffer
1362                                                                                          .charAt(buffer
1363                                                                                              .length() - 1))) {
1364                                                                                          buffer
1365                                                                                              .append(UNDERSCORE);
1366                                                                                      }
1367 
1368                                                                                      buffer
1369                                                                                          .append(Character
1370                                                                                              .toLowerCase(ch));
1371                                                                                  }
1372 
1373                                                                                  protected void inWord(
1374                                                                                                        StringBuffer buffer,
1375                                                                                                        char ch) {
1376                                                                                      buffer
1377                                                                                          .append(Character
1378                                                                                              .toLowerCase(ch));
1379                                                                                  }
1380 
1381                                                                                  protected void startDigitSentence(
1382                                                                                                                    StringBuffer buffer,
1383                                                                                                                    char ch) {
1384                                                                                      buffer
1385                                                                                          .append(ch);
1386                                                                                  }
1387 
1388                                                                                  protected void startDigitWord(
1389                                                                                                                StringBuffer buffer,
1390                                                                                                                char ch) {
1391                                                                                      if (!isDelimiter(buffer
1392                                                                                          .charAt(buffer
1393                                                                                              .length() - 1))) {
1394                                                                                          buffer
1395                                                                                              .append(UNDERSCORE);
1396                                                                                      }
1397 
1398                                                                                      buffer
1399                                                                                          .append(ch);
1400                                                                                  }
1401 
1402                                                                                  protected void inDigitWord(
1403                                                                                                             StringBuffer buffer,
1404                                                                                                             char ch) {
1405                                                                                      buffer
1406                                                                                          .append(ch);
1407                                                                                  }
1408 
1409                                                                                  protected void inDelimiter(
1410                                                                                                             StringBuffer buffer,
1411                                                                                                             char ch) {
1412                                                                                      buffer
1413                                                                                          .append(ch);
1414                                                                                  }
1415                                                                              };
1416 
1417     /**
1418      * 解析出下列语法所构成的<code>SENTENCE</code>。
1419      * <pre>
1420      *  SENTENCE = WORD (DELIMITER* WORD)*
1421      *
1422      *  WORD = UPPER_CASE_WORD | LOWER_CASE_WORD | TITLE_CASE_WORD | DIGIT_WORD
1423      *
1424      *  UPPER_CASE_WORD = UPPER_CASE_LETTER+
1425      *  LOWER_CASE_WORD = LOWER_CASE_LETTER+
1426      *  TITLE_CASE_WORD = UPPER_CASE_LETTER LOWER_CASE_LETTER+
1427      *  DIGIT_WORD      = DIGIT+
1428      *
1429      *  UPPER_CASE_LETTER = Character.isUpperCase()
1430      *  LOWER_CASE_LETTER = Character.isLowerCase()
1431      *  DIGIT             = Character.isDigit()
1432      *  NON_LETTER_DIGIT  = !Character.isUpperCase() && !Character.isLowerCase() && !Character.isDigit()
1433      *
1434      *  DELIMITER = WHITESPACE | NON_LETTER_DIGIT
1435      * </pre>
1436      */
1437     private abstract static class WordTokenizer {
1438         protected static final char UNDERSCORE = '_';
1439 
1440         /**
1441          * Parse sentence。
1442          */
1443         public String parse(String str) {
1444             if (StringUtil.isEmpty(str)) {
1445                 return str;
1446             }
1447 
1448             int length = str.length();
1449             StringBuffer buffer = new StringBuffer(length);
1450 
1451             for (int index = 0; index < length; index++) {
1452                 char ch = str.charAt(index);
1453 
1454                 // 忽略空白。
1455                 if (Character.isWhitespace(ch)) {
1456                     continue;
1457                 }
1458 
1459                 // 大写字母开始:UpperCaseWord或是TitleCaseWord。
1460                 if (Character.isUpperCase(ch)) {
1461                     int wordIndex = index + 1;
1462 
1463                     while (wordIndex < length) {
1464                         char wordChar = str.charAt(wordIndex);
1465 
1466                         if (Character.isUpperCase(wordChar)) {
1467                             wordIndex++;
1468                         } else if (Character.isLowerCase(wordChar)) {
1469                             wordIndex--;
1470                             break;
1471                         } else {
1472                             break;
1473                         }
1474                     }
1475 
1476                     // 1. wordIndex == length,说明最后一个字母为大写,以upperCaseWord处理之。
1477                     // 2. wordIndex == index,说明index处为一个titleCaseWord。
1478                     // 3. wordIndex > index,说明index到wordIndex - 1处全部是大写,以upperCaseWord处理。
1479                     if ((wordIndex == length) || (wordIndex > index)) {
1480                         index = parseUpperCaseWord(buffer, str, index, wordIndex);
1481                     } else {
1482                         index = parseTitleCaseWord(buffer, str, index);
1483                     }
1484 
1485                     continue;
1486                 }
1487 
1488                 // 小写字母开始:LowerCaseWord。
1489                 if (Character.isLowerCase(ch)) {
1490                     index = parseLowerCaseWord(buffer, str, index);
1491                     continue;
1492                 }
1493 
1494                 // 数字开始:DigitWord。
1495                 if (Character.isDigit(ch)) {
1496                     index = parseDigitWord(buffer, str, index);
1497                     continue;
1498                 }
1499 
1500                 // 非字母数字开始:Delimiter。
1501                 inDelimiter(buffer, ch);
1502             }
1503 
1504             return buffer.toString();
1505         }
1506 
1507         private int parseUpperCaseWord(StringBuffer buffer, String str, int index, int length) {
1508             char ch = str.charAt(index++);
1509 
1510             // 首字母,必然存在且为大写。
1511             if (buffer.length() == 0) {
1512                 startSentence(buffer, ch);
1513             } else {
1514                 startWord(buffer, ch);
1515             }
1516 
1517             // 后续字母,必为小写。
1518             for (; index < length; index++) {
1519                 ch = str.charAt(index);
1520                 inWord(buffer, ch);
1521             }
1522 
1523             return index - 1;
1524         }
1525 
1526         private int parseLowerCaseWord(StringBuffer buffer, String str, int index) {
1527             char ch = str.charAt(index++);
1528 
1529             // 首字母,必然存在且为小写。
1530             if (buffer.length() == 0) {
1531                 startSentence(buffer, ch);
1532             } else {
1533                 startWord(buffer, ch);
1534             }
1535 
1536             // 后续字母,必为小写。
1537             int length = str.length();
1538 
1539             for (; index < length; index++) {
1540                 ch = str.charAt(index);
1541 
1542                 if (Character.isLowerCase(ch)) {
1543                     inWord(buffer, ch);
1544                 } else {
1545                     break;
1546                 }
1547             }
1548 
1549             return index - 1;
1550         }
1551 
1552         private int parseTitleCaseWord(StringBuffer buffer, String str, int index) {
1553             char ch = str.charAt(index++);
1554 
1555             // 首字母,必然存在且为大写。
1556             if (buffer.length() == 0) {
1557                 startSentence(buffer, ch);
1558             } else {
1559                 startWord(buffer, ch);
1560             }
1561 
1562             // 后续字母,必为小写。
1563             int length = str.length();
1564 
1565             for (; index < length; index++) {
1566                 ch = str.charAt(index);
1567 
1568                 if (Character.isLowerCase(ch)) {
1569                     inWord(buffer, ch);
1570                 } else {
1571                     break;
1572                 }
1573             }
1574 
1575             return index - 1;
1576         }
1577 
1578         private int parseDigitWord(StringBuffer buffer, String str, int index) {
1579             char ch = str.charAt(index++);
1580 
1581             // 首字符,必然存在且为数字。
1582             if (buffer.length() == 0) {
1583                 startDigitSentence(buffer, ch);
1584             } else {
1585                 startDigitWord(buffer, ch);
1586             }
1587 
1588             // 后续字符,必为数字。
1589             int length = str.length();
1590 
1591             for (; index < length; index++) {
1592                 ch = str.charAt(index);
1593 
1594                 if (Character.isDigit(ch)) {
1595                     inDigitWord(buffer, ch);
1596                 } else {
1597                     break;
1598                 }
1599             }
1600 
1601             return index - 1;
1602         }
1603 
1604         protected boolean isDelimiter(char ch) {
1605             return !Character.isUpperCase(ch) && !Character.isLowerCase(ch)
1606                    && !Character.isDigit(ch);
1607         }
1608 
1609         protected abstract void startSentence(StringBuffer buffer, char ch);
1610 
1611         protected abstract void startWord(StringBuffer buffer, char ch);
1612 
1613         protected abstract void inWord(StringBuffer buffer, char ch);
1614 
1615         protected abstract void startDigitSentence(StringBuffer buffer, char ch);
1616 
1617         protected abstract void startDigitWord(StringBuffer buffer, char ch);
1618 
1619         protected abstract void inDigitWord(StringBuffer buffer, char ch);
1620 
1621         protected abstract void inDelimiter(StringBuffer buffer, char ch);
1622     }
1623 
1624     /* ============================================================================ */
1625     /*  字符串分割函数。                                                            */
1626     /*                                                                              */
1627     /*  将字符串按指定分隔符分割。                                                  */
1628     /* ============================================================================ */
1629 
1630     /**
1631      * 将字符串按空白字符分割。
1632      *
1633      * <p>
1634      * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
1635      * <pre>
1636      * StringUtil.split(null)       = null
1637      * StringUtil.split("")         = []
1638      * StringUtil.split("abc def")  = ["abc", "def"]
1639      * StringUtil.split("abc  def") = ["abc", "def"]
1640      * StringUtil.split(" abc ")    = ["abc"]
1641      * </pre>
1642      * </p>
1643      *
1644      * @param str 要分割的字符串
1645      *
1646      * @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
1647      */
1648     public static String[] split(String str) {
1649         return split(str, null, -1);
1650     }
1651 
1652     /**
1653      * 将字符串按指定字符分割。
1654      *
1655      * <p>
1656      * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
1657      * <pre>
1658      * StringUtil.split(null, *)         = null
1659      * StringUtil.split("", *)           = []
1660      * StringUtil.split("a.b.c", '.')    = ["a", "b", "c"]
1661      * StringUtil.split("a..b.c", '.')   = ["a", "b", "c"]
1662      * StringUtil.split("a:b:c", '.')    = ["a:b:c"]
1663      * StringUtil.split("a b c", ' ')    = ["a", "b", "c"]
1664      * </pre>
1665      * </p>
1666      *
1667      * @param str 要分割的字符串
1668      * @param separatorChar 分隔符
1669      *
1670      * @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
1671      */
1672     public static String[] split(String str, char separatorChar) {
1673         if (str == null) {
1674             return null;
1675         }
1676 
1677         int length = str.length();
1678 
1679         if (length == 0) {
1680             return ArrayUtil.EMPTY_STRING_ARRAY;
1681         }
1682 
1683         List list = new ArrayList();
1684         int i = 0;
1685         int start = 0;
1686         boolean match = false;
1687 
1688         while (i < length) {
1689             if (str.charAt(i) == separatorChar) {
1690                 if (match) {
1691                     list.add(str.substring(start, i));
1692                     match = false;
1693                 }
1694 
1695                 start = ++i;
1696                 continue;
1697             }
1698 
1699             match = true;
1700             i++;
1701         }
1702 
1703         if (match) {
1704             list.add(str.substring(start, i));
1705         }
1706 
1707         return (String[]) list.toArray(new String[list.size()]);
1708     }
1709 
1710     /**
1711      * 将字符串按指定字符分割。
1712      *
1713      * <p>
1714      * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
1715      * <pre>
1716      * StringUtil.split(null, *)                = null
1717      * StringUtil.split("", *)                  = []
1718      * StringUtil.split("abc def", null)        = ["abc", "def"]
1719      * StringUtil.split("abc def", " ")         = ["abc", "def"]
1720      * StringUtil.split("abc  def", " ")        = ["abc", "def"]
1721      * StringUtil.split(" ab:  cd::ef  ", ":")  = ["ab", "cd", "ef"]
1722      * StringUtil.split("abc.def", "")          = ["abc.def"]
1723      *  </pre>
1724      * </p>
1725      *
1726      * @param str 要分割的字符串
1727      * @param separatorChars 分隔符
1728      *
1729      * @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
1730      */
1731     public static String[] split(String str, String separatorChars) {
1732         return split(str, separatorChars, -1);
1733     }
1734 
1735     /**
1736      * 将字符串按指定字符分割。
1737      *
1738      * <p>
1739      * 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
1740      * <pre>
1741      * StringUtil.split(null, *, *)                 = null
1742      * StringUtil.split("", *, *)                   = []
1743      * StringUtil.split("ab cd ef", null, 0)        = ["ab", "cd", "ef"]
1744      * StringUtil.split("  ab   cd ef  ", null, 0)  = ["ab", "cd", "ef"]
1745      * StringUtil.split("ab:cd::ef", ":", 0)        = ["ab", "cd", "ef"]
1746      * StringUtil.split("ab:cd:ef", ":", 2)         = ["ab", "cdef"]
1747      * StringUtil.split("abc.def", "", 2)           = ["abc.def"]
1748      * </pre>
1749      * </p>
1750      *
1751      * @param str 要分割的字符串
1752      * @param separatorChars 分隔符
1753      * @param max 返回的数组的最大个数,如果小于等于0,则表示无限制
1754      *
1755      * @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
1756      */
1757     public static String[] split(String str, String separatorChars, int max) {
1758         if (str == null) {
1759             return null;
1760         }
1761 
1762         int length = str.length();
1763 
1764         if (length == 0) {
1765             return ArrayUtil.EMPTY_STRING_ARRAY;
1766         }
1767 
1768         List list = new ArrayList();
1769         int sizePlus1 = 1;
1770         int i = 0;
1771         int start = 0;
1772         boolean match = false;
1773 
1774         if (separatorChars == null) {
1775             // null表示使用空白作为分隔符
1776             while (i < length) {
1777                 if (Character.isWhitespace(str.charAt(i))) {
1778                     if (match) {
1779                         if (sizePlus1++ == max) {
1780                             i = length;
1781                         }
1782 
1783                         list.add(str.substring(start, i));
1784                         match = false;
1785                     }
1786 
1787                     start = ++i;
1788                     continue;
1789                 }
1790 
1791                 match = true;
1792                 i++;
1793             }
1794         } else if (separatorChars.length() == 1) {
1795             // 优化分隔符长度为1的情形
1796             char sep = separatorChars.charAt(0);
1797 
1798             while (i < length) {
1799                 if (str.charAt(i) == sep) {
1800                     if (match) {
1801                         if (sizePlus1++ == max) {
1802                             i = length;
1803                         }
1804 
1805                         list.add(str.substring(start, i));
1806                         match = false;
1807                     }
1808 
1809                     start = ++i;
1810                     continue;
1811                 }
1812 
1813                 match = true;
1814                 i++;
1815             }
1816         } else {
1817             // 一般情形
1818             while (i < length) {
1819                 if (separatorChars.indexOf(str.charAt(i)) >= 0) {
1820                     if (match) {
1821                         if (sizePlus1++ == max) {
1822                             i = length;
1823                         }
1824 
1825                         list.add(str.substring(start, i));
1826                         match = false;
1827                     }
1828 
1829                     start = ++i;
1830                     continue;
1831                 }
1832 
1833                 match = true;
1834                 i++;
1835             }
1836         }
1837 
1838         if (match) {
1839             list.add(str.substring(start, i));
1840         }
1841 
1842         return (String[]) list.toArray(new String[list.size()]);
1843     }
1844 
1845     /* ============================================================================ */
1846     /*  字符串连接函数。                                                            */
1847     /*                                                                              */
1848     /*  将多个对象按指定分隔符连接成字符串。                                        */
1849     /* ============================================================================ */
1850 
1851     /**
1852      * 将数组中的元素连接成一个字符串。
1853      * <pre>
1854      * StringUtil.join(null)            = null
1855      * StringUtil.join([])              = ""
1856      * StringUtil.join([null])          = ""
1857      * StringUtil.join(["a", "b", "c"]) = "abc"
1858      * StringUtil.join([null, "", "a"]) = "a"
1859      * </pre>
1860      *
1861      * @param array 要连接的数组
1862      *
1863      * @return 连接后的字符串,如果原数组为<code>null</code>,则返回<code>null</code>
1864      */
1865     public static String join(Object[] array) {
1866         return join(array, null);
1867     }
1868 
1869     /**
1870      * 将数组中的元素连接成一个字符串。
1871      * <pre>
1872      * StringUtil.join(null, *)               = null
1873      * StringUtil.join([], *)                 = ""
1874      * StringUtil.join([null], *)             = ""
1875      * StringUtil.join(["a", "b", "c"], ';')  = "a;b;c"
1876      * StringUtil.join(["a", "b", "c"], null) = "abc"
1877      * StringUtil.join([null, "", "a"], ';')  = ";;a"
1878      * </pre>
1879      *
1880      * @param array 要连接的数组
1881      * @param separator 分隔符
1882      *
1883      * @return 连接后的字符串,如果原数组为<code>null</code>,则返回<code>null</code>
1884      */
1885     public static String join(Object[] array, char separator) {
1886         if (array == null) {
1887             return null;
1888         }
1889 
1890         int arraySize = array.length;
1891         int bufSize = (arraySize == 0) ? 0 : ((((array[0] == null) ? 16 : array[0].toString()
1892             .length()) + 1) * arraySize);
1893         StringBuffer buf = new StringBuffer(bufSize);
1894 
1895         for (int i = 0; i < arraySize; i++) {
1896             if (i > 0) {
1897                 buf.append(separator);
1898             }
1899 
1900             if (array[i] != null) {
1901                 buf.append(array[i]);
1902             }
1903         }
1904 
1905         return buf.toString();
1906     }
1907 
1908     /**
1909      * 将数组中的元素连接成一个字符串。
1910      * <pre>
1911      * StringUtil.join(null, *)                = null
1912      * StringUtil.join([], *)                  = ""
1913      * StringUtil.join([null], *)              = ""
1914      * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
1915      * StringUtil.join(["a", "b", "c"], null)  = "abc"
1916      * StringUtil.join(["a", "b", "c"], "")    = "abc"
1917      * StringUtil.join([null, "", "a"], ',')   = ",,a"
1918      * </pre>
1919      *
1920      * @param array 要连接的数组
1921      * @param separator 分隔符
1922      *
1923      * @return 连接后的字符串,如果原数组为<code>null</code>,则返回<code>null</code>
1924      */
1925     public static String join(Object[] array, String separator) {
1926         if (array == null) {
1927             return null;
1928         }
1929 
1930         if (separator == null) {
1931             separator = EMPTY_STRING;
1932         }
1933 
1934         int arraySize = array.length;
1935 
1936         // ArraySize ==  0: Len = 0
1937         // ArraySize > 0:   Len = NofStrings *(len(firstString) + len(separator))
1938         //           (估计大约所有的字符串都一样长)
1939         int bufSize = (arraySize == 0) ? 0 : (arraySize * (((array[0] == null) ? 16 : array[0]
1940             .toString().length()) + ((separator != null) ? separator.length() : 0)));
1941 
1942         StringBuffer buf = new StringBuffer(bufSize);
1943 
1944         for (int i = 0; i < arraySize; i++) {
1945             if ((separator != null) && (i > 0)) {
1946                 buf.append(separator);
1947             }
1948 
1949             if (array[i] != null) {
1950                 buf.append(array[i]);
1951             }
1952         }
1953 
1954         return buf.toString();
1955     }
1956 
1957     /**
1958      * 将<code>Iterator</code>中的元素连接成一个字符串。
1959      * <pre>
1960      * StringUtil.join(null, *)                = null
1961      * StringUtil.join([], *)                  = ""
1962      * StringUtil.join([null], *)              = ""
1963      * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
1964      * StringUtil.join(["a", "b", "c"], null)  = "abc"
1965      * StringUtil.join(["a", "b", "c"], "")    = "abc"
1966      * StringUtil.join([null, "", "a"], ',')   = ",,a"
1967      * </pre>
1968      *
1969      * @param iterator 要连接的<code>Iterator</code>
1970      * @param separator 分隔符
1971      *
1972      * @return 连接后的字符串,如果原数组为<code>null</code>,则返回<code>null</code>
1973      */
1974     public static String join(Iterator iterator, char separator) {
1975         if (iterator == null) {
1976             return null;
1977         }
1978 
1979         StringBuffer buf = new StringBuffer(256); // Java默认值是16, 可能偏小
1980 
1981         while (iterator.hasNext()) {
1982             Object obj = iterator.next();
1983 
1984             if (obj != null) {
1985                 buf.append(obj);
1986             }
1987 
1988             if (iterator.hasNext()) {
1989                 buf.append(separator);
1990             }
1991         }
1992 
1993         return buf.toString();
1994     }
1995 
1996     /**
1997      * 将<code>Iterator</code>中的元素连接成一个字符串。
1998      * <pre>
1999      * StringUtil.join(null, *)                = null
2000      * StringUtil.join([], *)                  = ""
2001      * StringUtil.join([null], *)              = ""
2002      * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
2003      * StringUtil.join(["a", "b", "c"], null)  = "abc"
2004      * StringUtil.join(["a", "b", "c"], "")    = "abc"
2005      * StringUtil.join([null, "", "a"], ',')   = ",,a"
2006      * </pre>
2007      *
2008      * @param iterator 要连接的<code>Iterator</code>
2009      * @param separator 分隔符
2010      *
2011      * @return 连接后的字符串,如果原数组为<code>null</code>,则返回<code>null</code>
2012      */
2013     public static String join(Iterator iterator, String separator) {
2014         if (iterator == null) {
2015             return null;
2016         }
2017 
2018         StringBuffer buf = new StringBuffer(256); // Java默认值是16, 可能偏小
2019 
2020         while (iterator.hasNext()) {
2021             Object obj = iterator.next();
2022 
2023             if (obj != null) {
2024                 buf.append(obj);
2025             }
2026 
2027             if ((separator != null) && iterator.hasNext()) {
2028                 buf.append(separator);
2029             }
2030         }
2031 
2032         return buf.toString();
2033     }
2034 
2035     /* ============================================================================ */
2036     /*  字符串查找函数 —— 字符或字符串。                                          */
2037     /*                                                                              */
2038     /*  在字符串中查找指定字符或字符串。                                            */
2039     /* ============================================================================ */
2040 
2041     /**
2042      * 在字符串中查找指定字符,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2043      * <pre>
2044      * StringUtil.indexOf(null, *)         = -1
2045      * StringUtil.indexOf("", *)           = -1
2046      * StringUtil.indexOf("aabaabaa", 'a') = 0
2047      * StringUtil.indexOf("aabaabaa", 'b') = 2
2048      * </pre>
2049      *
2050      * @param str 要扫描的字符串
2051      * @param searchChar 要查找的字符
2052      *
2053      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2054      */
2055     public static int indexOf(String str, char searchChar) {
2056         if ((str == null) || (str.length() == 0)) {
2057             return -1;
2058         }
2059 
2060         return str.indexOf(searchChar);
2061     }
2062 
2063     /**
2064      * 在字符串中查找指定字符,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2065      * <pre>
2066      * StringUtil.indexOf(null, *, *)          = -1
2067      * StringUtil.indexOf("", *, *)            = -1
2068      * StringUtil.indexOf("aabaabaa", 'b', 0)  = 2
2069      * StringUtil.indexOf("aabaabaa", 'b', 3)  = 5
2070      * StringUtil.indexOf("aabaabaa", 'b', 9)  = -1
2071      * StringUtil.indexOf("aabaabaa", 'b', -1) = 2
2072      * </pre>
2073      *
2074      * @param str 要扫描的字符串
2075      * @param searchChar 要查找的字符
2076      * @param startPos 开始搜索的索引值,如果小于0,则看作0
2077      *
2078      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2079      */
2080     public static int indexOf(String str, char searchChar, int startPos) {
2081         if ((str == null) || (str.length() == 0)) {
2082             return -1;
2083         }
2084 
2085         return str.indexOf(searchChar, startPos);
2086     }
2087 
2088     /**
2089      * 在字符串中查找指定字符串,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2090      * <pre>
2091      * StringUtil.indexOf(null, *)          = -1
2092      * StringUtil.indexOf(*, null)          = -1
2093      * StringUtil.indexOf("", "")           = 0
2094      * StringUtil.indexOf("aabaabaa", "a")  = 0
2095      * StringUtil.indexOf("aabaabaa", "b")  = 2
2096      * StringUtil.indexOf("aabaabaa", "ab") = 1
2097      * StringUtil.indexOf("aabaabaa", "")   = 0
2098      * </pre>
2099      *
2100      * @param str 要扫描的字符串
2101      * @param searchStr 要查找的字符串
2102      *
2103      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2104      */
2105     public static int indexOf(String str, String searchStr) {
2106         if ((str == null) || (searchStr == null)) {
2107             return -1;
2108         }
2109 
2110         return str.indexOf(searchStr);
2111     }
2112 
2113     /**
2114      * 在字符串中查找指定字符串,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2115      * <pre>
2116      * StringUtil.indexOf(null, *, *)          = -1
2117      * StringUtil.indexOf(*, null, *)          = -1
2118      * StringUtil.indexOf("", "", 0)           = 0
2119      * StringUtil.indexOf("aabaabaa", "a", 0)  = 0
2120      * StringUtil.indexOf("aabaabaa", "b", 0)  = 2
2121      * StringUtil.indexOf("aabaabaa", "ab", 0) = 1
2122      * StringUtil.indexOf("aabaabaa", "b", 3)  = 5
2123      * StringUtil.indexOf("aabaabaa", "b", 9)  = -1
2124      * StringUtil.indexOf("aabaabaa", "b", -1) = 2
2125      * StringUtil.indexOf("aabaabaa", "", 2)   = 2
2126      * StringUtil.indexOf("abc", "", 9)        = 3
2127      * </pre>
2128      *
2129      * @param str 要扫描的字符串
2130      * @param searchStr 要查找的字符串
2131      * @param startPos 开始搜索的索引值,如果小于0,则看作0
2132      *
2133      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2134      */
2135     public static int indexOf(String str, String searchStr, int startPos) {
2136         if ((str == null) || (searchStr == null)) {
2137             return -1;
2138         }
2139 
2140         // JDK1.3及以下版本的bug:不能正确处理下面的情况
2141         if ((searchStr.length() == 0) && (startPos >= str.length())) {
2142             return str.length();
2143         }
2144 
2145         return str.indexOf(searchStr, startPos);
2146     }
2147 
2148     /**
2149      * 在字符串中查找指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为<code>null</code>,则返回<code>-1</code>。
2150      * 如果字符集合为<code>null</code>或空,也返回<code>-1</code>。
2151      * <pre>
2152      * StringUtil.indexOfAny(null, *)                = -1
2153      * StringUtil.indexOfAny("", *)                  = -1
2154      * StringUtil.indexOfAny(*, null)                = -1
2155      * StringUtil.indexOfAny(*, [])                  = -1
2156      * StringUtil.indexOfAny("zzabyycdxx",['z','a']) = 0
2157      * StringUtil.indexOfAny("zzabyycdxx",['b','y']) = 3
2158      * StringUtil.indexOfAny("aba", ['z'])           = -1
2159      * </pre>
2160      *
2161      * @param str 要扫描的字符串
2162      * @param searchChars 要搜索的字符集合
2163      *
2164      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2165      */
2166     public static int indexOfAny(String str, char[] searchChars) {
2167         if ((str == null) || (str.length() == 0) || (searchChars == null)
2168             || (searchChars.length == 0)) {
2169             return -1;
2170         }
2171 
2172         for (int i = 0; i < str.length(); i++) {
2173             char ch = str.charAt(i);
2174 
2175             for (int j = 0; j < searchChars.length; j++) {
2176                 if (searchChars[j] == ch) {
2177                     return i;
2178                 }
2179             }
2180         }
2181 
2182         return -1;
2183     }
2184 
2185     /**
2186      * 在字符串中查找指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为<code>null</code>,则返回<code>-1</code>。
2187      * 如果字符集合为<code>null</code>或空,也返回<code>-1</code>。
2188      * <pre>
2189      * StringUtil.indexOfAny(null, *)            = -1
2190      * StringUtil.indexOfAny("", *)              = -1
2191      * StringUtil.indexOfAny(*, null)            = -1
2192      * StringUtil.indexOfAny(*, "")              = -1
2193      * StringUtil.indexOfAny("zzabyycdxx", "za") = 0
2194      * StringUtil.indexOfAny("zzabyycdxx", "by") = 3
2195      * StringUtil.indexOfAny("aba","z")          = -1
2196      * </pre>
2197      *
2198      * @param str 要扫描的字符串
2199      * @param searchChars 要搜索的字符集合
2200      *
2201      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2202      */
2203     public static int indexOfAny(String str, String searchChars) {
2204         if ((str == null) || (str.length() == 0) || (searchChars == null)
2205             || (searchChars.length() == 0)) {
2206             return -1;
2207         }
2208 
2209         for (int i = 0; i < str.length(); i++) {
2210             char ch = str.charAt(i);
2211 
2212             for (int j = 0; j < searchChars.length(); j++) {
2213                 if (searchChars.charAt(j) == ch) {
2214                     return i;
2215                 }
2216             }
2217         }
2218 
2219         return -1;
2220     }
2221 
2222     /**
2223      * 在字符串中查找指定字符串集合中的字符串,并返回第一个匹配的起始索引。 如果字符串为<code>null</code>,则返回<code>-1</code>。
2224      * 如果字符串集合为<code>null</code>或空,也返回<code>-1</code>。
2225      * 如果字符串集合包括<code>""</code>,并且字符串不为<code>null</code>,则返回<code>str.length()</code>
2226      * <pre>
2227      * StringUtil.indexOfAny(null, *)                     = -1
2228      * StringUtil.indexOfAny(*, null)                     = -1
2229      * StringUtil.indexOfAny(*, [])                       = -1
2230      * StringUtil.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
2231      * StringUtil.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
2232      * StringUtil.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
2233      * StringUtil.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
2234      * StringUtil.indexOfAny("zzabyycdxx", [""])          = 0
2235      * StringUtil.indexOfAny("", [""])                    = 0
2236      * StringUtil.indexOfAny("", ["a"])                   = -1
2237      * </pre>
2238      *
2239      * @param str 要扫描的字符串
2240      * @param searchStrs 要搜索的字符串集合
2241      *
2242      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2243      */
2244     public static int indexOfAny(String str, String[] searchStrs) {
2245         if ((str == null) || (searchStrs == null)) {
2246             return -1;
2247         }
2248 
2249         int sz = searchStrs.length;
2250 
2251         // String's can't have a MAX_VALUEth index.
2252         int ret = Integer.MAX_VALUE;
2253 
2254         int tmp = 0;
2255 
2256         for (int i = 0; i < sz; i++) {
2257             String search = searchStrs[i];
2258 
2259             if (search == null) {
2260                 continue;
2261             }
2262 
2263             tmp = str.indexOf(search);
2264 
2265             if (tmp == -1) {
2266                 continue;
2267             }
2268 
2269             if (tmp < ret) {
2270                 ret = tmp;
2271             }
2272         }
2273 
2274         return (ret == Integer.MAX_VALUE) ? (-1) : ret;
2275     }
2276 
2277     /**
2278      * 在字符串中查找不在指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为<code>null</code>,则返回<code>-1</code>。
2279      * 如果字符集合为<code>null</code>或空,也返回<code>-1</code>。
2280      * <pre>
2281      * StringUtil.indexOfAnyBut(null, *)             = -1
2282      * StringUtil.indexOfAnyBut("", *)               = -1
2283      * StringUtil.indexOfAnyBut(*, null)             = -1
2284      * StringUtil.indexOfAnyBut(*, [])               = -1
2285      * StringUtil.indexOfAnyBut("zzabyycdxx",'za')   = 3
2286      * StringUtil.indexOfAnyBut("zzabyycdxx", 'by')  = 0
2287      * StringUtil.indexOfAnyBut("aba", 'ab')         = -1
2288      * </pre>
2289      *
2290      * @param str 要扫描的字符串
2291      * @param searchChars 要搜索的字符集合
2292      *
2293      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2294      */
2295     public static int indexOfAnyBut(String str, char[] searchChars) {
2296         if ((str == null) || (str.length() == 0) || (searchChars == null)
2297             || (searchChars.length == 0)) {
2298             return -1;
2299         }
2300 
2301         outer: for (int i = 0; i < str.length(); i++) {
2302             char ch = str.charAt(i);
2303 
2304             for (int j = 0; j < searchChars.length; j++) {
2305                 if (searchChars[j] == ch) {
2306                     continue outer;
2307                 }
2308             }
2309 
2310             return i;
2311         }
2312 
2313         return -1;
2314     }
2315 
2316     /**
2317      * 在字符串中查找不在指定字符集合中的字符,并返回第一个匹配的起始索引。 如果字符串为<code>null</code>,则返回<code>-1</code>。
2318      * 如果字符集合为<code>null</code>或空,也返回<code>-1</code>。
2319      * <pre>
2320      * StringUtil.indexOfAnyBut(null, *)            = -1
2321      * StringUtil.indexOfAnyBut("", *)              = -1
2322      * StringUtil.indexOfAnyBut(*, null)            = -1
2323      * StringUtil.indexOfAnyBut(*, "")              = -1
2324      * StringUtil.indexOfAnyBut("zzabyycdxx", "za") = 3
2325      * StringUtil.indexOfAnyBut("zzabyycdxx", "by") = 0
2326      * StringUtil.indexOfAnyBut("aba","ab")         = -1
2327      * </pre>
2328      *
2329      * @param str 要扫描的字符串
2330      * @param searchChars 要搜索的字符集合
2331      *
2332      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2333      */
2334     public static int indexOfAnyBut(String str, String searchChars) {
2335         if ((str == null) || (str.length() == 0) || (searchChars == null)
2336             || (searchChars.length() == 0)) {
2337             return -1;
2338         }
2339 
2340         for (int i = 0; i < str.length(); i++) {
2341             if (searchChars.indexOf(str.charAt(i)) < 0) {
2342                 return i;
2343             }
2344         }
2345 
2346         return -1;
2347     }
2348 
2349     /**
2350      * 从字符串尾部开始查找指定字符,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2351      * <pre>
2352      * StringUtil.lastIndexOf(null, *)         = -1
2353      * StringUtil.lastIndexOf("", *)           = -1
2354      * StringUtil.lastIndexOf("aabaabaa", 'a') = 7
2355      * StringUtil.lastIndexOf("aabaabaa", 'b') = 5
2356      * </pre>
2357      *
2358      * @param str 要扫描的字符串
2359      * @param searchChar 要查找的字符
2360      *
2361      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2362      */
2363     public static int lastIndexOf(String str, char searchChar) {
2364         if ((str == null) || (str.length() == 0)) {
2365             return -1;
2366         }
2367 
2368         return str.lastIndexOf(searchChar);
2369     }
2370 
2371     /**
2372      * 从字符串尾部开始查找指定字符,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2373      * <pre>
2374      * StringUtil.lastIndexOf(null, *, *)          = -1
2375      * StringUtil.lastIndexOf("", *,  *)           = -1
2376      * StringUtil.lastIndexOf("aabaabaa", 'b', 8)  = 5
2377      * StringUtil.lastIndexOf("aabaabaa", 'b', 4)  = 2
2378      * StringUtil.lastIndexOf("aabaabaa", 'b', 0)  = -1
2379      * StringUtil.lastIndexOf("aabaabaa", 'b', 9)  = 5
2380      * StringUtil.lastIndexOf("aabaabaa", 'b', -1) = -1
2381      * StringUtil.lastIndexOf("aabaabaa", 'a', 0)  = 0
2382      * </pre>
2383      *
2384      * @param str 要扫描的字符串
2385      * @param searchChar 要查找的字符
2386      * @param startPos 从指定索引开始向前搜索
2387      *
2388      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2389      */
2390     public static int lastIndexOf(String str, char searchChar, int startPos) {
2391         if ((str == null) || (str.length() == 0)) {
2392             return -1;
2393         }
2394 
2395         return str.lastIndexOf(searchChar, startPos);
2396     }
2397 
2398     /**
2399      * 从字符串尾部开始查找指定字符串,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2400      * <pre>
2401      * StringUtil.lastIndexOf(null, *)         = -1
2402      * StringUtil.lastIndexOf("", *)           = -1
2403      * StringUtil.lastIndexOf("aabaabaa", 'a') = 7
2404      * StringUtil.lastIndexOf("aabaabaa", 'b') = 5
2405      * </pre>
2406      *
2407      * @param str 要扫描的字符串
2408      * @param searchStr 要查找的字符串
2409      *
2410      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2411      */
2412     public static int lastIndexOf(String str, String searchStr) {
2413         if ((str == null) || (searchStr == null)) {
2414             return -1;
2415         }
2416 
2417         return str.lastIndexOf(searchStr);
2418     }
2419 
2420     /**
2421      * 从字符串尾部开始查找指定字符串,并返回第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>。
2422      * <pre>
2423      * StringUtil.lastIndexOf(null, *, *)          = -1
2424      * StringUtil.lastIndexOf(*, null, *)          = -1
2425      * StringUtil.lastIndexOf("aabaabaa", "a", 8)  = 7
2426      * StringUtil.lastIndexOf("aabaabaa", "b", 8)  = 5
2427      * StringUtil.lastIndexOf("aabaabaa", "ab", 8) = 4
2428      * StringUtil.lastIndexOf("aabaabaa", "b", 9)  = 5
2429      * StringUtil.lastIndexOf("aabaabaa", "b", -1) = -1
2430      * StringUtil.lastIndexOf("aabaabaa", "a", 0)  = 0
2431      * StringUtil.lastIndexOf("aabaabaa", "b", 0)  = -1
2432      * </pre>
2433      *
2434      * @param str 要扫描的字符串
2435      * @param searchStr 要查找的字符串
2436      * @param startPos 从指定索引开始向前搜索
2437      *
2438      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2439      */
2440     public static int lastIndexOf(String str, String searchStr, int startPos) {
2441         if ((str == null) || (searchStr == null)) {
2442             return -1;
2443         }
2444 
2445         return str.lastIndexOf(searchStr, startPos);
2446     }
2447 
2448     /**
2449      * 从字符串尾部开始查找指定字符串集合中的字符串,并返回第一个匹配的起始索引。 如果字符串为<code>null</code>,则返回<code>-1</code>。
2450      * 如果字符串集合为<code>null</code>或空,也返回<code>-1</code>。
2451      * 如果字符串集合包括<code>""</code>,并且字符串不为<code>null</code>,则返回<code>str.length()</code>
2452      * <pre>
2453      * StringUtil.lastIndexOfAny(null, *)                   = -1
2454      * StringUtil.lastIndexOfAny(*, null)                   = -1
2455      * StringUtil.lastIndexOfAny(*, [])                     = -1
2456      * StringUtil.lastIndexOfAny(*, [null])                 = -1
2457      * StringUtil.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
2458      * StringUtil.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
2459      * StringUtil.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
2460      * StringUtil.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
2461      * StringUtil.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
2462      * </pre>
2463      *
2464      * @param str 要扫描的字符串
2465      * @param searchStrs 要搜索的字符串集合
2466      *
2467      * @return 第一个匹配的索引值。如果字符串为<code>null</code>或未找到,则返回<code>-1</code>
2468      */
2469     public static int lastIndexOfAny(String str, String[] searchStrs) {
2470         if ((str == null) || (searchStrs == null)) {
2471             return -1;
2472         }
2473 
2474         int searchStrsLength = searchStrs.length;
2475         int index = -1;
2476         int tmp = 0;
2477 
2478         for (int i = 0; i < searchStrsLength; i++) {
2479             String search = searchStrs[i];
2480 
2481             if (search == null) {
2482                 continue;
2483             }
2484 
2485             tmp = str.lastIndexOf(search);
2486 
2487             if (tmp > index) {
2488                 index = tmp;
2489             }
2490         }
2491 
2492         return index;
2493     }
2494 
2495     /**
2496      * 检查字符串中是否包含指定的字符。如果字符串为<code>null</code>,将返回<code>false</code>。
2497      * <pre>
2498      * StringUtil.contains(null, *)    = false
2499      * StringUtil.contains("", *)      = false
2500      * StringUtil.contains("abc", 'a') = true
2501      * StringUtil.contains("abc", 'z') = false
2502      * </pre>
2503      *
2504      * @param str 要扫描的字符串
2505      * @param searchChar 要查找的字符
2506      *
2507      * @return 如果找到,则返回<code>true</code>
2508      */
2509     public static boolean contains(String str, char searchChar) {
2510         if ((str == null) || (str.length() == 0)) {
2511             return false;
2512         }
2513 
2514         return str.indexOf(searchChar) >= 0;
2515     }
2516 
2517     /**
2518      * 检查字符串中是否包含指定的字符串。如果字符串为<code>null</code>,将返回<code>false</code>。
2519      * <pre>
2520      * StringUtil.contains(null, *)     = false
2521      * StringUtil.contains(*, null)     = false
2522      * StringUtil.contains("", "")      = true
2523      * StringUtil.contains("abc", "")   = true
2524      * StringUtil.contains("abc", "a")  = true
2525      * StringUtil.contains("abc", "z")  = false
2526      * </pre>
2527      *
2528      * @param str 要扫描的字符串
2529      * @param searchStr 要查找的字符串
2530      *
2531      * @return 如果找到,则返回<code>true</code>
2532      */
2533     public static boolean contains(String str, String searchStr) {
2534         if ((str == null) || (searchStr == null)) {
2535             return false;
2536         }
2537 
2538         return str.indexOf(searchStr) >= 0;
2539     }
2540 
2541     /**
2542      * 检查字符串是是否只包含指定字符集合中的字符。
2543      *
2544      * <p>
2545      * 如果字符串为<code>null</code>,则返回<code>false</code>。
2546      * 如果字符集合为<code>null</code>则返回<code>false</code>。 但是空字符串永远返回<code>true</code>.
2547      * </p>
2548      * <pre>
2549      * StringUtil.containsOnly(null, *)       = false
2550      * StringUtil.containsOnly(*, null)       = false
2551      * StringUtil.containsOnly("", *)         = true
2552      * StringUtil.containsOnly("ab", '')      = false
2553      * StringUtil.containsOnly("abab", 'abc') = true
2554      * StringUtil.containsOnly("ab1", 'abc')  = false
2555      * StringUtil.containsOnly("abz", 'abc')  = false
2556      * </pre>
2557      *
2558      * @param str 要扫描的字符串
2559      * @param valid 要查找的字符串
2560      *
2561      * @return 如果找到,则返回<code>true</code>
2562      */
2563     public static boolean containsOnly(String str, char[] valid) {
2564         if ((valid == null) || (str == null)) {
2565             return false;
2566         }
2567 
2568         if (str.length() == 0) {
2569             return true;
2570         }
2571 
2572         if (valid.length == 0) {
2573             return false;
2574         }
2575 
2576         return indexOfAnyBut(str, valid) == -1;
2577     }
2578 
2579     /**
2580      * 检查字符串是是否只包含指定字符集合中的字符。
2581      *
2582      * <p>
2583      * 如果字符串为<code>null</code>,则返回<code>false</code>。
2584      * 如果字符集合为<code>null</code>则返回<code>false</code>。 但是空字符串永远返回<code>true</code>.
2585      * </p>
2586      * <pre>
2587      * StringUtil.containsOnly(null, *)       = false
2588      * StringUtil.containsOnly(*, null)       = false
2589      * StringUtil.containsOnly("", *)         = true
2590      * StringUtil.containsOnly("ab", "")      = false
2591      * StringUtil.containsOnly("abab", "abc") = true
2592      * StringUtil.containsOnly("ab1", "abc")  = false
2593      * StringUtil.containsOnly("abz", "abc")  = false
2594      * </pre>
2595      *
2596      * @param str 要扫描的字符串
2597      * @param valid 要查找的字符串
2598      *
2599      * @return 如果找到,则返回<code>true</code>
2600      */
2601     public static boolean containsOnly(String str, String valid) {
2602         if ((str == null) || (valid == null)) {
2603             return false;
2604         }
2605 
2606         return containsOnly(str, valid.toCharArray());
2607     }
2608 
2609     /**
2610      * 检查字符串是是否不包含指定字符集合中的字符。
2611      *
2612      * <p>
2613      * 如果字符串为<code>null</code>,则返回<code>false</code>。 如果字符集合为<code>null</code>则返回<code>true</code>。
2614      * 但是空字符串永远返回<code>true</code>.
2615      * </p>
2616      * <pre>
2617      * StringUtil.containsNone(null, *)       = true
2618      * StringUtil.containsNone(*, null)       = true
2619      * StringUtil.containsNone("", *)         = true
2620      * StringUtil.containsNone("ab", '')      = true
2621      * StringUtil.containsNone("abab", 'xyz') = true
2622      * StringUtil.containsNone("ab1", 'xyz')  = true
2623      * StringUtil.containsNone("abz", 'xyz')  = false
2624      * </pre>
2625      *
2626      * @param str 要扫描的字符串
2627      * @param invalid 要查找的字符串
2628      *
2629      * @return 如果找到,则返回<code>true</code>
2630      */
2631     public static boolean containsNone(String str, char[] invalid) {
2632         if ((str == null) || (invalid == null)) {
2633             return true;
2634         }
2635 
2636         int strSize = str.length();
2637         int validSize = invalid.length;
2638 
2639         for (int i = 0; i < strSize; i++) {
2640             char ch = str.charAt(i);
2641 
2642             for (int j = 0; j < validSize; j++) {
2643                 if (invalid[j] == ch) {
2644                     return false;
2645                 }
2646             }
2647         }
2648 
2649         return true;
2650     }
2651 
2652     /**
2653      * 检查字符串是是否不包含指定字符集合中的字符。
2654      *
2655      * <p>
2656      * 如果字符串为<code>null</code>,则返回<code>false</code>。 如果字符集合为<code>null</code>则返回<code>true</code>。
2657      * 但是空字符串永远返回<code>true</code>.
2658      * </p>
2659      * <pre>
2660      * StringUtil.containsNone(null, *)       = true
2661      * StringUtil.containsNone(*, null)       = true
2662      * StringUtil.containsNone("", *)         = true
2663      * StringUtil.containsNone("ab", "")      = true
2664      * StringUtil.containsNone("abab", "xyz") = true
2665      * StringUtil.containsNone("ab1", "xyz")  = true
2666      * StringUtil.containsNone("abz", "xyz")  = false
2667      * </pre>
2668      *
2669      * @param str 要扫描的字符串
2670      * @param invalidChars 要查找的字符串
2671      *
2672      * @return 如果找到,则返回<code>true</code>
2673      */
2674     public static boolean containsNone(String str, String invalidChars) {
2675         if ((str == null) || (invalidChars == null)) {
2676             return true;
2677         }
2678 
2679         return containsNone(str, invalidChars.toCharArray());
2680     }
2681 
2682     /**
2683      * 取得指定子串在字符串中出现的次数。
2684      *
2685      * <p>
2686      * 如果字符串为<code>null</code>或空,则返回<code>0</code>。
2687      * <pre>
2688      * StringUtil.countMatches(null, *)       = 0
2689      * StringUtil.countMatches("", *)         = 0
2690      * StringUtil.countMatches("abba", null)  = 0
2691      * StringUtil.countMatches("abba", "")    = 0
2692      * StringUtil.countMatches("abba", "a")   = 2
2693      * StringUtil.countMatches("abba", "ab")  = 1
2694      * StringUtil.countMatches("abba", "xxx") = 0
2695      * </pre>
2696      * </p>
2697      *
2698      * @param str 要扫描的字符串
2699      * @param subStr 子字符串
2700      *
2701      * @return 子串在字符串中出现的次数,如果字符串为<code>null</code>或空,则返回<code>0</code>
2702      */
2703     public static int countMatches(String str, String subStr) {
2704         if ((str == null) || (str.length() == 0) || (subStr == null) || (subStr.length() == 0)) {
2705             return 0;
2706         }
2707 
2708         int count = 0;
2709         int index = 0;
2710 
2711         while ((index = str.indexOf(subStr, index)) != -1) {
2712             count++;
2713             index += subStr.length();
2714         }
2715 
2716         return count;
2717     }
2718 
2719     /* ============================================================================ */
2720     /*  取子串函数。                                                                */
2721     /* ============================================================================ */
2722 
2723     /**
2724      * 取指定字符串的子串。
2725      *
2726      * <p>
2727      * 负的索引代表从尾部开始计算。如果字符串为<code>null</code>,则返回<code>null</code>。
2728      * <pre>
2729      * StringUtil.substring(null, *)   = null
2730      * StringUtil.substring("", *)     = ""
2731      * StringUtil.substring("abc", 0)  = "abc"
2732      * StringUtil.substring("abc", 2)  = "c"
2733      * StringUtil.substring("abc", 4)  = ""
2734      * StringUtil.substring("abc", -2) = "bc"
2735      * StringUtil.substring("abc", -4) = "abc"
2736      * </pre>
2737      * </p>
2738      *
2739      * @param str 字符串
2740      * @param start 起始索引,如果为负数,表示从尾部查找
2741      *
2742      * @return 子串,如果原始串为<code>null</code>,则返回<code>null</code>
2743      */
2744     public static String substring(String str, int start) {
2745         if (str == null) {
2746             return null;
2747         }
2748 
2749         if (start < 0) {
2750             start = str.length() + start;
2751         }
2752 
2753         if (start < 0) {
2754             start = 0;
2755         }
2756 
2757         if (start > str.length()) {
2758             return EMPTY_STRING;
2759         }
2760 
2761         return str.substring(start);
2762     }
2763 
2764     /**
2765      * 取指定字符串的子串。
2766      *
2767      * <p>
2768      * 负的索引代表从尾部开始计算。如果字符串为<code>null</code>,则返回<code>null</code>。
2769      * <pre>
2770      * StringUtil.substring(null, *, *)    = null
2771      * StringUtil.substring("", * ,  *)    = "";
2772      * StringUtil.substring("abc", 0, 2)   = "ab"
2773      * StringUtil.substring("abc", 2, 0)   = ""
2774      * StringUtil.substring("abc", 2, 4)   = "c"
2775      * StringUtil.substring("abc", 4, 6)   = ""
2776      * StringUtil.substring("abc", 2, 2)   = ""
2777      * StringUtil.substring("abc", -2, -1) = "b"
2778      * StringUtil.substring("abc", -4, 2)  = "ab"
2779      * </pre>
2780      * </p>
2781      *
2782      * @param str 字符串
2783      * @param start 起始索引,如果为负数,表示从尾部计算
2784      * @param end 结束索引(不含),如果为负数,表示从尾部计算
2785      *
2786      * @return 子串,如果原始串为<code>null</code>,则返回<code>null</code>
2787      */
2788     public static String substring(String str, int start, int end) {
2789         if (str == null) {
2790             return null;
2791         }
2792 
2793         if (end < 0) {
2794             end = str.length() + end;
2795         }
2796 
2797         if (start < 0) {
2798             start = str.length() + start;
2799         }
2800 
2801         if (end > str.length()) {
2802             end = str.length();
2803         }
2804 
2805         if (start > end) {
2806             return EMPTY_STRING;
2807         }
2808 
2809         if (start < 0) {
2810             start = 0;
2811         }
2812 
2813         if (end < 0) {
2814             end = 0;
2815         }
2816 
2817         return str.substring(start, end);
2818     }
2819 
2820     /**
2821      * 取得长度为指定字符数的最左边的子串。
2822      * <pre>
2823      * StringUtil.left(null, *)    = null
2824      * StringUtil.left(*, -ve)     = ""
2825      * StringUtil.left("", *)      = ""
2826      * StringUtil.left("abc", 0)   = ""
2827      * StringUtil.left("abc", 2)   = "ab"
2828      * StringUtil.left("abc", 4)   = "abc"
2829      * </pre>
2830      *
2831      * @param str 字符串
2832      * @param len 最左子串的长度
2833      *
2834      * @return 子串,如果原始字串为<code>null</code>,则返回<code>null</code>
2835      */
2836     public static String left(String str, int len) {
2837         if (str == null) {
2838             return null;
2839         }
2840 
2841         if (len < 0) {
2842             return EMPTY_STRING;
2843         }
2844 
2845         if (str.length() <= len) {
2846             return str;
2847         } else {
2848             return str.substring(0, len);
2849         }
2850     }
2851 
2852     /**
2853      * 取得长度为指定字符数的最右边的子串。
2854      * <pre>
2855      * StringUtil.right(null, *)    = null
2856      * StringUtil.right(*, -ve)     = ""
2857      * StringUtil.right("", *)      = ""
2858      * StringUtil.right("abc", 0)   = ""
2859      * StringUtil.right("abc", 2)   = "bc"
2860      * StringUtil.right("abc", 4)   = "abc"
2861      * </pre>
2862      *
2863      * @param str 字符串
2864      * @param len 最右子串的长度
2865      *
2866      * @return 子串,如果原始字串为<code>null</code>,则返回<code>null</code>
2867      */
2868     public static String right(String str, int len) {
2869         if (str == null) {
2870             return null;
2871         }
2872 
2873         if (len < 0) {
2874             return EMPTY_STRING;
2875         }
2876 
2877         if (str.length() <= len) {
2878             return str;
2879         } else {
2880             return str.substring(str.length() - len);
2881         }
2882     }
2883 
2884     /**
2885      * 取得从指定索引开始计算的、长度为指定字符数的子串。
2886      * <pre>
2887      * StringUtil.mid(null, *, *)    = null
2888      * StringUtil.mid(*, *, -ve)     = ""
2889      * StringUtil.mid("", 0, *)      = ""
2890      * StringUtil.mid("abc", 0, 2)   = "ab"
2891      * StringUtil.mid("abc", 0, 4)   = "abc"
2892      * StringUtil.mid("abc", 2, 4)   = "c"
2893      * StringUtil.mid("abc", 4, 2)   = ""
2894      * StringUtil.mid("abc", -2, 2)  = "ab"
2895      * </pre>
2896      *
2897      * @param str 字符串
2898      * @param pos 起始索引,如果为负数,则看作<code>0</code>
2899      * @param len 子串的长度,如果为负数,则看作长度为<code>0</code>
2900      *
2901      * @return 子串,如果原始字串为<code>null</code>,则返回<code>null</code>
2902      */
2903     public static String mid(String str, int pos, int len) {
2904         if (str == null) {
2905             return null;
2906         }
2907 
2908         if ((len < 0) || (pos > str.length())) {
2909             return EMPTY_STRING;
2910         }
2911 
2912         if (pos < 0) {
2913             pos = 0;
2914         }
2915 
2916         if (str.length() <= (pos + len)) {
2917             return str.substring(pos);
2918         } else {
2919             return str.substring(pos, pos + len);
2920         }
2921     }
2922 
2923     /* ============================================================================ */
2924     /*  搜索并取子串函数。                                                          */
2925     /* ============================================================================ */
2926 
2927     /**
2928      * 取得第一个出现的分隔子串之前的子串。
2929      *
2930      * <p>
2931      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>或未找到该子串,则返回原字符串。
2932      * <pre>
2933      * StringUtil.substringBefore(null, *)      = null
2934      * StringUtil.substringBefore("", *)        = ""
2935      * StringUtil.substringBefore("abc", "a")   = ""
2936      * StringUtil.substringBefore("abcba", "b") = "a"
2937      * StringUtil.substringBefore("abc", "c")   = "ab"
2938      * StringUtil.substringBefore("abc", "d")   = "abc"
2939      * StringUtil.substringBefore("abc", "")    = ""
2940      * StringUtil.substringBefore("abc", null)  = "abc"
2941      * </pre>
2942      * </p>
2943      *
2944      * @param str 字符串
2945      * @param separator 要搜索的分隔子串
2946      *
2947      * @return 子串,如果原始串为<code>null</code>,则返回<code>null</code>
2948      */
2949     public static String substringBefore(String str, String separator) {
2950         if ((str == null) || (separator == null) || (str.length() == 0)) {
2951             return str;
2952         }
2953 
2954         if (separator.length() == 0) {
2955             return EMPTY_STRING;
2956         }
2957 
2958         int pos = str.indexOf(separator);
2959 
2960         if (pos == -1) {
2961             return str;
2962         }
2963 
2964         return str.substring(0, pos);
2965     }
2966 
2967     /**
2968      * 取得第一个出现的分隔子串之后的子串。
2969      *
2970      * <p>
2971      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>或未找到该子串,则返回原字符串。
2972      * <pre>
2973      * StringUtil.substringAfter(null, *)      = null
2974      * StringUtil.substringAfter("", *)        = ""
2975      * StringUtil.substringAfter(*, null)      = ""
2976      * StringUtil.substringAfter("abc", "a")   = "bc"
2977      * StringUtil.substringAfter("abcba", "b") = "cba"
2978      * StringUtil.substringAfter("abc", "c")   = ""
2979      * StringUtil.substringAfter("abc", "d")   = ""
2980      * StringUtil.substringAfter("abc", "")    = "abc"
2981      * </pre>
2982      * </p>
2983      *
2984      * @param str 字符串
2985      * @param separator 要搜索的分隔子串
2986      *
2987      * @return 子串,如果原始串为<code>null</code>,则返回<code>null</code>
2988      */
2989     public static String substringAfter(String str, String separator) {
2990         if ((str == null) || (str.length() == 0)) {
2991             return str;
2992         }
2993 
2994         if (separator == null) {
2995             return EMPTY_STRING;
2996         }
2997 
2998         int pos = str.indexOf(separator);
2999 
3000         if (pos == -1) {
3001             return EMPTY_STRING;
3002         }
3003 
3004         return str.substring(pos + separator.length());
3005     }
3006 
3007     /**
3008      * 取得最后一个的分隔子串之前的子串。
3009      *
3010      * <p>
3011      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>或未找到该子串,则返回原字符串。
3012      * <pre>
3013      * StringUtil.substringBeforeLast(null, *)      = null
3014      * StringUtil.substringBeforeLast("", *)        = ""
3015      * StringUtil.substringBeforeLast("abcba", "b") = "abc"
3016      * StringUtil.substringBeforeLast("abc", "c")   = "ab"
3017      * StringUtil.substringBeforeLast("a", "a")     = ""
3018      * StringUtil.substringBeforeLast("a", "z")     = "a"
3019      * StringUtil.substringBeforeLast("a", null)    = "a"
3020      * StringUtil.substringBeforeLast("a", "")      = "a"
3021      * </pre>
3022      * </p>
3023      *
3024      * @param str 字符串
3025      * @param separator 要搜索的分隔子串
3026      *
3027      * @return 子串,如果原始串为<code>null</code>,则返回<code>null</code>
3028      */
3029     public static String substringBeforeLast(String str, String separator) {
3030         if ((str == null) || (separator == null) || (str.length() == 0)
3031             || (separator.length() == 0)) {
3032             return str;
3033         }
3034 
3035         int pos = str.lastIndexOf(separator);
3036 
3037         if (pos == -1) {
3038             return str;
3039         }
3040 
3041         return str.substring(0, pos);
3042     }
3043 
3044     /**
3045      * 取得最后一个的分隔子串之后的子串。
3046      *
3047      * <p>
3048      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>或未找到该子串,则返回原字符串。
3049      * <pre>
3050      * StringUtil.substringAfterLast(null, *)      = null
3051      * StringUtil.substringAfterLast("", *)        = ""
3052      * StringUtil.substringAfterLast(*, "")        = ""
3053      * StringUtil.substringAfterLast(*, null)      = ""
3054      * StringUtil.substringAfterLast("abc", "a")   = "bc"
3055      * StringUtil.substringAfterLast("abcba", "b") = "a"
3056      * StringUtil.substringAfterLast("abc", "c")   = ""
3057      * StringUtil.substringAfterLast("a", "a")     = ""
3058      * StringUtil.substringAfterLast("a", "z")     = ""
3059      * </pre>
3060      * </p>
3061      *
3062      * @param str 字符串
3063      * @param separator 要搜索的分隔子串
3064      *
3065      * @return 子串,如果原始串为<code>null</code>,则返回<code>null</code>
3066      */
3067     public static String substringAfterLast(String str, String separator) {
3068         if ((str == null) || (str.length() == 0)) {
3069             return str;
3070         }
3071 
3072         if ((separator == null) || (separator.length() == 0)) {
3073             return EMPTY_STRING;
3074         }
3075 
3076         int pos = str.lastIndexOf(separator);
3077 
3078         if ((pos == -1) || (pos == (str.length() - separator.length()))) {
3079             return EMPTY_STRING;
3080         }
3081 
3082         return str.substring(pos + separator.length());
3083     }
3084 
3085     /**
3086      * 取得指定分隔符的前两次出现之间的子串。
3087      *
3088      * <p>
3089      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>,则返回<code>null</code>。
3090      * <pre>
3091      * StringUtil.substringBetween(null, *)            = null
3092      * StringUtil.substringBetween("", "")             = ""
3093      * StringUtil.substringBetween("", "tag")          = null
3094      * StringUtil.substringBetween("tagabctag", null)  = null
3095      * StringUtil.substringBetween("tagabctag", "")    = ""
3096      * StringUtil.substringBetween("tagabctag", "tag") = "abc"
3097      * </pre>
3098      * </p>
3099      *
3100      * @param str 字符串
3101      * @param tag 要搜索的分隔子串
3102      *
3103      * @return 子串,如果原始串为<code>null</code>或未找到分隔子串,则返回<code>null</code>
3104      */
3105     public static String substringBetween(String str, String tag) {
3106         return substringBetween(str, tag, tag, 0);
3107     }
3108 
3109     /**
3110      * 取得两个分隔符之间的子串。
3111      *
3112      * <p>
3113      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>,则返回<code>null</code>。
3114      * <pre>
3115      * StringUtil.substringBetween(null, *, *)          = null
3116      * StringUtil.substringBetween("", "", "")          = ""
3117      * StringUtil.substringBetween("", "", "tag")       = null
3118      * StringUtil.substringBetween("", "tag", "tag")    = null
3119      * StringUtil.substringBetween("yabcz", null, null) = null
3120      * StringUtil.substringBetween("yabcz", "", "")     = ""
3121      * StringUtil.substringBetween("yabcz", "y", "z")   = "abc"
3122      * StringUtil.substringBetween("yabczyabcz", "y", "z")   = "abc"
3123      * </pre>
3124      * </p>
3125      *
3126      * @param str 字符串
3127      * @param open 要搜索的分隔子串1
3128      * @param close 要搜索的分隔子串2
3129      *
3130      * @return 子串,如果原始串为<code>null</code>或未找到分隔子串,则返回<code>null</code>
3131      */
3132     public static String substringBetween(String str, String open, String close) {
3133         return substringBetween(str, open, close, 0);
3134     }
3135 
3136     /**
3137      * 取得两个分隔符之间的子串。
3138      *
3139      * <p>
3140      * 如果字符串为<code>null</code>,则返回<code>null</code>。 如果分隔子串为<code>null</code>,则返回<code>null</code>。
3141      * <pre>
3142      * StringUtil.substringBetween(null, *, *)          = null
3143      * StringUtil.substringBetween("", "", "")          = ""
3144      * StringUtil.substringBetween("", "", "tag")       = null
3145      * StringUtil.substringBetween("", "tag", "tag")    = null
3146      * StringUtil.substringBetween("yabcz", null, null) = null
3147      * StringUtil.substringBetween("yabcz", "", "")     = ""
3148      * StringUtil.substringBetween("yabcz", "y", "z")   = "abc"
3149      * StringUtil.substringBetween("yabczyabcz", "y", "z")   = "abc"
3150      * </pre>
3151      * </p>
3152      *
3153      * @param str 字符串
3154      * @param open 要搜索的分隔子串1
3155      * @param close 要搜索的分隔子串2
3156      * @param fromIndex 从指定index处搜索
3157      *
3158      * @return 子串,如果原始串为<code>null</code>或未找到分隔子串,则返回<code>null</code>
3159      */
3160     public static String substringBetween(String str, String open, String close, int fromIndex) {
3161         if ((str == null) || (open == null) || (close == null)) {
3162             return null;
3163         }
3164 
3165         int start = str.indexOf(open, fromIndex);
3166 
3167         if (start != -1) {
3168             int end = str.indexOf(close, start + open.length());
3169 
3170             if (end != -1) {
3171                 return str.substring(start + open.length(), end);
3172             }
3173         }
3174 
3175         return null;
3176     }
3177 
3178     /* ============================================================================ */
3179     /*  删除字符。                                                                  */
3180     /* ============================================================================ */
3181 
3182     /**
3183      * 删除所有在<code>Character.isWhitespace(char)</code>中所定义的空白。
3184      * <pre>
3185      * StringUtil.deleteWhitespace(null)         = null
3186      * StringUtil.deleteWhitespace("")           = ""
3187      * StringUtil.deleteWhitespace("abc")        = "abc"
3188      * StringUtil.deleteWhitespace("   ab  c  ") = "abc"
3189      * </pre>
3190      *
3191      * @param str 要处理的字符串
3192      *
3193      * @return 去空白后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3194      */
3195     public static String deleteWhitespace(String str) {
3196         if (str == null) {
3197             return null;
3198         }
3199 
3200         int sz = str.length();
3201         StringBuffer buffer = new StringBuffer(sz);
3202 
3203         for (int i = 0; i < sz; i++) {
3204             if (!Character.isWhitespace(str.charAt(i))) {
3205                 buffer.append(str.charAt(i));
3206             }
3207         }
3208 
3209         return buffer.toString();
3210     }
3211 
3212     /* ============================================================================ */
3213     /*  替换子串。                                                                  */
3214     /* ============================================================================ */
3215 
3216     /**
3217      * 替换指定的子串,只替换第一个出现的子串。
3218      *
3219      * <p>
3220      * 如果字符串为<code>null</code>则返回<code>null</code>,如果指定子串为<code>null</code>,则返回原字符串。
3221      * <pre>
3222      * StringUtil.replaceOnce(null, *, *)        = null
3223      * StringUtil.replaceOnce("", *, *)          = ""
3224      * StringUtil.replaceOnce("aba", null, null) = "aba"
3225      * StringUtil.replaceOnce("aba", null, null) = "aba"
3226      * StringUtil.replaceOnce("aba", "a", null)  = "aba"
3227      * StringUtil.replaceOnce("aba", "a", "")    = "ba"
3228      * StringUtil.replaceOnce("aba", "a", "z")   = "zba"
3229      * </pre>
3230      * </p>
3231      *
3232      * @param text 要扫描的字符串
3233      * @param repl 要搜索的子串
3234      * @param with 替换字符串
3235      *
3236      * @return 被替换后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3237      */
3238     public static String replaceOnce(String text, String repl, String with) {
3239         return replace(text, repl, with, 1);
3240     }
3241 
3242     /**
3243      * 替换指定的子串,替换所有出现的子串。
3244      *
3245      * <p>
3246      * 如果字符串为<code>null</code>则返回<code>null</code>,如果指定子串为<code>null</code>,则返回原字符串。
3247      * <pre>
3248      * StringUtil.replace(null, *, *)        = null
3249      * StringUtil.replace("", *, *)          = ""
3250      * StringUtil.replace("aba", null, null) = "aba"
3251      * StringUtil.replace("aba", null, null) = "aba"
3252      * StringUtil.replace("aba", "a", null)  = "aba"
3253      * StringUtil.replace("aba", "a", "")    = "b"
3254      * StringUtil.replace("aba", "a", "z")   = "zbz"
3255      * </pre>
3256      * </p>
3257      *
3258      * @param text 要扫描的字符串
3259      * @param repl 要搜索的子串
3260      * @param with 替换字符串
3261      *
3262      * @return 被替换后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3263      */
3264     public static String replace(String text, String repl, String with) {
3265         return replace(text, repl, with, -1);
3266     }
3267 
3268     /**
3269      * 替换指定的子串,替换指定的次数。
3270      *
3271      * <p>
3272      * 如果字符串为<code>null</code>则返回<code>null</code>,如果指定子串为<code>null</code>,则返回原字符串。
3273      * <pre>
3274      * StringUtil.replace(null, *, *, *)         = null
3275      * StringUtil.replace("", *, *, *)           = ""
3276      * StringUtil.replace("abaa", null, null, 1) = "abaa"
3277      * StringUtil.replace("abaa", null, null, 1) = "abaa"
3278      * StringUtil.replace("abaa", "a", null, 1)  = "abaa"
3279      * StringUtil.replace("abaa", "a", "", 1)    = "baa"
3280      * StringUtil.replace("abaa", "a", "z", 0)   = "abaa"
3281      * StringUtil.replace("abaa", "a", "z", 1)   = "zbaa"
3282      * StringUtil.replace("abaa", "a", "z", 2)   = "zbza"
3283      * StringUtil.replace("abaa", "a", "z", -1)  = "zbzz"
3284      * </pre>
3285      * </p>
3286      *
3287      * @param text 要扫描的字符串
3288      * @param repl 要搜索的子串
3289      * @param with 替换字符串
3290      * @param max maximum number of values to replace, or <code>-1</code> if no maximum
3291      *
3292      * @return 被替换后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3293      */
3294     public static String replace(String text, String repl, String with, int max) {
3295         if ((text == null) || (repl == null) || (with == null) || (repl.length() == 0)
3296             || (max == 0)) {
3297             return text;
3298         }
3299 
3300         StringBuffer buf = new StringBuffer(text.length());
3301         int start = 0;
3302         int end = 0;
3303 
3304         while ((end = text.indexOf(repl, start)) != -1) {
3305             buf.append(text.substring(start, end)).append(with);
3306             start = end + repl.length();
3307 
3308             if (--max == 0) {
3309                 break;
3310             }
3311         }
3312 
3313         buf.append(text.substring(start));
3314         return buf.toString();
3315     }
3316 
3317     /**
3318      * 将字符串中所有指定的字符,替换成另一个。
3319      *
3320      * <p>
3321      * 如果字符串为<code>null</code>则返回<code>null</code>。
3322      * <pre>
3323      * StringUtil.replaceChars(null, *, *)        = null
3324      * StringUtil.replaceChars("", *, *)          = ""
3325      * StringUtil.replaceChars("abcba", 'b', 'y') = "aycya"
3326      * StringUtil.replaceChars("abcba", 'z', 'y') = "abcba"
3327      * </pre>
3328      * </p>
3329      *
3330      * @param str 要扫描的字符串
3331      * @param searchChar 要搜索的字符
3332      * @param replaceChar 替换字符
3333      *
3334      * @return 被替换后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3335      */
3336     public static String replaceChars(String str, char searchChar, char replaceChar) {
3337         if (str == null) {
3338             return null;
3339         }
3340 
3341         return str.replace(searchChar, replaceChar);
3342     }
3343 
3344     /**
3345      * 将字符串中所有指定的字符,替换成另一个。
3346      *
3347      * <p>
3348      * 如果字符串为<code>null</code>则返回<code>null</code>。如果搜索字符串为<code>null</code>或空,则返回原字符串。
3349      * </p>
3350      *
3351      * <p>
3352      * 例如: <code>replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = jelly</code>。
3353      * </p>
3354      *
3355      * <p>
3356      * 通常搜索字符串和替换字符串是等长的,如果搜索字符串比替换字符串长,则多余的字符将被删除。 如果搜索字符串比替换字符串短,则缺少的字符将被忽略。
3357      * <pre>
3358      * StringUtil.replaceChars(null, *, *)           = null
3359      * StringUtil.replaceChars("", *, *)             = ""
3360      * StringUtil.replaceChars("abc", null, *)       = "abc"
3361      * StringUtil.replaceChars("abc", "", *)         = "abc"
3362      * StringUtil.replaceChars("abc", "b", null)     = "ac"
3363      * StringUtil.replaceChars("abc", "b", "")       = "ac"
3364      * StringUtil.replaceChars("abcba", "bc", "yz")  = "ayzya"
3365      * StringUtil.replaceChars("abcba", "bc", "y")   = "ayya"
3366      * StringUtil.replaceChars("abcba", "bc", "yzx") = "ayzya"
3367      * </pre>
3368      * </p>
3369      *
3370      * @param str 要扫描的字符串
3371      * @param searchChars 要搜索的字符串
3372      * @param replaceChars 替换字符串
3373      *
3374      * @return 被替换后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3375      */
3376     public static String replaceChars(String str, String searchChars, String replaceChars) {
3377         if ((str == null) || (str.length() == 0) || (searchChars == null)
3378             || (searchChars.length() == 0)) {
3379             return str;
3380         }
3381 
3382         char[] chars = str.toCharArray();
3383         int len = chars.length;
3384         boolean modified = false;
3385 
3386         for (int i = 0, isize = searchChars.length(); i < isize; i++) {
3387             char searchChar = searchChars.charAt(i);
3388 
3389             if ((replaceChars == null) || (i >= replaceChars.length())) {
3390                 // 删除
3391                 int pos = 0;
3392 
3393                 for (int j = 0; j < len; j++) {
3394                     if (chars[j] != searchChar) {
3395                         chars[pos++] = chars[j];
3396                     } else {
3397                         modified = true;
3398                     }
3399                 }
3400 
3401                 len = pos;
3402             } else {
3403                 // 替换
3404                 for (int j = 0; j < len; j++) {
3405                     if (chars[j] == searchChar) {
3406                         chars[j] = replaceChars.charAt(i);
3407                         modified = true;
3408                     }
3409                 }
3410             }
3411         }
3412 
3413         if (!modified) {
3414             return str;
3415         }
3416 
3417         return new String(chars, 0, len);
3418     }
3419 
3420     /**
3421      * 将指定的子串用另一指定子串覆盖。
3422      *
3423      * <p>
3424      * 如果字符串为<code>null</code>,则返回<code>null</code>。 负的索引值将被看作<code>0</code>,越界的索引值将被设置成字符串的长度相同的值。
3425      * <pre>
3426      * StringUtil.overlay(null, *, *, *)            = null
3427      * StringUtil.overlay("", "abc", 0, 0)          = "abc"
3428      * StringUtil.overlay("abcdef", null, 2, 4)     = "abef"
3429      * StringUtil.overlay("abcdef", "", 2, 4)       = "abef"
3430      * StringUtil.overlay("abcdef", "", 4, 2)       = "abef"
3431      * StringUtil.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
3432      * StringUtil.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
3433      * StringUtil.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
3434      * StringUtil.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
3435      * StringUtil.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
3436      * StringUtil.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"
3437      * </pre>
3438      * </p>
3439      *
3440      * @param str 要扫描的字符串
3441      * @param overlay 用来覆盖的字符串
3442      * @param start 起始索引
3443      * @param end 结束索引
3444      *
3445      * @return 被覆盖后的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3446      */
3447     public static String overlay(String str, String overlay, int start, int end) {
3448         if (str == null) {
3449             return null;
3450         }
3451 
3452         if (overlay == null) {
3453             overlay = EMPTY_STRING;
3454         }
3455 
3456         int len = str.length();
3457 
3458         if (start < 0) {
3459             start = 0;
3460         }
3461 
3462         if (start > len) {
3463             start = len;
3464         }
3465 
3466         if (end < 0) {
3467             end = 0;
3468         }
3469 
3470         if (end > len) {
3471             end = len;
3472         }
3473 
3474         if (start > end) {
3475             int temp = start;
3476 
3477             start = end;
3478             end = temp;
3479         }
3480 
3481         return new StringBuffer((len + start) - end + overlay.length() + 1).append(
3482             str.substring(0, start)).append(overlay).append(str.substring(end)).toString();
3483     }
3484 
3485     /* ============================================================================ */
3486     /*  Perl风格的chomp和chop函数。                                                 */
3487     /* ============================================================================ */
3488 
3489     /**
3490      * 删除字符串末尾的换行符。如果字符串不以换行结尾,则什么也不做。
3491      *
3492      * <p>
3493      * 换行符有三种情形:&quot;<code>\n</code>&quot;、&quot;<code>\r</code>&quot;、&quot;<code>\r\n</code>&quot;。
3494      * <pre>
3495      * StringUtil.chomp(null)          = null
3496      * StringUtil.chomp("")            = ""
3497      * StringUtil.chomp("abc \r")      = "abc "
3498      * StringUtil.chomp("abc\n")       = "abc"
3499      * StringUtil.chomp("abc\r\n")     = "abc"
3500      * StringUtil.chomp("abc\r\n\r\n") = "abc\r\n"
3501      * StringUtil.chomp("abc\n\r")     = "abc\n"
3502      * StringUtil.chomp("abc\n\rabc")  = "abc\n\rabc"
3503      * StringUtil.chomp("\r")          = ""
3504      * StringUtil.chomp("\n")          = ""
3505      * StringUtil.chomp("\r\n")        = ""
3506      * </pre>
3507      * </p>
3508      *
3509      * @param str 要处理的字符串
3510      *
3511      * @return 不以换行结尾的字符串,如果原始字串为<code>null</code>,则返回<code>null</code>
3512      */
3513     public static String chomp(String str) {
3514         if ((str == null) || (str.length() == 0)) {
3515             return str;
3516         }
3517 
3518         if (str.length() == 1) {
3519             char ch = str.charAt(0);
3520 
3521             if ((ch == '\r') || (ch == '\n')) {
3522                 return EMPTY_STRING;
3523             } else {
3524                 return str;
3525             }
3526         }
3527 
3528         int lastIdx = str.length() - 1;
3529         char last = str.charAt(lastIdx);
3530 
3531         if (last == '\n') {
3532             if (str.charAt(lastIdx - 1) == '\r') {
3533                 lastIdx--;
3534             }
3535         } else if (last == '\r') {
3536         } else {
3537             lastIdx++;
3538         }
3539 
3540         return str.substring(0, lastIdx);
3541     }
3542 
3543     /**
3544      * 删除字符串末尾的指定字符串。如果字符串不以该字符串结尾,则什么也不做。
3545      * <pre>
3546      * StringUtil.chomp(null, *)         = null
3547      * StringUtil.chomp("", *)           = ""
3548      * StringUtil.chomp("foobar", "bar") = "foo"
3549      * StringUtil.chomp("foobar", "baz") = "foobar"
3550      * StringUtil.chomp("foo", "foo")    = ""
3551      * StringUtil.chomp("foo ", "foo")   = "foo "
3552      * StringUtil.chomp(" foo", "foo")   = " "
3553      * StringUtil.chomp("foo", "foooo")  = "foo"
3554      * StringUtil.chomp("foo", "")       = "foo"
3555      * StringUtil.chomp("foo", null)     = "foo"
3556      * </pre>
3557      *
3558      * @param str 要处理的字符串
3559      * @param separator 要删除的字符串
3560      *
3561      * @return 不以指定字符串结尾的字符串,如果原始字串为<code>null</code>,则返回<code>null</code>
3562      */
3563     public static String chomp(String str, String separator) {
3564         if ((str == null) || (str.length() == 0) || (separator == null)) {
3565             return str;
3566         }
3567 
3568         if (str.endsWith(separator)) {
3569             return str.substring(0, str.length() - separator.length());
3570         }
3571 
3572         return str;
3573     }
3574 
3575     /**
3576      * 删除最后一个字符。
3577      *
3578      * <p>
3579      * 如果字符串以<code>\r\n</code>结尾,则同时删除它们。
3580      * <pre>
3581      * StringUtil.chop(null)          = null
3582      * StringUtil.chop("")            = ""
3583      * StringUtil.chop("abc \r")      = "abc "
3584      * StringUtil.chop("abc\n")       = "abc"
3585      * StringUtil.chop("abc\r\n")     = "abc"
3586      * StringUtil.chop("abc")         = "ab"
3587      * StringUtil.chop("abc\nabc")    = "abc\nab"
3588      * StringUtil.chop("a")           = ""
3589      * StringUtil.chop("\r")          = ""
3590      * StringUtil.chop("\n")          = ""
3591      * StringUtil.chop("\r\n")        = ""
3592      * </pre>
3593      * </p>
3594      *
3595      * @param str 要处理的字符串
3596      *
3597      * @return 删除最后一个字符的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3598      */
3599     public static String chop(String str) {
3600         if (str == null) {
3601             return null;
3602         }
3603 
3604         int strLen = str.length();
3605 
3606         if (strLen < 2) {
3607             return EMPTY_STRING;
3608         }
3609 
3610         int lastIdx = strLen - 1;
3611         String ret = str.substring(0, lastIdx);
3612         char last = str.charAt(lastIdx);
3613 
3614         if (last == '\n') {
3615             if (ret.charAt(lastIdx - 1) == '\r') {
3616                 return ret.substring(0, lastIdx - 1);
3617             }
3618         }
3619 
3620         return ret;
3621     }
3622 
3623     /* ============================================================================ */
3624     /*  重复/对齐字符串。                                                           */
3625     /* ============================================================================ */
3626 
3627     /**
3628      * 将指定字符串重复n遍。
3629      * <pre>
3630      * StringUtil.repeat(null, 2)   = null
3631      * StringUtil.repeat("", 0)     = ""
3632      * StringUtil.repeat("", 2)     = ""
3633      * StringUtil.repeat("a", 3)    = "aaa"
3634      * StringUtil.repeat("ab", 2)   = "abab"
3635      * StringUtil.repeat("abcd", 2) = "abcdabcd"
3636      * StringUtil.repeat("a", -2)   = ""
3637      * </pre>
3638      *
3639      * @param str 要重复的字符串
3640      * @param repeat 重复次数,如果小于<code>0</code>,则看作<code>0</code>
3641      *
3642      * @return 重复n次的字符串,如果原始字符串为<code>null</code>,则返回<code>null</code>
3643      */
3644     public static String repeat(String str, int repeat) {
3645         if (str == null) {
3646             return null;
3647         }
3648 
3649         if (repeat <= 0) {
3650             return EMPTY_STRING;
3651         }
3652 
3653         int inputLength = str.length();
3654 
3655         if ((repeat == 1) || (inputLength == 0)) {
3656             return str;
3657         }
3658 
3659         int outputLength = inputLength * repeat;
3660 
3661         switch (inputLength) {
3662             case 1:
3663 
3664                 char ch = str.charAt(0);
3665                 char[] output1 = new char[outputLength];
3666 
3667                 for (int i = repeat - 1; i >= 0; i--) {
3668                     output1[i] = ch;
3669                 }
3670 
3671                 return new String(output1);
3672 
3673             case 2:
3674 
3675                 char ch0 = str.charAt(0);
3676                 char ch1 = str.charAt(1);
3677                 char[] output2 = new char[outputLength];
3678 
3679                 for (int i = (repeat * 2) - 2; i >= 0; i--, i--) {
3680                     output2[i] = ch0;
3681                     output2[i + 1] = ch1;
3682                 }
3683 
3684                 return new String(output2);
3685 
3686             default:
3687 
3688                 StringBuffer buf = new StringBuffer(outputLength);
3689 
3690                 for (int i = 0; i < repeat; i++) {
3691                     buf.append(str);
3692                 }
3693 
3694                 return buf.toString();
3695         }
3696     }
3697 
3698     /**
3699      * 扩展并左对齐字符串,用空格<code>' '</code>填充右边。
3700      * <pre>
3701      * StringUtil.alignLeft(null, *)   = null
3702      * StringUtil.alignLeft("", 3)     = "   "
3703      * StringUtil.alignLeft("bat", 3)  = "bat"
3704      * StringUtil.alignLeft("bat", 5)  = "bat  "
3705      * StringUtil.alignLeft("bat", 1)  = "bat"
3706      * StringUtil.alignLeft("bat", -1) = "bat"
3707      * </pre>
3708      *
3709      * @param str 要对齐的字符串
3710      * @param size 扩展字符串到指定宽度
3711      *
3712      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3713      */
3714     public static String alignLeft(String str, int size) {
3715         return alignLeft(str, size, ' ');
3716     }
3717 
3718     /**
3719      * 扩展并左对齐字符串,用指定字符填充右边。
3720      * <pre>
3721      * StringUtil.alignLeft(null, *, *)     = null
3722      * StringUtil.alignLeft("", 3, 'z')     = "zzz"
3723      * StringUtil.alignLeft("bat", 3, 'z')  = "bat"
3724      * StringUtil.alignLeft("bat", 5, 'z')  = "batzz"
3725      * StringUtil.alignLeft("bat", 1, 'z')  = "bat"
3726      * StringUtil.alignLeft("bat", -1, 'z') = "bat"
3727      * </pre>
3728      *
3729      * @param str 要对齐的字符串
3730      * @param size 扩展字符串到指定宽度
3731      * @param padChar 填充字符
3732      *
3733      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3734      */
3735     public static String alignLeft(String str, int size, char padChar) {
3736         if (str == null) {
3737             return null;
3738         }
3739 
3740         int pads = size - str.length();
3741 
3742         if (pads <= 0) {
3743             return str;
3744         }
3745 
3746         return alignLeft(str, size, String.valueOf(padChar));
3747     }
3748 
3749     /**
3750      * 扩展并左对齐字符串,用指定字符串填充右边。
3751      * <pre>
3752      * StringUtil.alignLeft(null, *, *)      = null
3753      * StringUtil.alignLeft("", 3, "z")      = "zzz"
3754      * StringUtil.alignLeft("bat", 3, "yz")  = "bat"
3755      * StringUtil.alignLeft("bat", 5, "yz")  = "batyz"
3756      * StringUtil.alignLeft("bat", 8, "yz")  = "batyzyzy"
3757      * StringUtil.alignLeft("bat", 1, "yz")  = "bat"
3758      * StringUtil.alignLeft("bat", -1, "yz") = "bat"
3759      * StringUtil.alignLeft("bat", 5, null)  = "bat  "
3760      * StringUtil.alignLeft("bat", 5, "")    = "bat  "
3761      * </pre>
3762      *
3763      * @param str 要对齐的字符串
3764      * @param size 扩展字符串到指定宽度
3765      * @param padStr 填充字符串
3766      *
3767      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3768      */
3769     public static String alignLeft(String str, int size, String padStr) {
3770         if (str == null) {
3771             return null;
3772         }
3773 
3774         if ((padStr == null) || (padStr.length() == 0)) {
3775             padStr = " ";
3776         }
3777 
3778         int padLen = padStr.length();
3779         int strLen = str.length();
3780         int pads = size - strLen;
3781 
3782         if (pads <= 0) {
3783             return str;
3784         }
3785 
3786         if (pads == padLen) {
3787             return str.concat(padStr);
3788         } else if (pads < padLen) {
3789             return str.concat(padStr.substring(0, pads));
3790         } else {
3791             char[] padding = new char[pads];
3792             char[] padChars = padStr.toCharArray();
3793 
3794             for (int i = 0; i < pads; i++) {
3795                 padding[i] = padChars[i % padLen];
3796             }
3797 
3798             return str.concat(new String(padding));
3799         }
3800     }
3801 
3802     /**
3803      * 扩展并右对齐字符串,用空格<code>' '</code>填充左边。
3804      * <pre>
3805      * StringUtil.alignRight(null, *)   = null
3806      * StringUtil.alignRight("", 3)     = "   "
3807      * StringUtil.alignRight("bat", 3)  = "bat"
3808      * StringUtil.alignRight("bat", 5)  = "  bat"
3809      * StringUtil.alignRight("bat", 1)  = "bat"
3810      * StringUtil.alignRight("bat", -1) = "bat"
3811      * </pre>
3812      *
3813      * @param str 要对齐的字符串
3814      * @param size 扩展字符串到指定宽度
3815      *
3816      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3817      */
3818     public static String alignRight(String str, int size) {
3819         return alignRight(str, size, ' ');
3820     }
3821 
3822     /**
3823      * 扩展并右对齐字符串,用指定字符填充左边。
3824      * <pre>
3825      * StringUtil.alignRight(null, *, *)     = null
3826      * StringUtil.alignRight("", 3, 'z')     = "zzz"
3827      * StringUtil.alignRight("bat", 3, 'z')  = "bat"
3828      * StringUtil.alignRight("bat", 5, 'z')  = "zzbat"
3829      * StringUtil.alignRight("bat", 1, 'z')  = "bat"
3830      * StringUtil.alignRight("bat", -1, 'z') = "bat"
3831      * </pre>
3832      *
3833      * @param str 要对齐的字符串
3834      * @param size 扩展字符串到指定宽度
3835      * @param padChar 填充字符
3836      *
3837      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3838      */
3839     public static String alignRight(String str, int size, char padChar) {
3840         if (str == null) {
3841             return null;
3842         }
3843 
3844         int pads = size - str.length();
3845 
3846         if (pads <= 0) {
3847             return str;
3848         }
3849 
3850         return alignRight(str, size, String.valueOf(padChar));
3851     }
3852 
3853     /**
3854      * 扩展并右对齐字符串,用指定字符串填充左边。
3855      * <pre>
3856      * StringUtil.alignRight(null, *, *)      = null
3857      * StringUtil.alignRight("", 3, "z")      = "zzz"
3858      * StringUtil.alignRight("bat", 3, "yz")  = "bat"
3859      * StringUtil.alignRight("bat", 5, "yz")  = "yzbat"
3860      * StringUtil.alignRight("bat", 8, "yz")  = "yzyzybat"
3861      * StringUtil.alignRight("bat", 1, "yz")  = "bat"
3862      * StringUtil.alignRight("bat", -1, "yz") = "bat"
3863      * StringUtil.alignRight("bat", 5, null)  = "  bat"
3864      * StringUtil.alignRight("bat", 5, "")    = "  bat"
3865      * </pre>
3866      *
3867      * @param str 要对齐的字符串
3868      * @param size 扩展字符串到指定宽度
3869      * @param padStr 填充字符串
3870      *
3871      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3872      */
3873     public static String alignRight(String str, int size, String padStr) {
3874         if (str == null) {
3875             return null;
3876         }
3877 
3878         if ((padStr == null) || (padStr.length() == 0)) {
3879             padStr = " ";
3880         }
3881 
3882         int padLen = padStr.length();
3883         int strLen = str.length();
3884         int pads = size - strLen;
3885 
3886         if (pads <= 0) {
3887             return str;
3888         }
3889 
3890         if (pads == padLen) {
3891             return padStr.concat(str);
3892         } else if (pads < padLen) {
3893             return padStr.substring(0, pads).concat(str);
3894         } else {
3895             char[] padding = new char[pads];
3896             char[] padChars = padStr.toCharArray();
3897 
3898             for (int i = 0; i < pads; i++) {
3899                 padding[i] = padChars[i % padLen];
3900             }
3901 
3902             return new String(padding).concat(str);
3903         }
3904     }
3905 
3906     /**
3907      * 扩展并居中字符串,用空格<code>' '</code>填充两边。
3908      * <pre>
3909      * StringUtil.center(null, *)   = null
3910      * StringUtil.center("", 4)     = "    "
3911      * StringUtil.center("ab", -1)  = "ab"
3912      * StringUtil.center("ab", 4)   = " ab "
3913      * StringUtil.center("abcd", 2) = "abcd"
3914      * StringUtil.center("a", 4)    = " a  "
3915      * </pre>
3916      *
3917      * @param str 要对齐的字符串
3918      * @param size 扩展字符串到指定宽度
3919      *
3920      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3921      */
3922     public static String center(String str, int size) {
3923         return center(str, size, ' ');
3924     }
3925 
3926     /**
3927      * 扩展并居中字符串,用指定字符填充两边。
3928      * <pre>
3929      * StringUtil.center(null, *, *)     = null
3930      * StringUtil.center("", 4, ' ')     = "    "
3931      * StringUtil.center("ab", -1, ' ')  = "ab"
3932      * StringUtil.center("ab", 4, ' ')   = " ab "
3933      * StringUtil.center("abcd", 2, ' ') = "abcd"
3934      * StringUtil.center("a", 4, ' ')    = " a  "
3935      * StringUtil.center("a", 4, 'y')    = "yayy"
3936      * </pre>
3937      *
3938      * @param str 要对齐的字符串
3939      * @param size 扩展字符串到指定宽度
3940      * @param padChar 填充字符
3941      *
3942      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3943      */
3944     public static String center(String str, int size, char padChar) {
3945         if ((str == null) || (size <= 0)) {
3946             return str;
3947         }
3948 
3949         int strLen = str.length();
3950         int pads = size - strLen;
3951 
3952         if (pads <= 0) {
3953             return str;
3954         }
3955 
3956         str = alignRight(str, strLen + (pads / 2), padChar);
3957         str = alignLeft(str, size, padChar);
3958         return str;
3959     }
3960 
3961     /**
3962      * 扩展并居中字符串,用指定字符串填充两边。
3963      * <pre>
3964      * StringUtil.center(null, *, *)     = null
3965      * StringUtil.center("", 4, " ")     = "    "
3966      * StringUtil.center("ab", -1, " ")  = "ab"
3967      * StringUtil.center("ab", 4, " ")   = " ab "
3968      * StringUtil.center("abcd", 2, " ") = "abcd"
3969      * StringUtil.center("a", 4, " ")    = " a  "
3970      * StringUtil.center("a", 4, "yz")   = "yayz"
3971      * StringUtil.center("abc", 7, null) = "  abc  "
3972      * StringUtil.center("abc", 7, "")   = "  abc  "
3973      * </pre>
3974      *
3975      * @param str 要对齐的字符串
3976      * @param size 扩展字符串到指定宽度
3977      * @param padStr 填充字符串
3978      *
3979      * @return 扩展后的字符串,如果字符串为<code>null</code>,则返回<code>null</code>
3980      */
3981     public static String center(String str, int size, String padStr) {
3982         if ((str == null) || (size <= 0)) {
3983             return str;
3984         }
3985 
3986         if ((padStr == null) || (padStr.length() == 0)) {
3987             padStr = " ";
3988         }
3989 
3990         int strLen = str.length();
3991         int pads = size - strLen;
3992 
3993         if (pads <= 0) {
3994             return str;
3995         }
3996 
3997         str = alignRight(str, strLen + (pads / 2), padStr);
3998         str = alignLeft(str, size, padStr);
3999         return str;
4000     }
4001 
4002     /* ============================================================================ */
4003     /*  反转字符串。                                                                */
4004     /* ============================================================================ */
4005 
4006     /**
4007      * 反转字符串中的字符顺序。
4008      *
4009      * <p>
4010      * 如果字符串为<code>null</code>,则返回<code>null</code>。
4011      * </p>
4012      * <pre>
4013      * StringUtil.reverse(null)  = null
4014      * StringUtil.reverse("")    = ""
4015      * StringUtil.reverse("bat") = "tab"
4016      * </pre>
4017      *
4018      * @param str 要反转的字符串
4019      *
4020      * @return 反转后的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
4021      */
4022     public static String reverse(String str) {
4023         if ((str == null) || (str.length() == 0)) {
4024             return str;
4025         }
4026 
4027         return new StringBuffer(str).reverse().toString();
4028     }
4029 
4030     /**
4031      * 反转指定分隔符分隔的各子串的顺序。
4032      *
4033      * <p>
4034      * 如果字符串为<code>null</code>,则返回<code>null</code>。
4035      * </p>
4036      * <pre>
4037      * StringUtil.reverseDelimited(null, *)      = null
4038      * StringUtil.reverseDelimited("", *)        = ""
4039      * StringUtil.reverseDelimited("a.b.c", 'x') = "a.b.c"
4040      * StringUtil.reverseDelimited("a.b.c", '.') = "c.b.a"
4041      * </pre>
4042      *
4043      * @param str 要反转的字符串
4044      * @param separatorChar 分隔符
4045      *
4046      * @return 反转后的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
4047      */
4048     public static String reverseDelimited(String str, char separatorChar) {
4049         if (str == null) {
4050             return null;
4051         }
4052 
4053         String[] strs = split(str, separatorChar);
4054 
4055         ArrayUtil.reverse(strs);
4056 
4057         return join(strs, separatorChar);
4058     }
4059 
4060     /**
4061      * 反转指定分隔符分隔的各子串的顺序。
4062      *
4063      * <p>
4064      * 如果字符串为<code>null</code>,则返回<code>null</code>。
4065      * </p>
4066      * <pre>
4067      * StringUtil.reverseDelimited(null, *, *)          = null
4068      * StringUtil.reverseDelimited("", *, *)            = ""
4069      * StringUtil.reverseDelimited("a.b.c", null, null) = "a.b.c"
4070      * StringUtil.reverseDelimited("a.b.c", "", null)   = "a.b.c"
4071      * StringUtil.reverseDelimited("a.b.c", ".", ",")   = "c,b,a"
4072      * StringUtil.reverseDelimited("a.b.c", ".", null)  = "c b a"
4073      * </pre>
4074      *
4075      * @param str 要反转的字符串
4076      * @param separatorChars 分隔符,如果为<code>null</code>,则默认使用空白字符
4077      * @param separator 用来连接子串的分隔符,如果为<code>null</code>,默认使用空格
4078      *
4079      * @return 反转后的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
4080      */
4081     public static String reverseDelimited(String str, String separatorChars, String separator) {
4082         if (str == null) {
4083             return null;
4084         }
4085 
4086         String[] strs = split(str, separatorChars);
4087 
4088         ArrayUtil.reverse(strs);
4089 
4090         if (separator == null) {
4091             return join(strs, ' ');
4092         }
4093 
4094         return join(strs, separator);
4095     }
4096 
4097     /* ============================================================================ */
4098     /*  取得字符串的缩略。                                                          */
4099     /* ============================================================================ */
4100 
4101     /**
4102      * 将字符串转换成指定长度的缩略,例如: 将"Now is the time for all good men"转换成"Now is the time for..."。
4103      *
4104      * <ul>
4105      * <li>
4106      * 如果<code>str</code>比<code>maxWidth</code>短,直接返回;
4107      * </li>
4108      * <li>
4109      * 否则将它转换成缩略:<code>substring(str, 0, max-3) + "..."</code>;
4110      * </li>
4111      * <li>
4112      * 如果<code>maxWidth</code>小于<code>4</code>抛出<code>IllegalArgumentException</code>;
4113      * </li>
4114      * <li>
4115      * 返回的字符串不可能长于指定的<code>maxWidth</code>。
4116      * </li>
4117      * </ul>
4118      *
4119      * <pre>
4120      * StringUtil.abbreviate(null, *)      = null
4121      * StringUtil.abbreviate("", 4)        = ""
4122      * StringUtil.abbreviate("abcdefg", 6) = "abc..."
4123      * StringUtil.abbreviate("abcdefg", 7) = "abcdefg"
4124      * StringUtil.abbreviate("abcdefg", 8) = "abcdefg"
4125      * StringUtil.abbreviate("abcdefg", 4) = "a..."
4126      * StringUtil.abbreviate("abcdefg", 3) = IllegalArgumentException
4127      * </pre>
4128      *
4129      * @param str 要检查的字符串
4130      * @param maxWidth 最大长度,不小于<code>4</code>,如果小于<code>4</code>,则看作<code>4</code>
4131      *
4132      * @return 字符串缩略,如果原始字符串为<code>null</code>则返回<code>null</code>
4133      */
4134     public static String abbreviate(String str, int maxWidth) {
4135         return abbreviate(str, 0, maxWidth);
4136     }
4137 
4138     /**
4139      * 将字符串转换成指定长度的缩略,例如: 将"Now is the time for all good men"转换成"...is the time for..."。
4140      *
4141      * <p>
4142      * 和<code>abbreviate(String, int)</code>类似,但是增加了一个“左边界”偏移量。
4143      * 注意,“左边界”处的字符未必出现在结果字符串的最左边,但一定出现在结果字符串中。
4144      * </p>
4145      *
4146      * <p>
4147      * 返回的字符串不可能长于指定的<code>maxWidth</code>。
4148      * <pre>
4149      * StringUtil.abbreviate(null, *, *)                = null
4150      * StringUtil.abbreviate("", 0, 4)                  = ""
4151      * StringUtil.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
4152      * StringUtil.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
4153      * StringUtil.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
4154      * StringUtil.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
4155      * StringUtil.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
4156      * StringUtil.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
4157      * StringUtil.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
4158      * StringUtil.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
4159      * StringUtil.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
4160      * StringUtil.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
4161      * StringUtil.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
4162      * </pre>
4163      * </p>
4164      *
4165      * @param str 要检查的字符串
4166      * @param offset 左边界偏移量
4167      * @param maxWidth 最大长度,不小于<code>4</code>,如果小于<code>4</code>,则看作<code>4</code>
4168      *
4169      * @return 字符串缩略,如果原始字符串为<code>null</code>则返回<code>null</code>
4170      */
4171     public static String abbreviate(String str, int offset, int maxWidth) {
4172         if (str == null) {
4173             return null;
4174         }
4175 
4176         // 调整最大宽度
4177         if (maxWidth < 4) {
4178             maxWidth = 4;
4179         }
4180 
4181         if (str.length() <= maxWidth) {
4182             return str;
4183         }
4184 
4185         if (offset > str.length()) {
4186             offset = str.length();
4187         }
4188 
4189         if ((str.length() - offset) < (maxWidth - 3)) {
4190             offset = str.length() - (maxWidth - 3);
4191         }
4192 
4193         if (offset <= 4) {
4194             return str.substring(0, maxWidth - 3) + "...";
4195         }
4196 
4197         // 调整最大宽度
4198         if (maxWidth < 7) {
4199             maxWidth = 7;
4200         }
4201 
4202         if ((offset + (maxWidth - 3)) < str.length()) {
4203             return "..." + abbreviate(str.substring(offset), maxWidth - 3);
4204         }
4205 
4206         return "..." + str.substring(str.length() - (maxWidth - 3));
4207     }
4208 
4209     /* ============================================================================ */
4210     /*  比较两个字符串的异同。                                                      */
4211     /*                                                                              */
4212     /*  查找字符串之间的差异,比较字符串的相似度。                                  */
4213     /* ============================================================================ */
4214 
4215     /**
4216      * 比较两个字符串,取得第二个字符串中,和第一个字符串不同的部分。
4217      * <pre>
4218      * StringUtil.difference("i am a machine", "i am a robot")  = "robot"
4219      * StringUtil.difference(null, null)                        = null
4220      * StringUtil.difference("", "")                            = ""
4221      * StringUtil.difference("", null)                          = ""
4222      * StringUtil.difference("", "abc")                         = "abc"
4223      * StringUtil.difference("abc", "")                         = ""
4224      * StringUtil.difference("abc", "abc")                      = ""
4225      * StringUtil.difference("ab", "abxyz")                     = "xyz"
4226      * StringUtil.difference("abcde", "abxyz")                  = "xyz"
4227      * StringUtil.difference("abcde", "xyz")                    = "xyz"
4228      * </pre>
4229      *
4230      * @param str1 字符串1
4231      * @param str2 字符串2
4232      *
4233      * @return 第二个字符串中,和第一个字符串不同的部分。如果两个字符串相同,则返回空字符串<code>""</code>
4234      */
4235     public static String difference(String str1, String str2) {
4236         if (str1 == null) {
4237             return str2;
4238         }
4239 
4240         if (str2 == null) {
4241             return str1;
4242         }
4243 
4244         int index = indexOfDifference(str1, str2);
4245 
4246         if (index == -1) {
4247             return EMPTY_STRING;
4248         }
4249 
4250         return str2.substring(index);
4251     }
4252 
4253     /**
4254      * 比较两个字符串,取得两字符串开始不同的索引值。
4255      * <pre>
4256      * StringUtil.indexOfDifference("i am a machine", "i am a robot")   = 7
4257      * StringUtil.indexOfDifference(null, null)                         = -1
4258      * StringUtil.indexOfDifference("", null)                           = -1
4259      * StringUtil.indexOfDifference("", "")                             = -1
4260      * StringUtil.indexOfDifference("", "abc")                          = 0
4261      * StringUtil.indexOfDifference("abc", "")                          = 0
4262      * StringUtil.indexOfDifference("abc", "abc")                       = -1
4263      * StringUtil.indexOfDifference("ab", "abxyz")                      = 2
4264      * StringUtil.indexOfDifference("abcde", "abxyz")                   = 2
4265      * StringUtil.indexOfDifference("abcde", "xyz")                     = 0
4266      * </pre>
4267      *
4268      * @param str1 字符串1
4269      * @param str2 字符串2
4270      *
4271      * @return 两字符串开始产生差异的索引值,如果两字符串相同,则返回<code>-1</code>
4272      */
4273     public static int indexOfDifference(String str1, String str2) {
4274         if ((str1 == str2) || (str1 == null) || (str2 == null)) {
4275             return -1;
4276         }
4277 
4278         int i;
4279 
4280         for (i = 0; (i < str1.length()) && (i < str2.length()); ++i) {
4281             if (str1.charAt(i) != str2.charAt(i)) {
4282                 break;
4283             }
4284         }
4285 
4286         if ((i < str2.length()) || (i < str1.length())) {
4287             return i;
4288         }
4289 
4290         return -1;
4291     }
4292 
4293     /**
4294      * 取得两个字符串的相似度,<code>0</code>代表字符串相等,数字越大表示字符串越不像。
4295      *
4296      * <p>
4297      * 这个算法取自<a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a>。
4298      * 它计算的是从字符串1转变到字符串2所需要的删除、插入和替换的步骤数。
4299      * </p>
4300      * <pre>
4301      * StringUtil.getLevenshteinDistance(null, *)             = IllegalArgumentException
4302      * StringUtil.getLevenshteinDistance(*, null)             = IllegalArgumentException
4303      * StringUtil.getLevenshteinDistance("","")               = 0
4304      * StringUtil.getLevenshteinDistance("","a")              = 1
4305      * StringUtil.getLevenshteinDistance("aaapppp", "")       = 7
4306      * StringUtil.getLevenshteinDistance("frog", "fog")       = 1
4307      * StringUtil.getLevenshteinDistance("fly", "ant")        = 3
4308      * StringUtil.getLevenshteinDistance("elephant", "hippo") = 7
4309      * StringUtil.getLevenshteinDistance("hippo", "elephant") = 7
4310      * StringUtil.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
4311      * StringUtil.getLevenshteinDistance("hello", "hallo")    = 1
4312      * </pre>
4313      *
4314      * @param s 第一个字符串,如果是<code>null</code>,则看作空字符串
4315      * @param t 第二个字符串,如果是<code>null</code>,则看作空字符串
4316      *
4317      * @return 相似度值
4318      */
4319     public static int getLevenshteinDistance(String s, String t) {
4320         s = defaultIfNull(s);
4321         t = defaultIfNull(t);
4322 
4323         int[][] d; // matrix
4324         int n; // length of s
4325         int m; // length of t
4326         int i; // iterates through s
4327         int j; // iterates through t
4328         char s_i; // ith character of s
4329         char t_j; // jth character of t
4330         int cost; // cost
4331 
4332         // Step 1
4333         n = s.length();
4334         m = t.length();
4335 
4336         if (n == 0) {
4337             return m;
4338         }
4339 
4340         if (m == 0) {
4341             return n;
4342         }
4343 
4344         d = new int[n + 1][m + 1];
4345 
4346         // Step 2
4347         for (i = 0; i <= n; i++) {
4348             d[i][0] = i;
4349         }
4350 
4351         for (j = 0; j <= m; j++) {
4352             d[0][j] = j;
4353         }
4354 
4355         // Step 3
4356         for (i = 1; i <= n; i++) {
4357             s_i = s.charAt(i - 1);
4358 
4359             // Step 4
4360             for (j = 1; j <= m; j++) {
4361                 t_j = t.charAt(j - 1);
4362 
4363                 // Step 5
4364                 if (s_i == t_j) {
4365                     cost = 0;
4366                 } else {
4367                     cost = 1;
4368                 }
4369 
4370                 // Step 6
4371                 d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
4372             }
4373         }
4374 
4375         // Step 7
4376         return d[n][m];
4377     }
4378 
4379     /**
4380      * 取得最小数。
4381      *
4382      * @param a 整数1
4383      * @param b 整数2
4384      * @param c 整数3
4385      *
4386      * @return 三个数中的最小值
4387      */
4388     private static int min(int a, int b, int c) {
4389         if (b < a) {
4390             a = b;
4391         }
4392 
4393         if (c < a) {
4394             a = c;
4395         }
4396 
4397         return a;
4398     }
4399 }
View Code

 

如果本文对您有帮助,点一下右下角的“推荐”
目录
相关文章
|
Java 索引
Java工具类之String常用方法
1.String包 java.lang 2.构造方法 常量 无参数 带参数String byte[] char[] 3.不可变特性 长度 内容 4.String内存机制 常量"abc" 字符串常量池 构造方法new == equals()区别 "a"+"b"+"c"+"d"; 产生几个对象 5.String与StringBuffer与StringBuilder区别 6.常用的方法 第一梯队(重写) equals hashCode compareTo toString
187 0
|
Java
利用StringUtils工具类进行String为空的判断
  利用工具类进行String类型数据的非空判断,让自己的项目代码变得更加的简洁明了。     判断某字符串是否为空,为空的标准是 str==null 或 str.length()==0     下面是 StringUtils 判断是否为空的示例:     StringUtils.
1200 0
|
6天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
13 0
|
21天前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
24 0
|
27天前
|
Java
Java String split()方法详细教程
Java String split()方法详细教程
19 0
|
1月前
|
安全 Java
Java StringBuffer 和 StringBuilder 类
Java StringBuffer 和 StringBuilder 类
14 0
|
1月前
|
存储 缓存 安全
【Java】Java中String不可变性的底层实现
【Java】Java中String不可变性的底层实现
7 0
|
1月前
|
Java 索引
Java中String方法学习总结_kaic
Java中String方法学习总结_kaic