/**
* Copyright (c) 2015, biezhi 王爵 (biezhi.me@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.blade.kit;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 有关字符串处理的工具类。
*
* @author <a href="mailto:biezhi.me@gmail.com" target="_blank">biezhi</a>
* @since 1.0
*/
public abstract class StringKit {
private static final String FOLDER_SEPARATOR = "/";
private static final String WINDOWS_FOLDER_SEPARATOR = "\\";
private static final String TOP_PATH = "..";
private static final String CURRENT_PATH = ".";
public static String[] NUMBER = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "百", "千", "万", "亿" };
private static final String RANDOM_CHAR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/**
* 检查字符串是否为<code>null</code>或空字符串<code>""</code>。
*
* <pre>
* StringUtil.isEmpty(null) = true
* StringUtil.isEmpty("") = true
* StringUtil.isEmpty(" ") = false
* StringUtil.isEmpty("bob") = false
* StringUtil.isEmpty(" bob ") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果为空, 则返回<code>true</code>
*/
public static boolean isEmpty(String str) {
return (str == null || str.length() == 0) ? true : false;
}
public static boolean isAnyEmpty(String...strings) {
if (strings == null) {
return true;
}
for (String string : strings) {
if (isEmpty(string)) {
return true;
}
}
return false;
}
/**
* 检查字符串是否不是<code>null</code>和空字符串<code>""</code>。
*
* <pre>
* StringUtil.isEmpty(null) = false
* StringUtil.isEmpty("") = false
* StringUtil.isEmpty(" ") = true
* StringUtil.isEmpty("bob") = true
* StringUtil.isEmpty(" bob ") = true
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果不为空, 则返回<code>true</code>
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
* 检查字符串是否是空白:<code>null</code>、空字符串<code>""</code>或只有空白字符。
*
* <pre>
* StringUtil.isBlank(null) = true
* StringUtil.isBlank("") = true
* StringUtil.isBlank(" ") = true
* StringUtil.isBlank("bob") = false
* StringUtil.isBlank(" bob ") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果为空白, 则返回<code>true</code>
*/
public static boolean isBlank(String str) {
int length;
if ((str == null) || ((length = str.length()) == 0)) {
return true;
}
for (int i = 0; i < length; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
}
public static boolean isAllBlank(String...strings) {
if (strings == null) {
return true;
}
for (String string : strings) {
if (isNotBlank(string)) {
return false;
}
}
return true;
}
public static boolean isAnyBlank(String...strings) {
if (strings == null) {
return true;
}
for (String string : strings) {
if (isBlank(string)) {
return true;
}
}
return false;
}
/**
* 检查字符串是否不是空白:<code>null</code>、空字符串<code>""</code>或只有空白字符。
*
* <pre>
* StringUtil.isBlank(null) = false
* StringUtil.isBlank("") = false
* StringUtil.isBlank(" ") = false
* StringUtil.isBlank("bob") = true
* StringUtil.isBlank(" bob ") = true
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果为空白, 则返回<code>true</code>
*/
public static boolean isNotBlank(String str) {
int length;
if ((str == null) || ((length = str.length()) == 0)) {
return false;
}
for (int i = 0; i < length; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
/**
* 如果字符串是<code>null</code>,则返回指定默认字符串,否则返回字符串本身。
*
* <pre>
* StringUtil.defaultIfNull(null, "default") = "default"
* StringUtil.defaultIfNull("", "default") = ""
* StringUtil.defaultIfNull(" ", "default") = " "
* StringUtil.defaultIfNull("bat", "default") = "bat"
* </pre>
*
* @param str 要转换的字符串
*
* @return 字符串本身或指定的默认字符串
*/
public static String defaultIfNull(String str) {
return (str == null) ? "" : str;
}
/**
* 如果字符串是<code>null</code>,则返回指定默认字符串,否则返回字符串本身。
*
* <pre>
* StringUtil.defaultIfNull(null, "default") = "default"
* StringUtil.defaultIfNull("", "default") = ""
* StringUtil.defaultIfNull(" ", "default") = " "
* StringUtil.defaultIfNull("bat", "default") = "bat"
* </pre>
*
* @param str 要转换的字符串
* @param defaultStr 默认字符串
*
* @return 字符串本身或指定的默认字符串
*/
public static String defaultIfNull(String str, String defaultStr) {
return (str == null) ? defaultStr : str;
}
/**
* 除去字符串头尾部的空白,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trim(null) = null
* StringUtil.trim("") = ""
* StringUtil.trim(" ") = ""
* StringUtil.trim("abc") = "abc"
* StringUtil.trim(" abc ") = "abc"
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
public static String trim(String str) {
return trim(str, null, 0);
}
/**
* Trims array of strings. <code>null</code> array elements are ignored.
*/
public static void trimAll(String[] strings) {
if (strings == null) {
return;
}
for (int i = 0; i < strings.length; i++) {
String string = strings[i];
if (string != null) {
strings[i] = trim(string);
}
}
}
/**
* 除去字符串头尾部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* <pre>
* StringUtil.trim(null, *) = null
* StringUtil.trim("", *) = ""
* StringUtil.trim("abc", null) = "abc"
* StringUtil.trim(" abc", null) = "abc"
* StringUtil.trim("abc ", null) = "abc"
* StringUtil.trim(" abc ", null) = "abc"
* StringUtil.trim(" abcyx", "xyz") = " abc"
* </pre>
*
* @param str 要处理的字符串
* @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
*
* @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
public static String trim(String str, String stripChars) {
return trim(str, stripChars, 0);
}
/**
* 除去字符串头部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trimStart(null) = null
* StringUtil.trimStart("") = ""
* StringUtil.trimStart("abc") = "abc"
* StringUtil.trimStart(" abc") = "abc"
* StringUtil.trimStart("abc ") = "abc "
* StringUtil.trimStart(" abc ") = "abc "
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimStart(String str) {
return trim(str, null, -1);
}
/**
* 除去字符串头部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* <pre>
* StringUtil.trimStart(null, *) = null
* StringUtil.trimStart("", *) = ""
* StringUtil.trimStart("abc", "") = "abc"
* StringUtil.trimStart("abc", null) = "abc"
* StringUtil.trimStart(" abc", null) = "abc"
* StringUtil.trimStart("abc ", null) = "abc "
* StringUtil.trimStart(" abc ", null) = "abc "
* StringUtil.trimStart("yxabc ", "xyz") = "abc "
* </pre>
*
* @param str 要处理的字符串
* @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
*
* @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
public static String trimStart(String str, String stripChars) {
return trim(str, stripChars, -1);
}
/**
* 除去字符串尾部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trimEnd(null) = null
* StringUtil.trimEnd("") = ""
* StringUtil.trimEnd("abc") = "abc"
* StringUtil.trimEnd(" abc") = " abc"
* StringUtil.trimEnd("abc ") = "abc"
* StringUtil.trimEnd(" abc ") = " abc"
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimEnd(String str) {
return trim(str, null, 1);
}
/**
* 除去字符串尾部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* <pre>
* StringUtil.trimEnd(null, *) = null
* StringUtil.trimEnd("", *) = ""
* StringUtil.trimEnd("abc", "") = "abc"
* StringUtil.trimEnd("abc", null) = "abc"
* StringUtil.trimEnd(" abc", null) = " abc"
* StringUtil.trimEnd("abc ", null) = "abc"
* StringUtil.trimEnd(" abc ", null) = " abc"
* StringUtil.trimEnd(" abcyx", "xyz") = " abc"
* </pre>
*
* @param str 要处理的字符串
* @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
*
* @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
public static String trimEnd(String str, String stripChars) {
return trim(str, stripChars, 1);
}
/**
* 除去字符串头尾部的空白,如果结果字符串是空字符串<code>""</code>,则返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trimToNull(null) = null
* StringUtil.trimToNull("") = null
* StringUtil.trimToNull(" ") = null
* StringUtil.trimToNull("abc") = "abc"
* StringUtil.trimToNull(" abc ") = "abc"
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimToNull(String str) {
return trimToNull(str, null);
}
/**
* 除去字符串头尾部的空白,如果结果字符串是空字符串<code>""</code>,则返回<code>null</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trim(null, *) = null
* StringUtil.trim("", *) = null
* StringUtil.trim("abc", null) = "abc"
* StringUtil.trim(" abc", null) = "abc"
* StringUtil.trim("abc ", null) = "abc"
* StringUtil.trim(" abc ", null) = "abc"
* StringUtil.trim(" abcyx", "xyz") = " abc"
* </pre>
*
* </p>
*
* @param str 要处理的字符串
* @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimToNull(String str, String stripChars) {
String result = trim(str, stripChars);
if ((result == null) || (result.length() == 0)) {
return null;
}
return result;
}
/**
* 除去字符串头尾部的空白,如果字符串是<code>null</code>,则返回空字符串<code>""</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trimToEmpty(null) = ""
* StringUtil.trimToEmpty("") = ""
* StringUtil.trimToEmpty(" ") = ""
* StringUtil.trimToEmpty("abc") = "abc"
* StringUtil.trimToEmpty(" abc ") = "abc"
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimToEmpty(String str) {
return trimToEmpty(str, null);
}
/**
* 除去字符串头尾部的空白,如果字符串是<code>null</code>,则返回空字符串<code>""</code>。
*
* <p>
* 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
* <pre>
* StringUtil.trim(null, *) = ""
* StringUtil.trim("", *) = ""
* StringUtil.trim("abc", null) = "abc"
* StringUtil.trim(" abc", null) = "abc"
* StringUtil.trim("abc ", null) = "abc"
* StringUtil.trim(" abc ", null) = "abc"
* StringUtil.trim(" abcyx", "xyz") = " abc"
* </pre>
*
* </p>
*
* @param str 要处理的字符串
*
* @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
*/
public static String trimToEmpty(String str, String stripChars) {
String result = trim(str, stripChars);
if (result == null) {
return "";
}
return result;
}
/**
* 除去字符串头尾部的指定字符,如果字符串是<code>null</code>,依然返回<code>null</code>。
*
* <pre>
* StringUtil.trim(null, *) = null
* StringUtil.trim("", *) = ""
* StringUtil.trim("abc", null) = "abc"
* StringUtil.trim(" abc", null) = "abc"
* StringUtil.trim("abc ", null) = "abc"
* StringUtil.trim(" abc ", null) = "abc"
* StringUtil.trim(" abcyx", "xyz") = " abc"
* </pre>
*
* @param str 要处理的字符串
* @param stripChars 要除去的字符,如果为<code>null</code>表示除去空白字符
* @param mode <code>-1</code>表示trimStart,<code>0</code>表示trim全部, <code>1</code>表示trimEnd
*
* @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
*/
private static String trim(String str, String stripChars, int mode) {
if (str == null) {
return null;
}
int length = str.length();
int start = 0;
int end = length;
// 扫描字符串头部
if (mode <= 0) {
if (stripChars == null) {
while ((start < end) && (Character.isWhitespace(str.charAt(start)))) {
start++;
}
} else if (stripChars.length() == 0) {
return str;
} else {
while ((start < end) && (str.startsWith(stripChars) && stripChars.indexOf(str.charAt(start)) != -1)) {
start++;
}
}
}
// 扫描字符串尾部
if (mode >= 0) {
if (stripChars == null) {
while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) {
end--;
}
} else if (stripChars.length() == 0) {
return str;
} else {
while ((start < end) && (str.endsWith(stripChars) && stripChars.indexOf(str.charAt(end - 1)) != -1)) {
end--;
}
}
}
if ((start > 0) || (end < length)) {
return str.substring(start, end);
}
return str;
}
/*
* ========================================================================== ==
*/
/* 比较函数。 */
/* */
/* 以下方法用来比较两个字符串是否相同。 */
/*
* ========================================================================== ==
*/
/**
* 比较两个字符串(大小写敏感)。
*
* <pre>
* StringUtil.equals(null, null) = true
* StringUtil.equals(null, "abc") = false
* StringUtil.equals("abc", null) = false
* StringUtil.equals("abc", "abc") = true
* StringUtil.equals("abc", "ABC") = false
* </pre>
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
*
* @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
*/
public static boolean equals(String str1, String str2) {
if (str1 == null) {
return str2 == null;
}
return str1.equals(str2);
}
/**
* 比较两个字符串(大小写不敏感)。
*
* <pre>
* StringUtil.equalsIgnoreCase(null, null) = true
* StringUtil.equalsIgnoreCase(null, "abc") = false
* StringUtil.equalsIgnoreCase("abc", null) = false
* StringUtil.equalsIgnoreCase("abc", "abc") = true
* StringUtil.equalsIgnoreCase("abc", "ABC") = true
* </pre>
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
*
* @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
*/
public static boolean equalsIgnoreCase(String str1, String str2) {
if (str1 == null) {
return str2 == null;
}
return str1.equalsIgnoreCase(str2);
}
/**
* Compares string with at least one from the provided array. If at least one equal string is found, returns its
* index. Otherwise, <code>-1</code> is returned.
*/
public static int equalsOne(String src, String[] dest) {
if (src == null || dest == null) {
return -1;
}
for (int i = 0; i < dest.length; i++) {
if (src.equals(dest[i])) {
return i;
}
}
return -1;
}
/**
* Compares string with at least one from the provided array, ignoring case. If at least one equal string is found,
* it returns its index. Otherwise, <code>-1</code> is returned.
*/
public static int equalsOneIgnoreCase(String src, String[] dest) {
if (src == null || dest == null) {
return -1;
}
for (int i = 0; i < dest.length; i++) {
if (src.equalsIgnoreCase(dest[i])) {
return i;
}
}
return -1;
}
/**
* Compares two string arrays.
*
* @param as first string array
* @param as1 second string array
*
* @return true if all array elements matches
*/
public static boolean equalsIgnoreCase(String as[], String as1[]) {
if (as == null && as1 == null) {
return true;
}
if (as == null || as1 == null) {
return false;
}
if (as.length != as1.length) {
return false;
}
for (int i = 0; i < as.length; i++) {
if (!as[i].equalsIgnoreCase(as1[i])) {
return false;
}
}
return true;
}
/*
* ========================================================================== ==
*/
/* 字符串类型判定函数。 */
/* */
/* 判定字符串的类型是否为:字母、数字、空白等 */
/*
* ========================================================================== ==
*/
/**
* 判断字符串是否只包含unicode字母。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isAlpha(null) = false
* StringUtil.isAlpha("") = true
* StringUtil.isAlpha(" ") = false
* StringUtil.isAlpha("abc") = true
* StringUtil.isAlpha("ab2c") = false
* StringUtil.isAlpha("ab-c") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode字母组成,则返回<code>true</code>
*/
public static boolean isAlpha(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isLetter(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 判断字符串是否只包含unicode字母和空格<code>' '</code>。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isAlphaSpace(null) = false
* StringUtil.isAlphaSpace("") = true
* StringUtil.isAlphaSpace(" ") = true
* StringUtil.isAlphaSpace("abc") = true
* StringUtil.isAlphaSpace("ab c") = true
* StringUtil.isAlphaSpace("ab2c") = false
* StringUtil.isAlphaSpace("ab-c") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode字母和空格组成,则返回<code>true</code>
*/
public static boolean isAlphaSpace(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isLetter(str.charAt(i)) && (str.charAt(i) != ' ')) {
return false;
}
}
return true;
}
/**
* 判断字符串是否只包含unicode字母和数字。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isAlphanumeric(null) = false
* StringUtil.isAlphanumeric("") = true
* StringUtil.isAlphanumeric(" ") = false
* StringUtil.isAlphanumeric("abc") = true
* StringUtil.isAlphanumeric("ab c") = false
* StringUtil.isAlphanumeric("ab2c") = true
* StringUtil.isAlphanumeric("ab-c") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode字母数字组成,则返回<code>true</code>
*/
public static boolean isAlphanumeric(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isLetterOrDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 判断字符串是否只包含unicode字母数字和空格<code>' '</code>。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isAlphanumericSpace(null) = false
* StringUtil.isAlphanumericSpace("") = true
* StringUtil.isAlphanumericSpace(" ") = true
* StringUtil.isAlphanumericSpace("abc") = true
* StringUtil.isAlphanumericSpace("ab c") = true
* StringUtil.isAlphanumericSpace("ab2c") = true
* StringUtil.isAlphanumericSpace("ab-c") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode字母数字和空格组成,则返回<code>true</code>
*/
public static boolean isAlphanumericSpace(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isLetterOrDigit(str.charAt(i)) && (str.charAt(i) != ' ')) {
return false;
}
}
return true;
}
/**
* 判断字符串是否只包含unicode数字。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isNumeric(null) = false
* StringUtil.isNumeric("") = true
* StringUtil.isNumeric(" ") = false
* StringUtil.isNumeric("123") = true
* StringUtil.isNumeric("12 3") = false
* StringUtil.isNumeric("ab2c") = false
* StringUtil.isNumeric("12-3") = false
* StringUtil.isNumeric("12.3") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode数字组成,则返回<code>true</code>
*/
public static boolean isNumeric(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 判断字符串是否只包含unicode数字和空格<code>' '</code>。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isNumericSpace(null) = false
* StringUtil.isNumericSpace("") = true
* StringUtil.isNumericSpace(" ") = true
* StringUtil.isNumericSpace("123") = true
* StringUtil.isNumericSpace("12 3") = true
* StringUtil.isNumericSpace("ab2c") = false
* StringUtil.isNumericSpace("12-3") = false
* StringUtil.isNumericSpace("12.3") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode数字和空格组成,则返回<code>true</code>
*/
public static boolean isNumericSpace(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isDigit(str.charAt(i)) && (str.charAt(i) != ' ')) {
return false;
}
}
return true;
}
/**
* 判断字符串是否只包含unicode空白。
*
* <p>
* <code>null</code>将返回<code>false</code>,空字符串<code>""</code>将返回 <code>true</code>。
* </p>
*
* <pre>
* StringUtil.isWhitespace(null) = false
* StringUtil.isWhitespace("") = true
* StringUtil.isWhitespace(" ") = true
* StringUtil.isWhitespace("abc") = false
* StringUtil.isWhitespace("ab2c") = false
* StringUtil.isWhitespace("ab-c") = false
* </pre>
*
* @param str 要检查的字符串
*
* @return 如果字符串非<code>null</code>并且全由unicode空白组成,则返回<code>true</code>
*/
public static boolean isWhitespace(String str) {
if (str == null) {
return false;
}
int length = str.length();
for (int i = 0; i < length; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
}
/*
* ========================================================================== ==
*/
/* 大小写转换。 */
/*
* ========================================================================== ==
*/
/**
* 将字符串转换成大写。
*
* <p>
* 如果字符串是<code>null</code>则返回<code>null</code>。
*
* <pre>
* StringUtil.toUpperCasing(null) = null
* StringUtil.toUpperCasing("") = ""
* StringUtil.toUpperCasing("aBc") = "ABC"
* </pre>
*
* </p>
*
* @param str 要转换的字符串
*
* @return 大写字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String toUpperCase(String str) {
if (str == null) {
return null;
}
return str.toUpperCase();
}
/**
* 将字符串转换成小写。
*
* <p>
* 如果字符串是<code>null</code>则返回<code>null</code>。
*
* <pre>
* StringUtil.toLowerCasing(null) = null
* StringUtil.toLowerCasing("") = ""
* StringUtil.toLowerCasing("aBc") = "abc"
* </pre>
*
* </p>
*
* @param str 要转换的字符串
*
* @return 大写字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String toLowerCase(String str) {
if (str == null) {
return null;
}
return str.toLowerCase();
}
/**
* 将字符串的首字符转成大写(<code>Character.toTitleCase</code>),其它字符不变。
*
* <p>
* 如果字符串是<code>null</code>则返回<code>null</code>。
*
* <pre>
* StringUtil.capitalize(null) = null
* StringUtil.capitalize("") = ""
* StringUtil.capitalize("cat") = "Cat"
* StringUtil.capitalize("cAt") = "CAt"
* </pre>
*
* </p>
*
* @param str 要转换的字符串
*
* @return 首字符为大写的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String capitalize(String str) {
int strLen;
if ((str == null) || ((strLen = str.length()) == 0)) {
return str;
}
return new StringBuilder(strLen).append(Character.toTitleCase(str.charAt(0))).append(str.substring(1))
.toString();
}
/**
* 将字符串的首字符转成小写,其它字符不变。
*
* <p>
* 如果字符串是<code>null</code>则返回<code>null</code>。
*
* <pre>
* StringUtil.uncapitalize(null) = null
* StringUtil.uncapitalize("") = ""
* StringUtil.uncapitalize("Cat") = "cat"
* StringUtil.uncapitalize("CAT") = "cAT"
* </pre>
*
* </p>
*
* @param str 要转换的字符串
*
* @return 首字符为小写的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String uncapitalize(String str) {
int strLen;
if ((str == null) || ((strLen = str.length()) == 0)) {
return str;
}
return new StringBuilder(strLen).append(Character.toLowerCase(str.charAt(0))).append(str.substring(1))
.toString();
}
/**
* 与 {@link #uncapitalize(String)}不同,连续大写字符将不做改变
*
* <p>
* 如果字符串是<code>null</code>则返回<code>null</code>。
*
* <pre>
* StringUtil.uncapitalize(null) = null
* StringUtil.uncapitalize("") = ""
* StringUtil.uncapitalize("Cat") = "cat"
* StringUtil.uncapitalize("CAT") = "CAT"
* </pre>
*
* </p>
*
* @param str 要转换的字符串
*
* @return 首字符为小写的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String decapitalize(String str) {
if ((str == null) || str.length() == 0) {
return str;
}
if (str.length() > 1 && Character.isUpperCase(str.charAt(1)) && Character.isUpperCase(str.charAt(0))) {
return str;
}
char chars[] = str.toCharArray();
char c = chars[0];
char modifiedChar = Character.toLowerCase(c);
if (modifiedChar == c) {
return str;
}
chars[0] = modifiedChar;
return new String(chars);
}
/**
* 反转字符串的大小写。
*
* <p>
* 如果字符串是<code>null</code>则返回<code>null</code>。
*
* <pre>
* StringUtil.swapCasing(null) = null
* StringUtil.swapCasing("") = ""
* StringUtil.swapCasing("The dog has a BONE") = "tHE DOG HAS A bone"
* </pre>
*
* </p>
*
* @param str 要转换的字符串
*
* @return 大小写被反转的字符串,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String swapCase(String str) {
int strLen;
if ((str == null) || ((strLen = str.length()) == 0)) {
return str;
}
StringBuilder builder = new StringBuilder(strLen);
char ch = 0;
for (int i = 0; i < strLen; i++) {
ch = str.charAt(i);
if (Character.isUpperCase(ch)) {
ch = Character.toLowerCase(ch);
} else if (Character.isTitleCase(ch)) {
ch = Character.toLowerCase(ch);
} else if (Character.isLowerCase(ch)) {
ch = Character.toUpperCase(ch);
}
builder.append(ch);
}
return builder.toString();
}
public static String fromCamelCase(String str, char separator) {
int strLen;
if ((str == null) || ((strLen = str.length()) == 0)) {
return str;
}
StringBuilder result = new StringBuilder(strLen * 2);
int resultLength = 0;
boolean prevTranslated = false;
for (int i = 0; i < strLen; i++) {
char c = str.charAt(i);
if (i > 0 || c != separator) {// skip first starting separator
if (Character.isUpperCase(c)) {
if (!prevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != separator) {
result.append(separator);
resultLength++;
}
c = Character.toLowerCase(c);
prevTranslated = true;
} else {
prevTranslated = false;
}
result.append(c);
resultLength++;
}
}
return resultLength > 0 ? result.toString() : str;
}
/**
* String2Short
*
* @param s
* @param def
* @return
*/
public static short toShort(String s, short def) {
try {
return (isEmpty(s)) ? def : Short.parseShort(s);
} catch (NumberFormatException e) {
return def;
}
}
/**
* String2Int
*
* @param s
* @param def
* @return
*/
public static int toInt(String s, int def) {
try {
return (isEmpty(s)) ? def : Integer.parseInt(s);
} catch (NumberFormatException e) {
return def;
}
}
/**
* String2Long
*
* @param s
* @param def
* @return
*/
public static long toLong(String s, long def) {
try {
return (isEmpty(s)) ? def : Long.parseLong(s);
} catch (NumberFormatException e) {
return def;
}
}
/**
* String2Float
*
* @param s
* @param def
* @return
*/
public static float toFloat(String s, float def) {
try {
return (isEmpty(s)) ? def : Float.parseFloat(s);
} catch (NumberFormatException e) {
return def;
}
}
/**
* String2Double
*
* @param s
* @param def
* @return
*/
public static double toDouble(String s, double def) {
try {
return (isEmpty(s)) ? def : Double.parseDouble(s);
} catch (NumberFormatException e) {
return def;
}
}
/**
* String2Boolean
*
* @param s
* @param def
* @return
*/
public static boolean toBoolean(String s, boolean def) {
if (isEmpty(s))
return def;
else {
return "true".equalsIgnoreCase(s);
}
}
// ----------- 字符串截取 ----------- //
/**
* 截取 float/double 类型 一位小数
*
* @param f
* @return
*/
public static String getDelFormat(Object f) {
DecimalFormat df = new DecimalFormat("0.0");
return df.format(f);
}
/**
* 截取 float/double 类型 两位小数
*
* @param f
* @return
*/
public static String getDelFormat2(Object f) {
DecimalFormat df = new DecimalFormat("0.00");
return df.format(f);
}
/**
* 截取三位
*
* @param f
* @return
*/
public static String getDelFormat3(Object f) {
DecimalFormat df = new DecimalFormat("0.000");
return df.format(f);
}
/**
* 截取字符串 先是一定的长多 多余...
*
* @param source
* 元字符串
* @param len
* 显示长多
* @return
*/
public static String getStringsubstr(String source, int len) {
if (null == source || "".equals(source)) {
return "";
}
if (source.length() > len) {
return source.substring(0, len) + "...";
}
return source;
}
// ----------- 随机数 ----------- //
/**
* 获得0-max的随机数
*
* @param length
* @return String
*/
public static String getRandomNumber(int length, int max) {
Random random = new Random();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
buffer.append(random.nextInt(max));
}
return buffer.toString();
}
/**
* 获取指定长度的随机数字组成的字符串
*
* @param size
* @return
*/
public static String getRandomNumber(int size) {
String num = "";
for (int i = 0; i < size; i++) {
double a = Math.random() * 9;
a = Math.ceil(a);
int randomNum = new Double(a).intValue();
num += randomNum;
}
return num;
}
/**
* 获取随机字符
*
* @param size
* @return
*/
public static String getRandomChar(int size) {
String sRand = "";
Random random = new Random();// 创建一个随机类
for (int i = 0; i < size; i++) {
String ch = String.valueOf(RANDOM_CHAR.charAt(random.nextInt(RANDOM_CHAR.length())));
sRand += ch;
}
return sRand;
}
// ----------- 验证 ----------- //
/**
* 判断字符串是否为数字和有正确的值
*
* @param str
* @return
*/
public static boolean isNumber(String str) {
// Pattern pattern=Pattern.compile("[0-9]*");
// return pattern.matcher(str).matches();
if (null != str && 0 != str.trim().length() && str.matches("\\d*")) {
return true;
}
return false;
}
public static boolean isBoolean(String value) {
if(null != value){
String val = value.toLowerCase();
if(val.equals("true") || val.equals("false")){
return true;
}
}
return false;
}
/**
* 将阿拉伯数字转为中文数字
*
* @return
*/
public static String toChineseNumber(int number, int depth) {
if (depth < 0)
depth = 0;
if (number <= 0 && depth == 0)
return NUMBER[0];
String chinese = "";
String src = number + "";
if (src.charAt(src.length() - 1) == 'l' || src.charAt(src.length() - 1) == 'L') {
src = src.substring(0, src.length() - 1);
}
if (src.length() > 4)
chinese = toChineseNumber(Integer.parseInt(src.substring(0, src.length() - 4)), depth + 1)
+ toChineseNumber(Integer.parseInt(src.substring(src.length() - 4, src.length())), depth - 1);
else {
char prv = 0;
for (int i = 0; i < src.length(); i++) {
switch (src.charAt(i)) {
case '0':
if (prv != '0')
chinese = chinese + NUMBER[0];
break;
case '1':
chinese = chinese + NUMBER[1];
break;
case '2':
chinese = chinese + NUMBER[2];
break;
case '3':
chinese = chinese + NUMBER[3];
break;
case '4':
chinese = chinese + NUMBER[4];
break;
case '5':
chinese = chinese + NUMBER[5];
break;
case '6':
chinese = chinese + NUMBER[6];
break;
case '7':
chinese = chinese + NUMBER[7];
break;
case '8':
chinese = chinese + NUMBER[8];
break;
case '9':
chinese = chinese + NUMBER[9];
break;
}
prv = src.charAt(i);
switch (src.length() - 1 - i) {
case 1:// 十
if (prv != '0')
chinese = chinese + NUMBER[10];
break;
case 2:// 百
if (prv != '0')
chinese = chinese + NUMBER[11];
break;
case 3:// 千
if (prv != '0')
chinese = chinese + NUMBER[12];
break;
}
}
}
while (chinese.length() > 0 && chinese.lastIndexOf(NUMBER[0]) == chinese.length() - 1)
chinese = chinese.substring(0, chinese.length() - 1);
if (depth == 1)
chinese += NUMBER[13];
if (depth == 2)
chinese += NUMBER[14];
return chinese;
}
/**
* 验证字符串是否含有特殊字符和中文
*
* @param
*
* @return
*/
public static boolean checkIsEnglish(String s) {
String Letters = "(){}[]\",.<>\\/~!@#$%^&*;': ";
int i;
int c;
if (s.charAt(0) == '-') {
return false;
}
if (s.charAt(s.length() - 1) == '-') {
return false;
}
for (i = 0; i < s.length(); i++) {
c = s.charAt(i);
if (Letters.indexOf(c) > -1) {
return false;
}
}
// 验证是否刚好匹配
boolean yesorno = isChineseStr(s);
if (yesorno) {
return false;
}
return true;
}
public static boolean isChineseStr(String pValue) {
for (int i = 0; i < pValue.length(); i++) {
if ((int) pValue.charAt(i) > 256)
return true;
}
return false;
}
/**
* 判断一个字符是Ascill字符还是其它字符(如汉,日,韩文字符)
*
* @param c, 需要判断的字符
* @return boolean, 返回true,Ascill字符
*/
public static boolean isLetter(char c) {
int k = 0x80;
return c / k == 0 ? true : false;
}
// ----------- 格式化 ---------- //
/**
* 格式化数据
*
* @param decimal
* l3453454
* @return 3,453,454
*/
public final static String FormatDecimalString(String decimal) {
double dValue = Double.valueOf(decimal).doubleValue();
DecimalFormat df = new DecimalFormat();
String positivePattern = " ,000";
String negativePattern = " ,000";
if (dValue < 0) {
df.applyPattern(negativePattern);
return df.format(dValue).replace(',', ',');
} else {
df.applyPattern(positivePattern);
return df.format(dValue).replace(',', ',');
}
}
/**
* 格式化数据
*
* @param source
* 3453454
* @return 3,453,454
*/
public static String getNumberFormat(long source) {
NumberFormat usFormat = NumberFormat.getIntegerInstance(Locale.US);
return usFormat.format(source);
}
// ----------- 过滤 ---------- //
/**
* 过滤字符串里的的特殊字符
*
* @param str
* 要过滤的字符串
* @return 过滤后的字符串
*/
public static String stringFilter(String str) {
// 过滤通过页面表单提交的字符
String[][] FilterChars = { { "<", "<" }, { ">", ">" }, { " ", " " }, { "\"", """ }, { "&", "&" },
{ "/", "/" }, { "\\", "\" }, { "'", "\\'" }, { "%", "%" } };
String[] str_arr = stringSpilit(str, "");
for (int i = 0; i < str_arr.length; i++) {
for (int j = 0; j < FilterChars.length; j++) {
if (FilterChars[j][0].equals(str_arr[i]))
str_arr[i] = FilterChars[j][1];
}
}
return (stringConnect(str_arr, "")).trim();
}
// 关健字过滤
public static String stringKeyWorldFilter(String str) {
// 过滤通过页面表单提交的字符
String[][] FilterChars = { { "<", "" }, { ">", "" }, { "\"", "" }, { "&", "" }, { "/", "" }, { "\\", "" }, { "'", "" },
{ "%", "" } };
String[] str_arr = stringSpilit(str, "");
for (int i = 0; i < str_arr.length; i++) {
for (int j = 0; j < FilterChars.length; j++) {
if (FilterChars[j][0].equals(str_arr[i]))
str_arr[i] = FilterChars[j][1];
}
}
return (stringConnect(str_arr, "")).trim();
}
public static String escapeJavaScript(String value) {
return escapeJava(value);
}
public static String unescapeJavaScript(String value) {
return unescapeJava(value);
}
public static String escapeJava(String value) {
if (value == null || value.length() == 0) {
return value;
}
int len = value.length();
StringBuilder buf = null;
for (int i = 0; i < len; i++) {
char ch = value.charAt(i);
String rep;
switch (ch) {
case '\\':
rep = "\\\\";
break;
case '\"':
rep = "\\\"";
break;
case '\'':
rep = "\\\'";
break;
case '\t':
rep = "\\t";
break;
case '\n':
rep = "\\n";
break;
case '\r':
rep = "\\r";
break;
case '\b':
rep = "\\b";
break;
case '\f':
rep = "\\f";
break;
default:
rep = null;
break;
}
if (rep != null) {
if (buf == null) {
buf = new StringBuilder(len * 2);
if (i > 0) {
buf.append(value.substring(0, i));
}
}
buf.append(rep);
} else {
if (buf != null) {
buf.append(ch);
}
}
}
if (buf != null) {
return buf.toString();
}
return value;
}
public static String unescapeJava(String value) {
if (value == null || value.length() == 0) {
return value;
}
StringBuilder buf = null;
int len = value.length();
int len1 = len - 1;
for (int i = 0; i < len; i++) {
char ch = value.charAt(i);
if (ch == '\\' && i < len1) {
int j = i;
i++;
ch = value.charAt(i);
switch (ch) {
case '\\':
ch = '\\';
break;
case '\"':
ch = '\"';
break;
case '\'':
ch = '\'';
break;
case 't':
ch = '\t';
break;
case 'n':
ch = '\n';
break;
case 'r':
ch = '\r';
break;
case 'b':
ch = '\b';
break;
case 'f':
ch = '\f';
break;
case 'u':
ch = (char) Integer.parseInt(value.substring(i + 1, i + 5), 16);
i = i + 4;
break;
default:
j--;
}
if (buf == null) {
buf = new StringBuilder(len);
if (j > 0) {
buf.append(value.substring(0, j));
}
}
buf.append(ch);
} else if (buf != null) {
buf.append(ch);
}
}
if (buf != null) {
return buf.toString();
}
return value;
}
// ----------- 切割合并 ---------- //
/**
* 分割字符串
*
* @param str
* 要分割的字符串
* @param spilit_sign
* 字符串的分割标志
* @return 分割后得到的字符串数组
*/
public static String[] stringSpilit(String str, String spilit_sign) {
String[] spilit_string = str.split(spilit_sign);
if (spilit_string[0].equals("")) {
String[] new_string = new String[spilit_string.length - 1];
for (int i = 1; i < spilit_string.length; i++)
new_string[i - 1] = spilit_string[i];
return new_string;
} else
return spilit_string;
}
/**
* 用特殊的字符连接字符串
*
* @param strings
* 要连接的字符串数组
* @param spilit_sign
* 连接字符
* @return 连接字符串
*/
public static String stringConnect(String[] strings, String spilit_sign) {
StringBuffer str = new StringBuffer("");
for (int i = 0; i < strings.length; i++) {
str.append(strings[i]).append(spilit_sign);
}
return str.toString();
}
/**
* 四舍五入 返回int类型
*
* @param dSource
* 2342.45
* @return 2342
*/
public static int getRound(double dSource) {
int iRound;
// BigDecimal的构造函数参数类型是double
BigDecimal deSource = new BigDecimal(dSource);
// deSource.setScale(0,BigDecimal.ROUND_HALF_UP) 返回值类型 BigDecimal
// intValue() 方法将BigDecimal转化为int
iRound = deSource.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
return iRound;
}
/**
* 提供小数位四舍五入处理。
*
* @param s
* 需要四舍五入的数字
* @return 四舍五入后的结果
*/
public static double round(double s) {
BigDecimal b = new BigDecimal(Double.toString(s));
BigDecimal one = new BigDecimal("1");
return b.divide(one, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供小数位四舍五入处理。
*
* @param s
* 需要四舍五入的数字
* @return 四舍五入后的结果
*/
public static long roundlong(double s) {
BigDecimal b = new BigDecimal(Double.toString(s));
BigDecimal one = new BigDecimal("1");
return b.divide(one, BigDecimal.ROUND_HALF_UP).longValue();
}
/**
* 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
*
* @param s ,需要得到长度的字符串
* @return int, 得到的字符串长度
*/
public static int length(String s) {
if (s == null)
return 0;
char[] c = s.toCharArray();
int len = 0;
for (int i = 0; i < c.length; i++) {
len++;
if (!isLetter(c[i])) {
len++;
}
}
return len;
}
/**
* 功能:获得配置文件中指定编码字符串
*
* @param str
* 解码字符串 charset 指定编码
*
*/
public static String getStrByCharset(String str, String charset) throws UnsupportedEncodingException {
return new String(str.getBytes("ISO-8859-1"), charset);
}
/**
* 提取字符串中的中文字符
*
* @param str
* @return
*/
public static String getChineseByStr(String str) {
StringBuilder resultStr = new StringBuilder("");
Pattern pcn = Pattern.compile("[\u4e00-\u9fa5]");
Matcher m = pcn.matcher(str);
while (m.find()) {
resultStr.append(m.group().toString());
}
return resultStr.toString();
}
// 将两位小数的字符串*100
public static String parseStrInt(String strDouble) {
String fen = "";
int dotIndex = strDouble.lastIndexOf(".");
if (dotIndex >= 0) {// 有小数点字符串
String zs = strDouble.substring(0, dotIndex);
if (!isNumber(zs)) {
return null;
}
fen = zs;
if (strDouble.substring(dotIndex).length() > 1) {// 有小数部分
String xs = strDouble.substring(dotIndex).substring(1);
if (!isNumber(xs)) {
return null;
}
if (xs.length() >= 3) {// 截取后面部分
xs = xs.substring(0, 2);
} else {
if (xs.length() < 2) {
xs = xs + "0";
}
}
fen = zs + xs;
} else {// 没有小数
return null;
}
} else {// 无小数点字符串
fen = strDouble + "00";
}
return fen;
}
/**
* 检查浮点数
*
* @param num
* @param type
* "0+":非负浮点数 "+":正浮点数 "-0":非正浮点数 "-":负浮点数 "":浮点数
* @return
*/
public static boolean checkFloat(String num, String type) {
String eL = "";
if (type.equals("0+"))
eL = "^\\d+(\\.\\d+)?$";// 非负浮点数
else if (type.equals("+"))
eL = "^((\\d+\\.\\d*[1-9]\\d*)|(\\d*[1-9]\\d*\\.\\d+)|(\\d*[1-9]\\d*))$";// 正浮点数
else if (type.equals("-0"))
eL = "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$";// 非正浮点数
else if (type.equals("-"))
eL = "^(-((\\d+\\.\\d*[1-9]\\d*)|(\\d*[1-9]\\d*\\.\\d+)|(\\d*[1-9]\\d*)))$";// 负浮点数
else
eL = "^(-?\\d+)(\\.\\d+)?$";// 浮点数
Pattern p = Pattern.compile(eL);
Matcher m = p.matcher(num);
boolean b = m.matches();
return b;
}
/**
* 替换字符串
*
* @param inString
* @param oldPattern
* @param newPattern
* @return
*/
public static String replace(String inString, String oldPattern, String newPattern) {
if (isEmpty(inString) || isEmpty(oldPattern) || newPattern == null) {
return inString;
}
StringBuilder sb = new StringBuilder();
int pos = 0; // our position in the old string
int index = inString.indexOf(oldPattern);
// the index of an occurrence we've found, or -1
int patLen = oldPattern.length();
while (index >= 0) {
sb.append(inString.substring(pos, index));
sb.append(newPattern);
pos = index + patLen;
index = inString.indexOf(oldPattern, pos);
}
sb.append(inString.substring(pos));
// remember to append any characters to the right of a match
return sb.toString();
}
public static String deleteAny(String inString, String charsToDelete) {
if (isEmpty(inString) || isEmpty(charsToDelete)) {
return inString;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < inString.length(); i++) {
char c = inString.charAt(i);
if (charsToDelete.indexOf(c) == -1) {
sb.append(c);
}
}
return sb.toString();
}
/**
* 获取文件名称
*
* @param path
* @return
*/
public static String getFilename(String path) {
if (path == null) {
return null;
}
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path);
}
public static String applyRelativePath(String path, String relativePath) {
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
if (separatorIndex != -1) {
String newPath = path.substring(0, separatorIndex);
if (!relativePath.startsWith(FOLDER_SEPARATOR)) {
newPath += FOLDER_SEPARATOR;
}
return newPath + relativePath;
} else {
return relativePath;
}
}
public static String cleanPath(String path) {
if (path == null) {
return null;
}
String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);
// Strip prefix from path to analyze, to not treat it as part of the
// first path element. This is necessary to correctly parse paths like
// "file:core/../core/io/Resource.class", where the ".." should just
// strip the first "core" directory while keeping the "file:" prefix.
int prefixIndex = pathToUse.indexOf(":");
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
pathToUse = pathToUse.substring(prefixIndex + 1);
}
if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
prefix = prefix + FOLDER_SEPARATOR;
pathToUse = pathToUse.substring(1);
}
String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);
List<String> pathElements = new LinkedList<String>();
int tops = 0;
for (int i = pathArray.length - 1; i >= 0; i--) {
String element = pathArray[i];
if (CURRENT_PATH.equals(element)) {
// Points to current directory - drop it.
} else if (TOP_PATH.equals(element)) {
// Registering top path found.
tops++;
} else {
if (tops > 0) {
// Merging path element with element corresponding to top path.
tops--;
} else {
// Normal path element found.
pathElements.add(0, element);
}
}
}
// Remaining top paths need to be retained.
for (int i = 0; i < tops; i++) {
pathElements.add(0, TOP_PATH);
}
return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);
}
public static String[] toStringArray(Collection<String> collection) {
if (collection == null) {
return null;
}
return collection.toArray(new String[collection.size()]);
}
public static String[] delimitedListToStringArray(String str, String delimiter) {
return delimitedListToStringArray(str, delimiter, null);
}
public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) {
if (str == null) {
return new String[0];
}
if (delimiter == null) {
return new String[] {str};
}
List<String> result = new ArrayList<String>();
if ("".equals(delimiter)) {
for (int i = 0; i < str.length(); i++) {
result.add(deleteAny(str.substring(i, i + 1), charsToDelete));
}
} else {
int pos = 0;
int delPos;
while ((delPos = str.indexOf(delimiter, pos)) != -1) {
result.add(deleteAny(str.substring(pos, delPos), charsToDelete));
pos = delPos + delimiter.length();
}
if (str.length() > 0 && pos <= str.length()) {
// Add rest of String, but not in case of empty input.
result.add(deleteAny(str.substring(pos), charsToDelete));
}
}
return toStringArray(result);
}
public static String collectionToDelimitedString(Collection<?> coll, String delim, String prefix, String suffix) {
if (CollectionKit.isEmpty(coll)) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator<?> it = coll.iterator();
while (it.hasNext()) {
sb.append(prefix).append(it.next()).append(suffix);
if (it.hasNext()) {
sb.append(delim);
}
}
return sb.toString();
}
public static String collectionToDelimitedString(Collection<?> coll, String delim) {
return collectionToDelimitedString(coll, delim, "", "");
}
public static String firstUpperCase(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
public static String join(final String[] array, final String separator) {
if (array == null) {
return null;
}
final int noOfItems = array.length;
if (noOfItems <= 0) {
return null;
}
if (noOfItems == 1) {
return array[0].toString();
}
final StringBuilder buf = new StringBuilder(noOfItems * 16);
for (int i = 0; i < noOfItems; i++) {
buf.append(separator);
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}
public static String join(final Object[] array, final String separator) {
if (array == null) {
return null;
}
final int noOfItems = array.length;
if (noOfItems <= 0) {
return null;
}
if (noOfItems == 1) {
return array[0].toString();
}
final StringBuilder buf = new StringBuilder(noOfItems * 16);
for (int i = 0; i < noOfItems; i++) {
buf.append(separator);
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}
public static <T> String join(final List<T> array, final String separator) {
if (array == null) {
return null;
}
final int noOfItems = array.size();
if (noOfItems <= 0) {
return null;
}
if (noOfItems == 1) {
return array.get(0).toString();
}
final StringBuilder buf = new StringBuilder(noOfItems * 16);
for (int i = 0; i < noOfItems; i++) {
buf.append(separator);
if (array.get(i) != null) {
buf.append(array.get(i));
}
}
return buf.toString();
}
public static String join(String... parts) {
StringBuilder sb = new StringBuilder(parts.length);
for (String part : parts) {
sb.append(part);
}
return sb.toString();
}
public static String join(Iterable<?> elements, String separator) {
if (elements == null) {
return "";
}
return join(elements.iterator(), separator);
}
public static String join(Iterator<?> elements, String separator) {
if (elements == null) {
return "";
}
StringBuilder sb = new StringBuilder();
while (elements.hasNext()) {
Object o = elements.next();
if (sb.length() > 0 && separator != null) {
sb.append(separator);
}
sb.append(o);
}
return sb.toString();
}
/**
* 随机获取UUID字符串(无中划线)
*
* @return UUID字符串
*/
public static String getUUID() {
String uuid = UUID.randomUUID().toString();
return uuid.substring(0, 8) + uuid.substring(9, 13) + uuid.substring(14, 18) + uuid.substring(19, 23)
+ uuid.substring(24);
}
/**
* 随机获取字符串
*
* @param length 随机字符串长度
* @return 随机字符串
*/
public static String random(int length) {
if (length <= 0) {
return "";
}
char[] randomChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm' };
Random random = new Random();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < length; i++) {
stringBuffer.append(randomChar[Math.abs(random.nextInt()) % randomChar.length]);
}
return stringBuffer.toString();
}
/**
* 根据指定长度 分隔字符串
*
* @param str 需要处理的字符串
* @param length 分隔长度
* @return 字符串集合
*/
public static List<String> split(String str, int length) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < str.length(); i += length) {
int endIndex = i + length;
if (endIndex <= str.length()) {
list.add(str.substring(i, i + length));
} else {
list.add(str.substring(i, str.length() - 1));
}
}
return list;
}
/**
* 将字符串按空白字符分割。
*
* <p>
* 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
*
* <pre>
* StringUtil.split(null) = null
* StringUtil.split("") = []
* StringUtil.split("abc def") = ["abc", "def"]
* StringUtil.split("abc def") = ["abc", "def"]
* StringUtil.split(" abc ") = ["abc"]
* </pre>
*
* </p>
*
* @param str 要分割的字符串
*
* @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String[] split(String str) {
return split(str, null, -1);
}
/**
* 将String to long list
*
* @param source
* @param token
* @return
*/
public static List<Long> parseStringToLongList(String source, String token) {
if (isBlank(source) || isEmpty(token)) {
return null;
}
List<Long> result = new ArrayList<Long>();
String[] units = source.split(token);
for (String unit : units) {
result.add(Long.valueOf(unit));
}
return result;
}
/**
* Splits a string in several parts (tokens) that are separated by delimiter. Delimiter is <b>always</b> surrounded
* by two strings! If there is no content between two delimiters, empty string will be returned for that token.
* Therefore, the length of the returned array will always be: #delimiters + 1.
* <p>
* Method is much, much faster then regexp <code>String.split()</code>, and a bit faster then
* <code>StringTokenizer</code>.
*
* @param src string to split
* @param delimiter split delimiter
*
* @return array of split strings
*/
public static String[] splitNoCompress(String src, String delimiter) {
if (src == null || delimiter == null) {
return null;
}
int maxparts = (src.length() / delimiter.length()) + 2; // one more for
// the last
int[] positions = new int[maxparts];
int dellen = delimiter.length();
int i, j = 0;
int count = 0;
positions[0] = -dellen;
while ((i = src.indexOf(delimiter, j)) != -1) {
count++;
positions[count] = i;
j = i + dellen;
}
count++;
positions[count] = src.length();
String[] result = new String[count];
for (i = 0; i < count; i++) {
result[i] = src.substring(positions[i] + dellen, positions[i + 1]);
}
return result;
}
public static String[] splitc(String src, String d) {
if (isAnyEmpty(src, d)) {
return new String[] { src };
}
char[] delimiters = d.toCharArray();
char[] srcc = src.toCharArray();
int maxparts = srcc.length + 1;
int[] start = new int[maxparts];
int[] end = new int[maxparts];
int count = 0;
start[0] = 0;
int s = 0, e;
if (CharKit.equalsOne(srcc[0], delimiters)) { // string starts with
// delimiter
end[0] = 0;
count++;
s = CharKit.findFirstDiff(srcc, 1, delimiters);
if (s == -1) { // nothing after delimiters
return new String[] { "", "" };
}
start[1] = s; // new start
}
while (true) {
// find new end
e = CharKit.findFirstEqual(srcc, s, delimiters);
if (e == -1) {
end[count] = srcc.length;
break;
}
end[count] = e;
// find new start
count++;
s = CharKit.findFirstDiff(srcc, e, delimiters);
if (s == -1) {
start[count] = end[count] = srcc.length;
break;
}
start[count] = s;
}
count++;
String[] result = new String[count];
for (int i = 0; i < count; i++) {
result[i] = src.substring(start[i], end[i]);
}
return result;
}
public static String[] splitc(String src, char delimiter) {
if (isEmpty(src)) {
return new String[] { "" };
}
char[] srcc = src.toCharArray();
int maxparts = srcc.length + 1;
int[] start = new int[maxparts];
int[] end = new int[maxparts];
int count = 0;
start[0] = 0;
int s = 0, e;
if (srcc[0] == delimiter) { // string starts with delimiter
end[0] = 0;
count++;
s = CharKit.findFirstDiff(srcc, 1, delimiter);
if (s == -1) { // nothing after delimiters
return new String[] { "", "" };
}
start[1] = s; // new start
}
while (true) {
// find new end
e = CharKit.findFirstEqual(srcc, s, delimiter);
if (e == -1) {
end[count] = srcc.length;
break;
}
end[count] = e;
// find new start
count++;
s = CharKit.findFirstDiff(srcc, e, delimiter);
if (s == -1) {
start[count] = end[count] = srcc.length;
break;
}
start[count] = s;
}
count++;
String[] result = new String[count];
for (int i = 0; i < count; i++) {
result[i] = src.substring(start[i], end[i]);
}
return result;
}
public static String[] splitc(String src, char[] delimiters) {
if (isEmpty(src) || null == delimiters || delimiters.length == 0) {
return new String[] { src };
}
char[] srcc = src.toCharArray();
int maxparts = srcc.length + 1;
int[] start = new int[maxparts];
int[] end = new int[maxparts];
int count = 0;
start[0] = 0;
int s = 0, e;
if (CharKit.equalsOne(srcc[0], delimiters) == true) { // string start
// with
// delimiter
end[0] = 0;
count++;
s = CharKit.findFirstDiff(srcc, 1, delimiters);
if (s == -1) { // nothing after delimiters
return new String[] { "", "" };
}
start[1] = s; // new start
}
while (true) {
// find new end
e = CharKit.findFirstEqual(srcc, s, delimiters);
if (e == -1) {
end[count] = srcc.length;
break;
}
end[count] = e;
// find new start
count++;
s = CharKit.findFirstDiff(srcc, e, delimiters);
if (s == -1) {
start[count] = end[count] = srcc.length;
break;
}
start[count] = s;
}
count++;
String[] result = new String[count];
for (int i = 0; i < count; i++) {
result[i] = src.substring(start[i], end[i]);
}
return result;
}
/**
* 将字符串按指定字符分割。
*
* <p>
* 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
*
* <pre>
* StringUtil.split(null, *) = null
* StringUtil.split("", *) = []
* StringUtil.split("a.b.c", '.') = ["a", "b", "c"]
* StringUtil.split("a..b.c", '.') = ["a", "b", "c"]
* StringUtil.split("a:b:c", '.') = ["a:b:c"]
* StringUtil.split("a b c", ' ') = ["a", "b", "c"]
* </pre>
*
* </p>
*
* @param str 要分割的字符串
* @param separatorChar 分隔符
*
* @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String[] split(String str, char separatorChar) {
if (str == null) {
return null;
}
int length = str.length();
if (length == 0) {
return Emptys.EMPTY_STRING_ARRAY;
}
List<String> list = CollectionKit.createArrayList();
int i = 0;
int start = 0;
boolean match = false;
while (i < length) {
if (str.charAt(i) == separatorChar) {
if (match) {
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
match = true;
i++;
}
if (match) {
list.add(str.substring(start, i));
}
return list.toArray(new String[list.size()]);
}
/**
* 将字符串按指定字符分割。
*
* <p>
* 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
*
* <pre>
* StringUtil.split(null, *) = null
* StringUtil.split("", *) = []
* StringUtil.split("abc def", null) = ["abc", "def"]
* StringUtil.split("abc def", " ") = ["abc", "def"]
* StringUtil.split("abc def", " ") = ["abc", "def"]
* StringUtil.split(" ab: cd::ef ", ":") = ["ab", "cd", "ef"]
* StringUtil.split("abc.def", "") = ["abc.def"]
* </pre>
*
* </p>
*
* @param str 要分割的字符串
* @param separatorChars 分隔符
*
* @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String[] split(String str, String separatorChars) {
return split(str, separatorChars, -1);
}
/**
* 将字符串按指定字符分割。
*
* <p>
* 分隔符不会出现在目标数组中,连续的分隔符就被看作一个。如果字符串为<code>null</code>,则返回<code>null</code>。
*
* <pre>
* StringUtil.split(null, *, *) = null
* StringUtil.split("", *, *) = []
* StringUtil.split("ab cd ef", null, 0) = ["ab", "cd", "ef"]
* StringUtil.split(" ab cd ef ", null, 0) = ["ab", "cd", "ef"]
* StringUtil.split("ab:cd::ef", ":", 0) = ["ab", "cd", "ef"]
* StringUtil.split("ab:cd:ef", ":", 2) = ["ab", "cdef"]
* StringUtil.split("abc.def", "", 2) = ["abc.def"]
* </pre>
*
* </p>
*
* @param str 要分割的字符串
* @param separatorChars 分隔符
* @param max 返回的数组的最大个数,如果小于等于0,则表示无限制
*
* @return 分割后的字符串数组,如果原字符串为<code>null</code>,则返回<code>null</code>
*/
public static String[] split(String str, String separatorChars, int max) {
if (str == null) {
return null;
}
int length = str.length();
if (length == 0) {
return Emptys.EMPTY_STRING_ARRAY;
}
List<String> list = CollectionKit.createArrayList();
int sizePlus1 = 1;
int i = 0;
int start = 0;
boolean match = false;
if (separatorChars == null) {
// null表示使用空白作为分隔符
while (i < length) {
if (Character.isWhitespace(str.charAt(i))) {
if (match) {
if (sizePlus1++ == max) {
i = length;
}
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
match = true;
i++;
}
} else if (separatorChars.length() == 1) {
// 优化分隔符长度为1的情形
char sep = separatorChars.charAt(0);
while (i < length) {
if (str.charAt(i) == sep) {
if (match) {
if (sizePlus1++ == max) {
i = length;
}
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
match = true;
i++;
}
} else {
// 一般情形
while (i < length) {
if (separatorChars.indexOf(str.charAt(i)) >= 0) {
if (match) {
if (sizePlus1++ == max) {
i = length;
}
list.add(str.substring(start, i));
match = false;
}
start = ++i;
continue;
}
match = true;
i++;
}
}
if (match) {
list.add(str.substring(start, i));
}
return list.toArray(new String[list.size()]);
}
/**
* Convenience method to return a String array as a CSV String.
* E.g. useful for {@code toString()} implementations.
* @param arr the array to display
* @return the delimited String
*/
public static String arrayToCommaDelimitedString(Object[] arr) {
return arrayToDelimitedString(arr, ",");
}
/**
* Convenience method to return a String array as a delimited (e.g. CSV)
* String. E.g. useful for {@code toString()} implementations.
* @param arr the array to display
* @param delim the delimiter to use (probably a ",")
* @return the delimited String
*/
public static String arrayToDelimitedString(Object[] arr, String delim) {
if (arr == null || arr.length == 0) {
return "";
}
if (arr.length == 1) {
return nullSafeToString(arr[0]);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i > 0) {
sb.append(delim);
}
sb.append(arr[i]);
}
return sb.toString();
}
/**
* Determine if the given objects are equal, returning {@code true}
* if both are {@code null} or {@code false} if only one is
* {@code null}.
* <p>Compares arrays with {@code Arrays.equals}, performing an equality
* check based on the array elements rather than the array reference.
* @param o1 first Object to compare
* @param o2 second Object to compare
* @return whether the given objects are equal
* @see java.util.Arrays#equals
*/
public static boolean nullSafeEquals(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 == null || o2 == null) {
return false;
}
if (o1.equals(o2)) {
return true;
}
if (o1.getClass().isArray() && o2.getClass().isArray()) {
if (o1 instanceof Object[] && o2 instanceof Object[]) {
return Arrays.equals((Object[]) o1, (Object[]) o2);
}
if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
return Arrays.equals((boolean[]) o1, (boolean[]) o2);
}
if (o1 instanceof byte[] && o2 instanceof byte[]) {
return Arrays.equals((byte[]) o1, (byte[]) o2);
}
if (o1 instanceof char[] && o2 instanceof char[]) {
return Arrays.equals((char[]) o1, (char[]) o2);
}
if (o1 instanceof double[] && o2 instanceof double[]) {
return Arrays.equals((double[]) o1, (double[]) o2);
}
if (o1 instanceof float[] && o2 instanceof float[]) {
return Arrays.equals((float[]) o1, (float[]) o2);
}
if (o1 instanceof int[] && o2 instanceof int[]) {
return Arrays.equals((int[]) o1, (int[]) o2);
}
if (o1 instanceof long[] && o2 instanceof long[]) {
return Arrays.equals((long[]) o1, (long[]) o2);
}
if (o1 instanceof short[] && o2 instanceof short[]) {
return Arrays.equals((short[]) o1, (short[]) o2);
}
}
return false;
}
public static String nullSafeToString(Object obj) {
if (obj == null) {
return "null";
}
if (obj instanceof String) {
return (String) obj;
}
if (obj instanceof Object[]) {
return nullSafeToString((Object[]) obj);
}
if (obj instanceof boolean[]) {
return nullSafeToString((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeToString((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeToString((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeToString((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeToString((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeToString((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeToString((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeToString((short[]) obj);
}
String str = obj.toString();
return (str != null ? str : "");
}
/**
* 将字符串List转化为字符串,以分隔符间隔.
*
* @param list 需要处理的List.
* @param separator 分隔符.
* @return 转化后的字符串
*/
public static String toString(List<String> list, String separator) {
StringBuffer stringBuffer = new StringBuffer();
for (String str : list) {
stringBuffer.append(separator + str);
}
stringBuffer.deleteCharAt(0);
return stringBuffer.toString();
}
public static String toString(Object value) {
if (value == null) {
return null;
}
return value.toString();
}
public static String toString(Collection<String> collection) {
return toString(collection, " ");
}
public static String toString(Collection<String> collection, String split) {
if (collection == null || split == null) {
return null;
}
StringBuilder builder = new StringBuilder();
for (Object object : collection) {
builder.append(object).append(split);
}
builder.setLength(builder.length() - split.length());
return builder.toString();
}
/**
* 在字符串左侧填充一定数量的特殊字符
*
* @param o 可被 toString 的对象
* @param width 字符数量
* @param c 字符
* @return 新字符串
*/
public static String alignRight(Object o, int width, char c) {
if (null == o)
return null;
String s = o.toString();
int len = s.length();
if (len >= width)
return s;
return new StringBuilder().append(dup(c, width - len)).append(s).toString();
}
/**
* 在字符串右侧填充一定数量的特殊字符
*
* @param o 可被 toString 的对象
* @param width 字符数量
* @param c 字符
* @return 新字符串
*/
public static String alignLeft(Object o, int width, char c) {
if (null == o)
return null;
String s = o.toString();
int length = s.length();
if (length >= width)
return s;
return new StringBuilder().append(s).append(dup(c, width - length)).toString();
}
/**
* 复制字符
*
* @param c 字符
* @param num 数量
* @return 新字符串
*/
public static String dup(char c, int num) {
if (c == 0 || num < 1)
return "";
StringBuilder sb = new StringBuilder(num);
for (int i = 0; i < num; i++)
sb.append(c);
return sb.toString();
}
}