All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jcohy.lang.StringUtils Maven / Gradle / Ivy

The newest version!
package com.jcohy.lang;


import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.*;
import java.util.regex.Pattern;


/**
 * Copyright  : 2015-2033 Beijing
 * Created by jiac on 2018/3/5 11:21.
 * ClassName  : DateUtils
 * Description  : provider some method resolve the string.
 */
public class StringUtils {

	/**
	 * A trim model for trim(),this model will remove the
	 * space,whitespace between the string start and end.
	 *
	 */
	private static final int TRIM_ALL = 0;

	private static final int TRIM_START = -1;

	private static final int TRIM_END = 1;

	private static final String EMPTY = "";

	private static final String SPACE = " ";

	private static final int INDEX_NOT_FOUND = -1;

	private static final String EMPTY_JSON = "{}";

	private static final String UNDERLINE = "_";

	private static final char C_DELIMITER_START = '{';

	private static final char C_BACKSLASH = '\\';

	private static final char  LF= '\n';

	private static final char  CR = '\r';

	// Empty checks
	//-----------------------------------------------------------------------
	/**
	 * 判断字符串是否为空
	 * empty:代表的是空串("")和null值,不包含空白符;
	 * StringUtils.isEmpty(null)      = true
	 * StringUtils.isEmpty("")        = true
	 * StringUtils.isEmpty(" ")       = false
	 * StringUtils.isEmpty("bob")     = false
	 * StringUtils.isEmpty("  bob  ") = false
	 * @param cs 原始字符串
	 * @return result
	 */
	public static boolean isEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }

	/**
	 * 判断字符串是否不为空
	 * empty:代表的是空串("")和null值,不包含空白符;
	 * StringUtils.isNotEmpty(null)      = false
	 * StringUtils.isNotEmpty("")        = false
	 * StringUtils.isNotEmpty(" ")       = true
	 * StringUtils.isNotEmpty("bob")     = true
	 * StringUtils.isNotEmpty("  bob  ") = true
	 * @param cs 原始字符串
	 * @return result
	 */
	public static boolean isNotEmpty(final CharSequence cs) {
		return !StringUtils.isEmpty(cs);
	}

	/**
	 * 字符串列表是否有空字符串
	 * empty:代表的是空串("")和null值,不包含空白符;
	 * @param css 原始字符串列表
	 * @return result
	 */
	public static boolean hashEmpty(CharSequence...css) {
		if(css == null || css.length == 0 ) {
			return true;
		}
		for(CharSequence str:css) {
			if(isEmpty(str)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 字符串列表是否全部为空
	 * empty:代表的是空串("")和null值,不包含空白符;
	 * @param css 原始字符串列表
	 * @return result
	 */
	public static boolean isAllEmpty(CharSequence...css) {
		if(css == null || css.length == 0 ) {
			return true;
		}
		for(CharSequence str:css) {
			if(isNotEmpty(str)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 字符串是否全部为空白
	 * blank:代表的是空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
	 * @param cs 原始字符串
	 * @return result
	 */
	public static boolean isBlank(final CharSequence cs) {
		int strLen;
		if (cs == null || (strLen = cs.length()) == 0) {
			return true;
		}
		for (int i = 0; i < strLen; i++) {
			if (Character.isWhitespace(cs.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 字符串是否不为空白
	 * blank:代表的是空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
	 * @param cs 原始字符串
	 * @return  result
	 */
	public static boolean isNotBlank(final CharSequence cs) {
		return !StringUtils.isBlank(cs);
	}

	/**
	 * 字符串列表是否存在空白
	 * blank:代表的是空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
	 * @param css 原始字符串列表
	 * @return result
	 */
	public static boolean hashBlank(CharSequence...css) {
		if(css == null || css.length == 0) {
			return true;
		}
		for(CharSequence cs: css) {
			if(isBlank(cs)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 字符串列表是否全部为空白
	 * blank:代表的是空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
	 * @param css 原始字符串列表
	 * @return result
	 */
	public static boolean isAllBlank(CharSequence...css) {
		if(css == null || css.length == 0) {
			return true;
		}
		for(CharSequence cs: css) {
			if(isNotBlank(cs)) {
				return false;
			}
		}
		return true;
	}


	// Trim
	//-----------------------------------------------------------------------
	/**
	 *  除去字符串中的空格符
	 * @param str 原始字符串
	 * @return 清理后的字符串
	 */
	public static String cleanBlank(String str){
		int strLen;
		if(null == str || (strLen = str.length()) == 0){
			return null;
		}
		char c;
		StringBuffer sb = new StringBuffer(strLen);
		for(int i = 0; i < strLen; i++){
			c = str.charAt(i);
			if(!Character.isWhitespace(c)){
				sb.append(c);
			}
		}
		return sb.toString();
	}

	/**
	 * 去除首尾字符串。
	 * @param str 原始字符串
	 * @return result
	 */
	public static String trim(String str){
		return str == null ? null:trim(str,TRIM_ALL);
	}

	/**
	 * 除去字符串所有字符串列表的头尾空格
	 * @param strings 原始字符串列表
	 */
	public static void trimAll(String[] strings){
		if(null == strings){
			return;
		}
		for(String str : strings){
			if(null != str){
				str = trim(str);
			}
		}
	}

	/**
	 * 除去字符串头部字符串
	 * @param str str 原始字符串
	 * @return result
	 */
	public static String trimStart(String str){
		return trim(str,TRIM_START);
	}

	/**
	 * 除去字符串尾部字符串
	 * @param str 原始字符串
	 * @return  result
	 */
	public static String trimEnd(String str){
		return trim(str,TRIM_END);
	}

	/**
	 * 除去字符串头尾部的空白符,如果字符串是null,依然返回null。
	 * @param str 字符串
	 * @param trimModel -1表示trimStart,0表示trim全部, 1表示trimEnd
	 * @return result
	 */
	public static String trim(String str, int trimModel) {
		if(null == str){
			return null;
		}
		int start = 0;
		int end = str.length();
		//查找头部第一个不为空的char的位置
		if(trimModel <= TRIM_ALL){
			while((start < end) && (Character.isWhitespace(str.charAt(start)))){
				start++;
			}
		}
		//查找尾部第一个不为空的char位置
		if(trimModel >= TRIM_ALL){
			while((start < end) && (Character.isWhitespace(str.charAt(end-1)))){
				end --;
			}
		}

		if((start > 0) || (end < str.length())){
			return str.substring(start,end);
		}
		return str;
	}

	/**
	 * 将含有空字符串和空格符的字符串转为Null
	 * StringUtils.trimToNull(null)          = null
	 * StringUtils.trimToNull("")            = null
	 * StringUtils.trimToNull("     ")       = null
	 * StringUtils.trimToNull("abc")         = "abc"
	 * StringUtils.trimToNull("    abc    ") = "abc"
	 * @param str 原始字符串
	 * @return result
	 */
	public static String trimToNull(String str) {
		String ts = trim(str);
		return isEmpty(ts) ? null : ts;
	}

	/**
	 * 将含有空字符串和空格符的字符串转为""
	 * StringUtils.trimToEmpty(null)          = ""
	 * StringUtils.trimToEmpty("")            = ""
	 * StringUtils.trimToEmpty("     ")       = ""
	 * StringUtils.trimToEmpty("abc")         = "abc"
	 * StringUtils.trimToEmpty("    abc    ") = "abc"
	 * @param str 原始字符串
	 * @return result
	 */
	public static String trimToEmpty(String str) {
		return str == null ? "" : str.trim();
	}


	// Case conversion
	//-----------------------------------------------------------------------
	/**
	 * 返回字符串首字母大写,其他小写,驼峰式。
	 * @param str 原始字符串
	 * @return result
	 */
	public static String capitalize(String str){
		int strLen;
		if (str == null || (strLen = str.length()) == 0) {
			return str;
		}

		final int firstCodepoint = str.codePointAt(0);
		final int newCodePoint = Character.toTitleCase(firstCodepoint);
		if (firstCodepoint == newCodePoint) {
			// already capitalized
			return str;
		}

		// cannot be longer than the char array

		final int newCodePoints[] = new int[strLen];
		int outOffset = 0;
		// copy the first codepoint
		newCodePoints[outOffset++] = newCodePoint;
		for (int inOffset = Character.charCount(firstCodepoint); inOffset < strLen; ) {
			final int codepoint = str.codePointAt(inOffset);
			// copy the remaining ones
			newCodePoints[outOffset++] = codepoint;
			inOffset += Character.charCount(codepoint);
		}
		return new String(newCodePoints, 0, outOffset);
	}


	/**
	 *	将字符串变成大写
	 * StringUtils.upperCase(null,Locale.ENGLISH)  = null
	 * StringUtils.upperCase("",Locale.ENGLISH)    = ""
	 * StringUtils.upperCase("aBc",Locale.ENGLISH) = "ABC"
	 * @param str 原始字符串
	 * @return 大写字符串
	 */
	public static String upperCase(String str){

		return upperCase(str,null);
	}

	/**
	 *	将字符串变成小写
	 * StringUtils.upperCase(null,Locale.ENGLISH)  = null
	 * StringUtils.upperCase("",Locale.ENGLISH)    = ""
	 * StringUtils.upperCase("aBc",Locale.ENGLISH) = "ABC"
	 * @param str 原始字符串
	 * @return 小写字符串
	 */
	public static String lowerCase(String str){
		return lowerCase(str,null);
	}

	/**
	 *	将字符串变成大写
	 * StringUtils.upperCase(null,Locale.ENGLISH)  = null
	 * StringUtils.upperCase("",Locale.ENGLISH)    = ""
	 * StringUtils.upperCase("aBc",Locale.ENGLISH) = "ABC"
	 * @param str 原始字符串
	 * @param locale 地区
	 * @return 大写字符串
	 */
	public static String upperCase(String str,Locale locale){
		if (str == null) {
			return null;
		}
		if(locale == null){
			return str.toUpperCase();
		}
		return str.toUpperCase(locale);
	}

	/**
	 *	将字符串变成小写
	 * StringUtils.upperCase(null,Locale.ENGLISH)  = null
	 * StringUtils.upperCase("",Locale.ENGLISH)    = ""
	 * StringUtils.upperCase("aBc",Locale.ENGLISH) = "ABC"
	 * @param str 原始字符串
	 * @param locale 地区
	 * @return 小写字符串
	 */
	public static String lowerCase(String str,Locale locale){
		if (str == null) {
			return null;
		}
		if(locale == null){
			return str.toLowerCase();
		}
		return str.toLowerCase(locale);
	}

	/**
	 * 是否全是大写
	 * @param str 原始字符串
	 * @return result
	 */
	public static boolean isAllUpperCase(String str){
		if (str == null || isEmpty(str)) {
			return false;
		}
		int sz = str.length();
		for (int i = 0; i < sz; i++) {
			if (Character.isUpperCase(str.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 是否全是小写
	 * @param str 原始字符串
	 * @return  result
	 */
	public static boolean isAllLowerCase(String str) {
		if (str == null || isEmpty(str)) {
			return false;
		}
		int sz = str.length();
		for (int i = 0; i < sz; i++) {
			if (Character.isLowerCase(str.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
	 * 例如:HelloWorld = hello_world
	 *
	 * @param camelCaseStr 转换前的驼峰式命名的字符串
	 * @return 转换后下划线大写方式命名的字符串
	 */
	public static String toUnderlineCase(String camelCaseStr) {
		if (camelCaseStr == null) {
			return null;
		}

		final int length = camelCaseStr.length();
		StringBuilder sb = new StringBuilder();
		char c;
		boolean isPreUpperCase = false;
		for (int i = 0; i < length; i++) {
			c = camelCaseStr.charAt(i);
			boolean isNextUpperCase = true;
			if (i < (length - 1)) {
				isNextUpperCase = Character.isUpperCase(camelCaseStr.charAt(i + 1));
			}
			if (Character.isUpperCase(c)) {
				if (!isPreUpperCase || !isNextUpperCase) {
					if (i > 0) {
						sb.append(UNDERLINE);
					}
				}
				isPreUpperCase = true;
			} else {
				isPreUpperCase = false;
			}
			sb.append(Character.toLowerCase(c));
		}
		return sb.toString();
	}

	/**
	 * 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
	 * 例如:hello_world = HelloWorld
	 *
	 * @param name 转换前的下划线大写方式命名的字符串
	 * @return 转换后的驼峰式命名的字符串
	 */
	public static String toCamelCase(String name) {
		if (name == null) {
			return null;
		}
		if (name.contains(UNDERLINE)) {
			name = name.toLowerCase();

			StringBuilder sb = new StringBuilder(name.length());
			boolean upperCase = false;
			for (int i = 0; i < name.length(); i++) {
				char c = name.charAt(i);

				if (c == '_') {
					upperCase = true;
				} else if (upperCase) {
					sb.append(Character.toUpperCase(c));
					upperCase = false;
				} else {
					sb.append(c);
				}
			}
			return sb.toString();
		} else{
			return name;
		}

	}


	// Split
	//-----------------------------------------------------------------------
	/**
	 * 拆分字符串
	 * @param str 原始字符串
	 * @param separator 分隔符
	 * @return result
	 */
	public static List split(String str,char separator){
		return split(str,separator,0);
	}

	/**
	 * 拆分字符串
	 * @param str 原始字符串
	 * @param separator 分隔符
	 * @param limit 分片数
	 * @return result
	 */
	public static String[] splitToArray(String str,char separator,int limit){
		List split = split(str, separator, 0);
		return split.toArray(new String[split.size()]);
	}

	/**
	 * 拆分字符串
	 * @param str 原始字符串
	 * @param separator 分隔符
	 * @return result
	 */
	public static String[] splitToArray(String str,char separator){
		List split = split(str, separator);
		return split.toArray(new String[split.size()]);
	}

	/**
	 * 拆分字符串
	 * StringUtils.split(null, *, *)            = null
	 * StringUtils.split("", *, *)              = []
	 * StringUtils.split("ab cd ef", null, 0)   = ["ab", "cd", "ef"]
	 * StringUtils.split("ab   cd ef", null, 0) = ["ab", "cd", "ef"]
	 * StringUtils.split("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]
	 * StringUtils.split("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]
	 * @param str 原始字符串
	 * @param separator 分隔符
	 * @param limit 分片数
	 * @return result
	 */
	public static List split(String str,char separator,int limit){
		if(str == null){
			return null;
		}
		List list = new ArrayList(limit==0?16:limit);
		if(limit == 1){
			list.add(str);
			return list;
		}

		boolean isEnd = false;
		int strLen = str.length();
		StringBuilder sb = new StringBuilder(strLen);
		for(int i =0;i startIndex) {
				buf.append(separator);
			}
			if (array[i] != null) {
				buf.append(array[i]);
			}
		}
		return buf.toString();
	}


	// Chopping
	//-----------------------------------------------------------------------
	/**
	 * Remove the last character from a String.
	 *
	 * If the String ends in \r\n then remove both
	 * of them.
	 * StringUtils.chop(null)          = null
	 * StringUtils.chop("")            = ""
	 * StringUtils.chop("abc \r")      = "abc "
	 * StringUtils.chop("abc\n")       = "abc"
	 * StringUtils.chop("abc\r\n")     = "abc"
	 * StringUtils.chop("abc")         = "ab"
	 * StringUtils.chop("abc\nabc")    = "abc\nab"
	 * StringUtils.chop("a")           = ""
	 * StringUtils.chop("\r")          = ""
	 * StringUtils.chop("\n")          = ""
	 * StringUtils.chop("\r\n")        = ""
	 * @param str  the String to chop last character from, may be null
	 * @return String without last character
	 */
	public static String chop(final String str) {
		if (str == null) {
			return null;
		}
		final int strLen = str.length();
		if (strLen < 2) {
			return EMPTY;
		}
		final int lastIdx = strLen - 1;
		final String ret = str.substring(0, lastIdx);
		final char last = str.charAt(lastIdx);
		if (last == StringUtils.LF && ret.charAt(lastIdx - 1) == StringUtils.CR) {
			return ret.substring(0, lastIdx - 1);
		}
		return ret;
	}


	// Delete
	//-----------------------------------------------------------------------
	/**
	 *
	 * Deletes all whitespaces from a String as defined by
	 * StringUtils.deleteWhitespace(null)         = null
	 * StringUtils.deleteWhitespace("")           = ""
	 * StringUtils.deleteWhitespace("abc")        = "abc"
	 * StringUtils.deleteWhitespace("   ab  c  ") = "abc"
	 * @param str 原始字符串
	 * @return result
	 */
	public static String deleteWhitespace(final String str) {
		if (isEmpty(str)) {
			return str;
		}
		final int sz = str.length();
		final char[] chs = new char[sz];
		int count = 0;
		for (int i = 0; i < sz; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				chs[count++] = str.charAt(i);
			}
		}
		if (count == sz) {
			return str;
		}
		return new String(chs, 0, count);
	}


	// Remove
	//-----------------------------------------------------------------------
	/**
	 *
	 * @param str 原始字符串
	 * @param remove 被移除的字符串
	 * @return result
	 */
	public static String remove(final String str, final String remove) {
		if (isEmpty(str) || isEmpty(remove)) {
			return str;
		}
		return str.replace(remove,EMPTY);
	}

	/**
	 * Removes each substring of the source String that matches the given regular expression using the DOTALL option.
	 * StringUtils.removePattern(null, *)       = null
	 * StringUtils.removePattern("any", null)   = "any"
	 * StringUtils.removePattern("A<__>\n<__>B", "<.*>")  = "AB"
	 * StringUtils.removePattern("ABCabc123", "[a-z]")    = "ABC123"
	 * @param source the source string
	 * @param regex the regular expression to which this string is to be matched
	 * @return The resulting
	 */
	public static String removePattern(final String source, final String regex) {
		return replacePattern(source, regex, StringUtils.EMPTY);
	}

	/**
	 * 移除匹配正则表达式的字符串
	 * StringUtils.replacePattern(null, *, *)       = null
	 * StringUtils.replacePattern("any", null, *)   = "any"
	 * StringUtils.replacePattern("any", *, null)   = "any"
	 * StringUtils.replacePattern("", "", "zzz")    = "zzz"
	 * StringUtils.replacePattern("", ".*", "zzz")  = "zzz"
	 * StringUtils.replacePattern("", ".+", "zzz")  = ""
	 * StringUtils.replacePattern("<__>\n<__>", "<.*>", "z")       = "z"
	 * StringUtils.replacePattern("ABCabc123", "[a-z]", "_")       = "ABC___123"
	 * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_")  = "ABC_123"
	 * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "")   = "ABC123"
	 * StringUtils.replacePattern("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2")  = "Lorem_ipsum_dolor_sit"
	 * @param source 原始字符串
	 * @param regex 正则表达式
	 * @param replacement 被移除的字符串
	 * @return result
	 */
	public static String replacePattern(final String source, final String regex, final String replacement) {
		if (source == null || regex == null || replacement == null) {
			return source;
		}
		return Pattern.compile(regex, Pattern.DOTALL).matcher(source).replaceAll(replacement);
	}


	// Substring
	//-----------------------------------------------------------------------
	/**
	 * Gets a substring from the specified String avoiding exceptions.
	 * StringUtils.substring(null, *)   = null
	 * StringUtils.substring("", *)     = ""
	 * StringUtils.substring("abc", 0)  = "abc"
	 * StringUtils.substring("abc", 2)  = "c"
	 * StringUtils.substring("abc", 4)  = ""
	 * StringUtils.substring("abc", -2) = "bc"
	 * StringUtils.substring("abc", -4) = "abc"
	 * @param str 原始字符串
	 * @param start 起始位置
	 * @return result
	 */
	public static String substring(final String str, int start) {
		if (str == null) {
			return null;
		}

		// handle negatives, which means last n characters
		if (start < 0) {
			// remember start is negative
			start = str.length() + start;
		}

		if (start < 0) {
			start = 0;
		}
		if (start > str.length()) {
			return EMPTY;
		}

		return str.substring(start);
	}

	/**
	 * Gets a substring from the specified String avoiding exceptions.
	 * StringUtils.substring(null, *, *)    = null
	 * StringUtils.substring("", * ,  *)    = "";
	 * StringUtils.substring("abc", 0, 2)   = "ab"
	 * StringUtils.substring("abc", 2, 0)   = ""
	 * StringUtils.substring("abc", 2, 4)   = "c"
	 * StringUtils.substring("abc", 4, 6)   = ""
	 * StringUtils.substring("abc", 2, 2)   = ""
	 * StringUtils.substring("abc", -2, -1) = "b"
	 * StringUtils.substring("abc", -4, 2)  = "ab"
	 * @param str  原始字符串
	 * @param start  起始位置
	 * @param end  结束位置
	 * @return result
	 */
	public static String substring(final String str, int start, int end) {
		if (str == null) {
			return null;
		}

		// handle negatives
		if (end < 0) {
			end = str.length() + end; // remember end is negative
		}
		if (start < 0) {
			start = str.length() + start; // remember start is negative
		}

		// check length next
		if (end > str.length()) {
			end = str.length();
		}

		// if start is greater than end, return ""
		if (start > end) {
			return EMPTY;
		}

		if (start < 0) {
			start = 0;
		}
		if (end < 0) {
			end = 0;
		}

		return str.substring(start, end);
	}


	// Overlay
	//-----------------------------------------------------------------------
	/**
	 * Overlays part of a String with another String.
	 * StringUtils.overlay(null, *, *, *)            = null
	 * StringUtils.overlay("", "abc", 0, 0)          = "abc"
	 * StringUtils.overlay("abcdef", null, 2, 4)     = "abef"
	 * StringUtils.overlay("abcdef", "", 2, 4)       = "abef"
	 * StringUtils.overlay("abcdef", "", 4, 2)       = "abef"
	 * StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
	 * StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
	 * StringUtils.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
	 * StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
	 * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
	 * StringUtils.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"
	 * @param str  the String to do overlaying in, may be null
	 * @param overlay  the String to overlay, may be null
	 * @param start  the position to start overlaying at
	 * @param end  the position to stop overlaying before
	 * @return overlayed String
	 */
	public static String overlay(final String str, String overlay, int start, int end) {
		if (str == null) {
			return null;
		}
		if (overlay == null) {
			overlay = EMPTY;
		}
		final int len = str.length();
		if (start < 0) {
			start = 0;
		}
		if (start > len) {
			start = len;
		}
		if (end < 0) {
			end = 0;
		}
		if (end > len) {
			end = len;
		}
		if (start > end) {
			final int temp = start;
			start = end;
			end = temp;
		}
		return str.substring(0, start) +
				overlay +
				str.substring(end);
	}


	// Chomping
	//-----------------------------------------------------------------------
	/**
	 * Removes one newline from end of a String if it's there,
	 * otherwise leave it alone.
	 * StringUtils.chomp(null)          = null
	 * StringUtils.chomp("")            = ""
	 * StringUtils.chomp("abc \r")      = "abc "
	 * StringUtils.chomp("abc\n")       = "abc"
	 * StringUtils.chomp("abc\r\n")     = "abc"
	 * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
	 * StringUtils.chomp("abc\n\r")     = "abc\n"
	 * StringUtils.chomp("abc\n\rabc")  = "abc\n\rabc"
	 * StringUtils.chomp("\r")          = ""
	 * StringUtils.chomp("\n")          = ""
	 * StringUtils.chomp("\r\n")        = ""
	 * @param str  the String to chomp a newline from, may be null
	 * @return String without newline, {@code null} if null String input
	 */
	@Deprecated
	public static String chomp(final String str) {
		if (isEmpty(str)) {
			return str;
		}

		if (str.length() == 1) {
			final char ch = str.charAt(0);
			if (ch == StringUtils.CR || ch == StringUtils.LF) {
				return EMPTY;
			}
			return str;
		}

		int lastIdx = str.length() - 1;
		final char last = str.charAt(lastIdx);

		if (last == StringUtils.LF) {
			if (str.charAt(lastIdx - 1) == StringUtils.CR) {
				lastIdx--;
			}
		} else if (last != StringUtils.CR) {
			lastIdx++;
		}
		return str.substring(0, lastIdx);
	}


	// repeat
	//-----------------------------------------------------------------------
	/**
	 * 重复字符串
	 * @param str 原始字符串
	 * @param count 次数
	 * @return result
	 */
	public static String repeat(String str,int count){
		if(isEmpty(str)){
			return null;
		}
		int strLength = str.length();

		long inputLength = strLength*count;
		final int outputLength = (int)inputLength;
		if(outputLength != inputLength){
			throw new IndexOutOfBoundsException("required string is too large!");
		}
		final char[] array = new char[outputLength];
		str.getChars(0,strLength,array,0);
		int n;
		for(n = strLength;n < outputLength-n;n <<= 1){
			System.arraycopy(array,0,array,n,n);
		}
		System.arraycopy(array,0,array,n,outputLength-n);

		return new String(array);
	}

	/**
	 * 重复字符串
	 * @param c 原始字符
	 * @param count 次数
	 * @return result
	 */
	public static String repeat(char c,int count){
		char[] result = new char[count];
		for(int i = 0;i < count ;i++){
			result[i]=c;
		}
		return new String(result);
	}


	// Count matches
	//-----------------------------------------------------------------------
	/**
	 * StringUtils.countMatches(null, *)       = 0
	 * StringUtils.countMatches("", *)         = 0
	 * StringUtils.countMatches("abba", null)  = 0
	 * StringUtils.countMatches("abba", "")    = 0
	 * StringUtils.countMatches("abba", "a")   = 2
	 * StringUtils.countMatches("abba", "ab")  = 1
	 * StringUtils.countMatches("abba", "xxx") = 0
	 * @param str 原始字符串
	 * @param sub 统计的字符串
	 * @return result
	 */
	public static int countMatches(final String str, final String sub) {
		if (isEmpty(str) || isEmpty(sub)) {
			return 0;
		}
		int count = 0;
		int idx = 0;
		while ((idx = str.indexOf(sub, idx)) != INDEX_NOT_FOUND) {
			count++;
			idx += sub.length();
		}
		return count;
	}

	/**
	 * 统计指定内容中包含指定字符的数量
	 *
	 * @param content       内容
	 * @param charForSearch 被统计的字符
	 * @return 包含数量
	 */
	public static int countMatches(String content, char charForSearch) {
		int count = 0;
		if (isEmpty(content)) {
			return 0;
		}
		int contentLength = content.length();
		for (int i = 0; i < contentLength; i++) {
			if (charForSearch == content.charAt(i)) {
				count++;
			}
		}
		return count;
	}

	/**
	 * 统计汉子数目
	 *
	 * @param charSequence 字符串
	 * @return result
	 */
	public int countWords(CharSequence charSequence) {
		if (charSequence == null){
			return 0;
		}
		char[] t1 = charSequence.toString().toCharArray();
		int count = 0;
		for (char aT1 : t1) {
			if (Character.toString(aT1).matches("[\\u4E00-\\u9FA5]+")) {
				count++;
			}
		}
		return count;
	}

	//  check
	//-----------------------------------------------------------------------
	/**
	 * 是否被字符串包围
	 * @param str 原始字符串
	 * @param prefix 前缀
	 * @param suffix 后缀
	 * @return result
	 */
	public static boolean isSurround(CharSequence str , char prefix, char suffix){
		return !isBlank(str) && str.length() >= 2 && str.charAt(0) == prefix && str.charAt(str.length()-1) == suffix;
	}

	/**
	 * 判断全角的字符串,包括全角汉字以及全角标点
	 *
	 * @param charSequence 字符串
	 * @return r	 */
	public int fullAngelWords(CharSequence charSequence) {
		if (charSequence == null){
			return 0;
		}
		char[] t1 = charSequence.toString().toCharArray();
		int count = 0;
		for (char aT1 : t1) {
			if (Character.toString(aT1).matches("[^\\x00-\\xff]")) {
				System.out.println(aT1);
				count++;
			}
		}
		return count;
	}


	// Rotating (circular shift)
	//-----------------------------------------------------------------------
	/**
	 *
	 * StringUtils.rotate(null, *)        = null
	 * StringUtils.rotate("", *)          = ""
	 * StringUtils.rotate("abcdefg", 0)   = "abcdefg"
	 * StringUtils.rotate("abcdefg", 2)   = "fgabcde"
	 * StringUtils.rotate("abcdefg", -2)  = "cdefgab"
	 * StringUtils.rotate("abcdefg", 7)   = "abcdefg"
	 * StringUtils.rotate("abcdefg", -7)  = "abcdefg"
	 * StringUtils.rotate("abcdefg", 9)   = "fgabcde"
	 * StringUtils.rotate("abcdefg", -9)  = "cdefgab"
	 *
	 * @param str  the String to rotate, may be null
	 * @param shift  number of time to shift (positive : right shift, negative : left shift)
	 * @return the rotated String,
	 */
	public static String rotate(final String str, final int shift) {
		if (str == null) {
			return null;
		}

		final int strLen = str.length();
		if (shift == 0 || strLen == 0 || shift % strLen == 0) {
			return str;
		}

		final StringBuilder builder = new StringBuilder(strLen);
		final int offset = - (shift % strLen);
		builder.append(substring(str, offset));
		builder.append(substring(str, 0, offset));
		return builder.toString();
	}


	// Reversing
	//-----------------------------------------------------------------------
	/**
	 * 反转字符串
	 * StringUtils.reverse(null)  = null
	 * StringUtils.reverse("")    = ""
	 * StringUtils.reverse("bat") = "tab"
	 * @param str 原始字符串
	 * @return result
	 */
	public static String reverse(final String str) {
		if (str == null) {
			return null;
		}
		return new StringBuilder(str).reverse().toString();
	}


	// Abbreviating
	//-----------------------------------------------------------------------
	/**
	 * Abbreviates a String using ellipses. This will turn
	 * "Now is the time for all good men" into "Now is the time for..."
	 * StringUtils.abbreviate(null, *)      = null
	 * StringUtils.abbreviate("", 4)        = ""
	 * StringUtils.abbreviate("abcdefg", 6) = "abc..."
	 * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
	 * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
	 * StringUtils.abbreviate("abcdefg", 4) = "a..."
	 * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
	 * @param str  the String to check, may be null
	 * @param maxWidth  maximum length of result String, must be at least 4
	 * @return abbreviated String, {@code null} if null String input
	 */
	public static String abbreviate(final String str, final int maxWidth) {
		final String defaultAbbrevMarker = "...";
		return abbreviate(str, defaultAbbrevMarker, 0, maxWidth);
	}

	/**
	 * Abbreviates a String using ellipses. This will turn
	 * "Now is the time for all good men" into "...is the time for..."
	 * StringUtils.abbreviate(null, *, *)                = null
	 * StringUtils.abbreviate("", 0, 4)                  = ""
	 * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
	 * StringUtils.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
	 * StringUtils.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
	 * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
	 * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
	 * StringUtils.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
	 * StringUtils.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
	 * @param str  the String to check, may be null
	 * @param offset  left edge of source String
	 * @param maxWidth  maximum length of result String, must be at least 4
	 * @return abbreviated String, {@code null} if null String input
	 */
	public static String abbreviate(final String str, final int offset, final int maxWidth) {
		final String defaultAbbrevMarker = "...";
		return abbreviate(str, defaultAbbrevMarker, offset, maxWidth);
	}

	/**
	 * Abbreviates a String using another given String as replacement marker. This will turn
	 * "Now is the time for all good men" into "Now is the time for..." if "..." was defined
	 * as the replacement marker.
	 * StringUtils.abbreviate(null, "...", *)      = null
	 * StringUtils.abbreviate("abcdefg", null, *)  = "abcdefg"
	 * StringUtils.abbreviate("", "...", 4)        = ""
	 * StringUtils.abbreviate("abcdefg", ".", 5)   = "abcd."
	 * StringUtils.abbreviate("abcdefg", ".", 7)   = "abcdefg"
	 * StringUtils.abbreviate("abcdefg", ".", 8)   = "abcdefg"
	 * StringUtils.abbreviate("abcdefg", "..", 4)  = "ab.."
	 * StringUtils.abbreviate("abcdefg", "..", 3)  = "a.."
	 * StringUtils.abbreviate("abcdefg", "..", 2)  = IllegalArgumentException
	 * StringUtils.abbreviate("abcdefg", "...", 3) = IllegalArgumentException
	 * @param str  the String to check, may be null
	 * @param abbrevMarker  the String used as replacement marker
	 * @param maxWidth  maximum length of result String, must be at least {@code abbrevMarker.length + 1}
	 * @return abbreviated String, {@code null} if null String input
	 */
	public static String abbreviate(final String str, final String abbrevMarker, final int maxWidth) {
		return abbreviate(str, abbrevMarker, 0, maxWidth);
	}

	/**
	 * Abbreviates a String using a given replacement marker. This will turn
	 * "Now is the time for all good men" into "...is the time for..." if "..." was defined
	 * as the replacement marker.
	 * StringUtils.abbreviate(null, null, *, *)                 = null
	 * StringUtils.abbreviate("abcdefghijklmno", null, *, *)    = "abcdefghijklmno"
	 * StringUtils.abbreviate("", "...", 0, 4)                  = ""
	 * StringUtils.abbreviate("abcdefghijklmno", "---", -1, 10) = "abcdefg---"
	 * StringUtils.abbreviate("abcdefghijklmno", ",", 0, 10)    = "abcdefghi,"
	 * StringUtils.abbreviate("abcdefghijklmno", ",", 1, 10)    = "abcdefghi,"
	 * StringUtils.abbreviate("abcdefghijklmno", ",", 2, 10)    = "abcdefghi,"
	 * StringUtils.abbreviate("abcdefghijklmno", "::", 4, 10)   = "::efghij::"
	 * StringUtils.abbreviate("abcdefghijklmno", "...", 6, 10)  = "...ghij..."
	 * StringUtils.abbreviate("abcdefghijklmno", "*", 9, 10)    = "*ghijklmno"
	 * StringUtils.abbreviate("abcdefghijklmno", "'", 10, 10)   = "'ghijklmno"
	 * StringUtils.abbreviate("abcdefghijklmno", "!", 12, 10)   = "!ghijklmno"
	 * StringUtils.abbreviate("abcdefghij", "abra", 0, 4)       = IllegalArgumentException
	 * StringUtils.abbreviate("abcdefghij", "...", 5, 6)        = IllegalArgumentException
	 * @param str  the String to check, may be null
	 * @param abbrevMarker  the String used as replacement marker
	 * @param offset  left edge of source String
	 * @param maxWidth  maximum length of result String, must be at least 4
	 * @return abbreviated String, {@code null} if null String input
	 */
	public static String abbreviate(final String str, final String abbrevMarker, int offset, final int maxWidth) {
		if (isEmpty(str) || isEmpty(abbrevMarker)) {
			return str;
		}

		final int abbrevMarkerLength = abbrevMarker.length();
		final int minAbbrevWidth = abbrevMarkerLength + 1;
		final int minAbbrevWidthOffset = abbrevMarkerLength + abbrevMarkerLength + 1;

		if (maxWidth < minAbbrevWidth) {
			throw new IllegalArgumentException(String.format("Minimum abbreviation width is %d", minAbbrevWidth));
		}
		if (str.length() <= maxWidth) {
			return str;
		}
		if (offset > str.length()) {
			offset = str.length();
		}
		if (str.length() - offset < maxWidth - abbrevMarkerLength) {
			offset = str.length() - (maxWidth - abbrevMarkerLength);
		}
		if (offset <= abbrevMarkerLength+1) {
			return str.substring(0, maxWidth - abbrevMarkerLength) + abbrevMarker;
		}
		if (maxWidth < minAbbrevWidthOffset) {
			throw new IllegalArgumentException(String.format("Minimum abbreviation width with offset is %d", minAbbrevWidthOffset));
		}
		if (offset + maxWidth - abbrevMarkerLength < str.length()) {
			return abbrevMarker + abbreviate(str.substring(offset), abbrevMarker, maxWidth - abbrevMarkerLength);
		}
		return abbrevMarker + str.substring(str.length() - (maxWidth - abbrevMarkerLength));
	}


	// Difference
	//-----------------------------------------------------------------------
	/**
	 * Compares two Strings, and returns the portion where they differ.
	 * More precisely, return the remainder of the second String,
	 * starting from where it's different from the first. This means that
	 * the difference between "abc" and "ab" is the empty String and not "c".
	 * StringUtils.difference(null, null) = null
	 * StringUtils.difference("", "") = ""
	 * StringUtils.difference("", "abc") = "abc"
	 * StringUtils.difference("abc", "") = ""
	 * StringUtils.difference("abc", "abc") = ""
	 * StringUtils.difference("abc", "ab") = ""
	 * StringUtils.difference("ab", "abxyz") = "xyz"
	 * StringUtils.difference("abcde", "abxyz") = "xyz"
	 * StringUtils.difference("abcde", "xyz") = "xyz"
	 * @param str1  the first String, may be null
	 * @param str2  the second String, may be null
	 * @return the portion of str2 where it differs from str1; returns the
	 * empty String if they are equal
	 */
	public static String difference(final String str1, final String str2) {
		if (str1 == null) {
			return str2;
		}
		if (str2 == null) {
			return str1;
		}
		final int at = indexOfDifference(str1, str2);
		if (at == INDEX_NOT_FOUND) {
			return EMPTY;
		}
		return str2.substring(at);
	}

	/**
	 * Compares two CharSequences, and returns the index at which the
	 * CharSequences begin to differ.
	 * StringUtils.indexOfDifference(null, null) = -1
	 * StringUtils.indexOfDifference("", "") = -1
	 * StringUtils.indexOfDifference("", "abc") = 0
	 * StringUtils.indexOfDifference("abc", "") = 0
	 * StringUtils.indexOfDifference("abc", "abc") = -1
	 * StringUtils.indexOfDifference("ab", "abxyz") = 2
	 * StringUtils.indexOfDifference("abcde", "abxyz") = 2
	 * StringUtils.indexOfDifference("abcde", "xyz") = 0
	 * @param cs1  the first CharSequence, may be null
	 * @param cs2  the second CharSequence, may be null
	 * @return the index where cs1 and cs2 begin to differ; -1 if they are equal
	 */
	public static int indexOfDifference(final CharSequence cs1, final CharSequence cs2) {
		if (cs1 == cs2) {
			return INDEX_NOT_FOUND;
		}
		if (cs1 == null || cs2 == null) {
			return 0;
		}
		int i;
		for (i = 0; i < cs1.length() && i < cs2.length(); ++i) {
			if (cs1.charAt(i) != cs2.charAt(i)) {
				break;
			}
		}
		if (i < cs2.length() || i < cs1.length()) {
			return i;
		}
		return INDEX_NOT_FOUND;
	}

	/**
	 * Compares all CharSequences in an array and returns the index at which the
	 * CharSequences begin to differ.
	 * StringUtils.indexOfDifference(null) = -1
	 * StringUtils.indexOfDifference(new String[] {}) = -1
	 * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
	 * StringUtils.indexOfDifference(new String[] {null, null}) = -1
	 * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
	 * StringUtils.indexOfDifference(new String[] {"", null}) = 0
	 * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
	 * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
	 * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
	 * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
	 * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
	 * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
	 * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
	 * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
	 * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
	 * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
	 * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
	 * @param css  array of CharSequences, entries may be null
	 * @return the index where the strings begin to differ; -1 if they are all equal
	 */
	public static int indexOfDifference(final CharSequence... css) {
		if (css == null || css.length <= 1) {
			return INDEX_NOT_FOUND;
		}
		boolean anyStringNull = false;
		boolean allStringsNull = true;
		final int arrayLen = css.length;
		int shortestStrLen = Integer.MAX_VALUE;
		int longestStrLen = 0;

		// find the min and max string lengths; this avoids checking to make
		// sure we are not exceeding the length of the string each time through
		// the bottom loop.
		for (final CharSequence cs : css) {
			if (cs == null) {
				anyStringNull = true;
				shortestStrLen = 0;
			} else {
				allStringsNull = false;
				shortestStrLen = Math.min(cs.length(), shortestStrLen);
				longestStrLen = Math.max(cs.length(), longestStrLen);
			}
		}

		// handle lists containing all nulls or all empty strings
		if (allStringsNull || longestStrLen == 0 && !anyStringNull) {
			return INDEX_NOT_FOUND;
		}

		// handle lists containing some nulls or some empty strings
		if (shortestStrLen == 0) {
			return 0;
		}

		// find the position with the first difference across all strings
		int firstDiff = -1;
		for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
			final char comparisonChar = css[0].charAt(stringPos);
			for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
				if (css[arrayPos].charAt(stringPos) != comparisonChar) {
					firstDiff = stringPos;
					break;
				}
			}
			if (firstDiff != -1) {
				break;
			}
		}

		if (firstDiff == -1 && shortestStrLen != longestStrLen) {
			// we compared all of the characters up to the length of the
			// shortest string and didn't find a match, but the string lengths
			// vary, so return the length of the shortest string.
			return shortestStrLen;
		}
		return firstDiff;
	}


	//normalizeSpace
	//-----------------------------------------------------------------------
	/**
	 *
	 * Similar to http://www.w3.org/TR/xpath/#function-normalize
	 * -space
	 * @param str the source String to normalize whitespaces from, may be null
	 * @return the modified string with whitespace normalized, {@code null} if null String input
	 * @since 3.0
	 */
	public static String normalizeSpace(final String str) {
		// LANG-1020: Improved performance significantly by normalizing manually instead of using regex
		// See https://github.com/librucha/commons-lang-normalizespaces-benchmark for performance test
		if (isEmpty(str)) {
			return str;
		}
		final int size = str.length();
		final char[] newChars = new char[size];
		int count = 0;
		int whitespacesCount = 0;
		boolean startWhitespaces = true;
		for (int i = 0; i < size; i++) {
			final char actualChar = str.charAt(i);
			final boolean isWhitespace = Character.isWhitespace(actualChar);
			if (!isWhitespace) {
				startWhitespaces = false;
				newChars[count++] = (actualChar == 160 ? 32 : actualChar);
				whitespacesCount = 0;
			} else {
				if (whitespacesCount == 0 && !startWhitespaces) {
					newChars[count++] = SPACE.charAt(0);
				}
				whitespacesCount++;
			}
		}
		if (startWhitespaces) {
			return EMPTY;
		}
		return new String(newChars, 0, count - (whitespacesCount > 0 ? 1 : 0)).trim();
	}


	//format
	//-----------------------------------------------------------------------
	/**
	 * 有序的格式化文本,用{number}做占位符
	 * indexFormat("this is {1} for {2}","a","b")
	 *
	 * @param template 文本格式
	 * @param args 参数
	 * @return 格式化后的文本
	 */
	public static String indexFormat(String template,Object...args){
		return MessageFormat.format(template,args);
	}

	/**
	 * 格式化文本, {} 表示占位符
* 此方法只是简单将占位符 {} 按照顺序替换为参数
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
* 例:
* 通常使用:format("this is {} for {}", "a", "b") = this is a for b
* 转义{}: format("this is \\{} for {}", "a", "b") = this is \{} for a
* 转义\: format("this is \\\\{} for {}", "a", "b") = this is \a for b
* * @param template 文本模板,被替换的部分用 {} 表示 * @param params 参数值 * @return 格式化后的文本 */ public String format(String template, Object... params) { if (params == null || params.length == 0 || isBlank(template)) { return template; } return placeholder(template, params); } /** * 格式化文本,使用 {varName} 占位
* map = {a: "aValue", b: "bValue"} format("{a} and {b}", map) = aValue and bValue * * @param template 文本模板,被替换的部分用 {key} 表示 * @param map 参数值对 * @return 格式化后的文本 */ public String format(String template, Map map) { if (null == map || map.isEmpty()) { return template; } for (Map.Entry entry : map.entrySet()) { template = template.replace("{" + entry.getKey() + "}", utf8Str(entry.getValue())); } return template; } /** * 格式化字符串
* 此方法只是简单将占位符 {} 按照顺序替换为参数
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
* 例:
* 通常使用:format("this is {} for {}", "a", "b") = this is a for b
* 转义{}: format("this is \\{} for {}", "a", "b") = this is \{} for a
* 转义\: format("this is \\\\{} for {}", "a", "b") = this is \a for b
* * @param needReplaceString 字符串模板 * @param argArray 参数列表 * @return 结果 */ public String placeholder(final String needReplaceString, final Object... argArray) { if (StringUtils.isBlank(needReplaceString) || (argArray == null || argArray.length == 0)) { return needReplaceString; } final int strPatternLength = needReplaceString.length(); //初始化定义好的长度以获得更好的性能 StringBuilder sb = new StringBuilder(strPatternLength + 50); //记录已经处理到的位置 int handledPosition = 0; //占位符所在位置 int delimiterIndex; for (int argIndex = 0; argIndex < argArray.length; argIndex++) { delimiterIndex = needReplaceString.indexOf(EMPTY_JSON, handledPosition); //剩余部分无占位符 if (delimiterIndex == -1) { //不带占位符的模板直接返回 if (handledPosition == 0) { return needReplaceString; } else { //字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 sb.append(needReplaceString, handledPosition, strPatternLength); return sb.toString(); } } else { //转义符 if (delimiterIndex > 0 && needReplaceString.charAt(delimiterIndex - 1) == C_BACKSLASH) { //双转义符 if (delimiterIndex > 1 && needReplaceString.charAt(delimiterIndex - 2) == C_BACKSLASH) { //转义符之前还有一个转义符,占位符依旧有效 sb.append(needReplaceString, handledPosition, delimiterIndex - 1); sb.append(StringUtils.utf8Str(argArray[argIndex])); handledPosition = delimiterIndex + 2; } else { //占位符被转义 argIndex--; sb.append(needReplaceString, handledPosition, delimiterIndex - 1); sb.append(C_DELIMITER_START); handledPosition = delimiterIndex + 1; } } else {//正常占位符 sb.append(needReplaceString, handledPosition, delimiterIndex); sb.append(StringUtils.utf8Str(argArray[argIndex])); handledPosition = delimiterIndex + 2; } } } // append the characters following the last {} pair. //加入最后一个占位符后所有的字符 sb.append(needReplaceString, handledPosition, needReplaceString.length()); return sb.toString(); } //encode //----------------------------------------------------------------------- /** * 以UFT-8格式编码字符串 * @param str 字符串 * @return 编码后的字符串 */ public static byte[] utf8Bytes(String str){ return bytes(str, StandardCharsets.UTF_8); } /** * 以系统默认格式编码字符串 * @param str 字符串 * @return 编码后的字符串 */ public static byte[] defaultBytes(String str){ return bytes(str,Charset.defaultCharset()); } /** * 编码字符串 * @param str 字符串 * @param charset 字符集,如果为空,取决于平台 * @return 编码后的字节码 */ public static byte[] bytes(String str, Charset charset) { if(str == null){ return null; } byte[] bytes = null; if(null == charset){ bytes = str.getBytes(); return bytes; } try { bytes = str.getBytes(charset.name()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return bytes; } /** * 编码字符串 * @param str 字符串 * @param charset 字符集,如果为空,取决于平台 * @return 编码后的字节码 */ public static byte[] bytes(String str, String charset) { return bytes(str,charset == null ? Charset.defaultCharset():Charset.forName(charset)); } //decode //----------------------------------------------------------------------- /** * 解码字节码 * * @param data 字符串 * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 * @return 解码后的字符串 */ public static String str(byte[] data, Charset charset) { if (data == null) { return null; } if (null == charset) { return new String(data); } return new String(data, charset); } /** * 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 * * @param obj 对象 * @return 字符串 */ public static String utf8Str(Object obj) { return str(obj, StandardCharsets.UTF_8); } /** * 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 * * @param obj 对象 * @param charsetName 字符集 * @return 字符串 */ public static String str(Object obj, String charsetName) { return str(obj, Charset.forName(charsetName)); } /** * 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 * * @param obj 对象 * @param charset 字符集 * @return 字符串 */ public static String str(Object obj, Charset charset) { if (null == obj) { return null; } if (obj instanceof String) { return (String) obj; } else if (obj instanceof byte[]) { return str((byte[]) obj, charset); } else if (obj instanceof Byte[]) { return str((Byte[]) obj, charset); } else if (obj instanceof ByteBuffer) { return str((ByteBuffer) obj, charset); } else if (obj.getClass().isArray()) { try { return Arrays.deepToString((Object[]) obj); } catch (Exception e) { final String className = obj.getClass().getComponentType().getName(); switch (className) { case "long": return Arrays.toString((long[]) obj); case "int": return Arrays.toString((int[]) obj); case "short": return Arrays.toString((short[]) obj); case "char": return Arrays.toString((char[]) obj); case "byte": return Arrays.toString((byte[]) obj); case "boolean": return Arrays.toString((boolean[]) obj); case "float": return Arrays.toString((float[]) obj); case "double": return Arrays.toString((double[]) obj); default: throw new RuntimeException(e); } } } return obj.toString(); } /** * 将byte数组转为字符串 * * @param bytes byte数组 * @param charset 字符集 * @return 字符串 */ public static String str(byte[] bytes, String charset) { return str(bytes, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset)); } /** * 将Byte数组转为字符串 * * @param bytes byte数组 * @param charset 字符集 * @return 字符串 */ public static String str(Byte[] bytes, String charset) { return str(bytes, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset)); } /** * 解码字节码 * * @param data 字符串 * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 * @return 解码后的字符串 */ public static String str(Byte[] data, Charset charset) { if (data == null) { return null; } byte[] bytes = new byte[data.length]; Byte dataByte; for (int i = 0; i < data.length; i++) { dataByte = data[i]; bytes[i] = (null == dataByte) ? -1 : dataByte; } return str(bytes, charset); } /** * 将编码的byteBuffer数据转换为字符串 * * @param data 数据 * @param charset 字符集,如果为空使用当前系统字符集 * @return 字符串 */ public static String str(ByteBuffer data, String charset) { if (data == null) { return null; } return str(data, Charset.forName(charset)); } /** * 将编码的byteBuffer数据转换为字符串 * * @param data 数据 * @param charset 字符集,如果为空使用当前系统字符集 * @return 字符串 */ public static String str(ByteBuffer data, Charset charset) { if (null == charset) { charset = Charset.defaultCharset(); } return charset.decode(data).toString(); } /** * 字符串转换为byteBuffer * * @param str 字符串 * @param charset 编码 * @return byteBuffer */ public static ByteBuffer byteBuffer(String str, String charset) { return ByteBuffer.wrap(bytes(str, charset)); } //wrap //----------------------------------------------------------------------- /** * 包装指定字符串 * * @param str 被包装的字符串 * @param prefix 前缀 * @param suffix 后缀 * @return 包装后的字符串 */ public String wrap(String str, String prefix, String suffix) { return format("{}{}{}", prefix, str, suffix); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy