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

org.voovan.tools.TString Maven / Gradle / Ivy

package org.voovan.tools;

import org.voovan.Global;
import org.voovan.tools.json.JSON;
import org.voovan.tools.log.Logger;
import org.voovan.tools.reflect.TReflect;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String 工具类
 *
 * @author helyho
 * 

* Voovan Framework80797d4b533dc83bb73457eb5194d13a45779258eaf3a2c07f041a98b329f79d. * WebSite: https://github.com/helyho/Voovan * Licence: Apache v2 License */ public class TString { private static Map regexPattern = new ConcurrentHashMap(); /** * 单词首字母大写 * * @param source 字符串 * @return 首字母大写后的字符串 */ public static String upperCaseHead(String source) { if (source == null) { return null; } char[] charArray = source.toCharArray(); charArray[0] = Character.toUpperCase(charArray[0]); return new String(charArray); } /** * 移除字符串前缀 * * @param source 目标字符串 * @return 移除第一个字节后的字符串 */ public static String removePrefix(String source) { if (source == null) { return null; } return source.substring(1, source.length()); } /** * 移除字符串后缀 * * @param source 目标字符串 * @return 移除最后一个字节后的字符串 */ public static String removeSuffix(String source) { if (source == null) { return null; } if (source.isEmpty()) { return source; } return source.substring(0, source.length() - 1); } /** * 左补齐 * * @param source 目标字符串 * @param len 补齐后字符串的长度 * @param c 用于补齐的字符串 * @return 补齐后的字符串 */ public static String leftPad(String source, int len, char c) { if (source == null) { source = ""; } StringBuffer sb = new StringBuffer(); for (int i = 0; i < len - source.length(); i++) { sb.append(c); } return sb.append(source).toString(); } /** * 右补齐 * * @param source 目标字符串 * @param len 补齐后字符串的长度 * @param c 用于补齐的字符串 * @return 补齐后的字符串 */ public static String rightPad(String source, int len, char c) { if (source == null) { source = ""; } StringBuffer sb = new StringBuffer(); sb.append(source); for (int i = 0; i < len - source.length(); i++) { sb.append(c); } return sb.toString(); } /** * 判断是否是指定进制的数字字符串 * * @param numberString 目标字符串 * @param radix 进制 * @return 是否是指定进制的数字字符串 */ public static boolean isNumber(String numberString, int radix) { if (numberString == null) { return false; } try { Integer.parseInt(numberString, radix); return true; } catch (Exception e) { return false; } } /** * 判断是否是整形数 * * @param integerString 数字字符串 * @return 是否是整形数 */ public static boolean isInteger(String integerString) { if (integerString != null && regexMatch(integerString, "^-?[0-9]\\d*$") > 0) { return true; } else { return false; } } /** * 判断是否是浮点数 * * @param decimalString 浮点数字符串 * @return 是否是浮点数 */ public static boolean isDecimal(String decimalString) { if (decimalString != null && regexMatch(decimalString, "^-?\\d+\\.\\d+$") > 0) { return true; } else { return false; } } /** * 判断是否是布尔值 * * @param booleanString 布尔值字符串 * @return 是否是布尔值 */ public static boolean isBoolean(String booleanString) { if ("true".equalsIgnoreCase(booleanString) || "false".equalsIgnoreCase(booleanString)) { return true; } else { return false; } } private static Pattern getCachedPattern(String regex, Integer flags) { Pattern pattern = null; flags = flags == null ? 0 : flags; pattern = regexPattern.get(regex.hashCode()); if (pattern==null) { pattern = Pattern.compile(regex, flags); regexPattern.put(regex.hashCode(), pattern); } return pattern; } /** * 执行正则运算 * * @param source 目标字符串 * @param regex 正则表达式 * @return Matcher对象 */ public static Matcher doRegex(String source, String regex) { return doRegex(source, regex, 0); } /** * 执行正则运算 * * @param source 目标字符串 * @param regex 正则表达式 * @param flags 正则匹配标记 CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS, COMMENTS * @return Matcher对象 */ public static Matcher doRegex(String source, String regex, Integer flags) { if (source == null) { return null; } Pattern pattern = getCachedPattern(regex, flags); Matcher matcher = pattern.matcher(source); if (matcher.find()) { return matcher; } else { return null; } } /** * 正则表达式查找 * 匹配的被提取出来做数组 * * @param source 目标字符串 * @param regex 正则表达式 * @return 匹配的字符串数组 */ public static String[] searchByRegex(String source, String regex) { return searchByRegex(source, regex, 0); } /** * 正则表达式查找 * 匹配的被提取出来做数组 * * @param source 目标字符串 * @param regex 正则表达式 * @param flags 正则匹配标记 CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS, COMMENTS * @return 匹配的字符串数组 */ public static String[] searchByRegex(String source, String regex, Integer flags) { if (source == null) { return null; } ArrayList result = new ArrayList(); Matcher matcher = doRegex(source, regex, flags); if (matcher != null) { do { result.add(matcher.group()); } while (matcher.find()); } return result.toArray(new String[0]); } /** * 正则匹配 * * @param source 目标字符串 * @param regex 正则表达式 * @return 正则搜索后得到的匹配数量 */ public static int regexMatch(String source, String regex) { return regexMatch(source, regex, 0); } /** * 正则匹配 * * @param source 目标字符串 * @param regex 正则表达式 * @param flags 正则匹配标记 CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS, COMMENTS * @return 正则搜索后得到的匹配数量 */ public static int regexMatch(String source, String regex, Integer flags) { Matcher matcher = doRegex(source, regex, flags); int count = 0; if (matcher != null) { do { count++; } while (matcher.find()); } return count; } /** * 快速字符串替换算法 * 默认正在 flag = 0, quoteReplacement = true * @param source 源字符串 * @param regex 正则字符串 * @param replacement 替换字符串 * @return 替换后的字符串 */ public static String fastReplaceAll(String source, String regex, String replacement) { return fastReplaceAll(source, regex, replacement, 0, true); } /** * 快速字符串替换算法 * 默认正在 flag = 0 * @param source 源字符串 * @param regex 正则字符串 * @param replacement 替换字符串 * @param quoteReplacement 对 replacement 是否进行转移 * @return 替换后的字符串 */ public static String fastReplaceAll(String source, String regex, String replacement, boolean quoteReplacement) { return fastReplaceAll(source, regex, replacement, 0, quoteReplacement); } /** * 快速字符串替换算法 * * @param source 源字符串 * @param regex 正则字符串 * @param replacement 替换字符串 * @param flags 正则匹配标记 CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS, COMMENTS * @param quoteReplacement 对 replacement 是否进行转移 * @return 替换后的字符串 */ public static String fastReplaceAll(String source, String regex, String replacement, Integer flags, boolean quoteReplacement) { Pattern pattern = getCachedPattern(regex, flags); if(quoteReplacement) { replacement = Matcher.quoteReplacement(replacement); } return pattern.matcher(source).replaceAll(replacement); } /** * 快速字符串替换算法 * 默认正在 flag = 0, quoteReplacement = true * @param source 源字符串 * @param regex 正则字符串 * @param replacement 替换字符串 * @return 替换后的字符串 */ public static String fastReplaceFirst(String source, String regex, String replacement) { return fastReplaceFirst(source, regex, replacement, 0, true); } /** * 快速字符串替换算法 * 默认正在 flag = 0 * @param source 源字符串 * @param regex 正则字符串 * @param replacement 替换字符串 * @param quoteReplacement 对 replacement 是否进行转移 * @return 替换后的字符串 */ public static String fastReplaceFirst(String source, String regex, String replacement, boolean quoteReplacement) { return fastReplaceFirst(source, regex, replacement, 0, quoteReplacement); } /** * 快速字符串替换算法 * * @param source 源字符串 * @param regex 正则字符串 * @param replacement 替换字符串 * @param flags 正则匹配标记 CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS, COMMENTS * @param quoteReplacement 对 replacement 是否进行转移 * @return 替换后的字符串 */ public static String fastReplaceFirst(String source, String regex, String replacement, Integer flags, boolean quoteReplacement) { Pattern pattern = getCachedPattern(regex, flags); if(quoteReplacement) { replacement = Matcher.quoteReplacement(replacement); } return pattern.matcher(source).replaceFirst(replacement); } /** * 判断字符串空指针或者内容为空 * * @param source 字符串 * @return 是否是空指针或者内容为空 */ public static boolean isNullOrEmpty(String source) { if (source == null || source.isEmpty()) { return true; } else { return false; } } /** * 按照标识符 Map 进行替换 * * @param source 源字符串,标识符使用"{标识}"进行包裹,这些标识符将会被替换 * @param tokens 标识符 Map, 包含匹配字符串和替换字符串 * @return 替换后的字符串 */ public static String tokenReplace(String source, Map tokens) { if (source == null) { return null; } for (Entry entry : tokens.entrySet()) { String value = entry.getValue() == null ? "null" : entry.getValue().toString(); source = oneTokenReplace(source, entry.getKey(), value); } return source; } /** * 按照标识符 Map 进行替换 * * @param source 源字符串,标识符使用"{标识}"进行包裹,这些标识符将会被替换 * @param list 数据 List 集合 * @return 替换后的字符串 */ public static String tokenReplace(String source, List list) { Map tokens = TObject.arrayToMap(list.toArray()); return tokenReplace(source, tokens); } /** * 按位置格式化字符串 * TString.tokenReplace("aaaa{1}bbbb{2}cccc{3}", "1","2","3") * 或者TString.tokenReplace("aaaa{}bbbb{}cccc{}", "1","2","3") * 输出aaaa1bbbb2cccc3 * * @param source 字符串 * @param args 多个参数 * @return 格式化后的字符串 */ public static String tokenReplace(String source, Object... args) { if (source == null) { return null; } source = tokenReplace(source, TObject.arrayToMap(args)); return source; } public static String TOKEN_PREFIX = "{"; public static String TOKEN_SUFFIX = "}"; public static String TOKEN_EMPTY = TOKEN_PREFIX + TOKEN_SUFFIX; public static String TOKEN_PREFIX_REGEX = "\\" + TOKEN_PREFIX; public static String TOKEN_SUFFIX_REGEX = "\\" + TOKEN_SUFFIX; public static String TOKEN_EMPTY_REGEX = TOKEN_PREFIX_REGEX + TOKEN_SUFFIX_REGEX; /** * 按照标识符进行替换 * tokenName 为 null 则使用 {} 进行替换 * 如果为 tokenName 为数字 可以不在标识中填写数字标识,会自动按照标识的先后顺序进行替换 * * @param source 源字符串,标识符使用"{标识}"进行包裹 * @param tokenName 标识符 * @param tokenValue 标志符值 * @return 替换后的字符串 */ public static String oneTokenReplace(String source, String tokenName, String tokenValue) { if (source == null) { return null; } if (source.contains(TOKEN_PREFIX + tokenName + TOKEN_SUFFIX)) { return fastReplaceAll(source, TOKEN_PREFIX_REGEX + tokenName + TOKEN_SUFFIX_REGEX, tokenValue == null ? "null" : Matcher.quoteReplacement(tokenValue)); } else if ((tokenName == null || TString.isInteger(tokenName)) && source.contains(TOKEN_EMPTY)) { return TString.fastReplaceFirst(source, TOKEN_EMPTY_REGEX, tokenValue); } else { return source; } } /** * 替换第一个标志字符串 * * @param source 字符串 * @param mark 标志字符 * @param replacement 替换字符 * @return 替换后的结果 */ public static String replaceFirst(String source, String mark, String replacement) { if (source == null) { return null; } int head = source.indexOf(mark); int tail = head + mark.length(); replacement = TObject.nullDefault(replacement, ""); source = source.substring(0, head) + replacement + source.substring(tail, source.length()); return source; } /** * 替换最后一个标志字符串 * * @param source 字符串 * @param mark 标志字符 * @param replacement 替换字符 * @return 替换后的结果 */ public static String replaceLast(String source, String mark, String replacement) { if (source == null) { return null; } int head = source.lastIndexOf(mark); int tail = head + mark.length(); replacement = TObject.nullDefault(replacement, ""); source = source.substring(0, head) + replacement + source.substring(tail, source.length()); return source; } /** * 缩进字符串 * * @param source 待缩进的字符串 * @param indentCount 缩进数(空格的数目) * @return 缩进后的字符串 */ public static String indent(String source, int indentCount) { if (indentCount > 0 && source != null) { StringBuilder indent = new StringBuilder(); for (int i = 0; i < indentCount; i++) { indent.append(" "); } source = indent.toString() + source; source = org.voovan.tools.TString.fastReplaceAll(source, "\n", "\n" + indent.toString()); } return source; } /** * 翻转字符串 输入1234 输出4321 * * @param source 字符串 * @return 翻转后的字符串 */ public static String reverse(String source) { if (source != null) { char[] array = source.toCharArray(); StringBuilder reverse = new StringBuilder(); for (int i = array.length - 1; i >= 0; i--) reverse.append(array[i]); return reverse.toString(); } return null; } /** * 将系统转义字符,转义成可在字符串表达的转义字符 * 例如:将字符串中的 \" 转转成 \\\" * * @param source 源字符串 * @return 转换后的字符串 */ public static String convertEscapeChar(String source) { if (source == null) { return null; } source = fastReplaceAll(source, "\\[^u][^[0-9|a-f]]{4}", "\\u005c"); source = fastReplaceAll(source, "\f", "\\u000c"); source = fastReplaceAll(source, "\'", "\\u0027"); source = fastReplaceAll(source, "\r", "\\u000d"); source = fastReplaceAll(source, "\"", "\\u0022"); source = fastReplaceAll(source, "\b", "\\u0008"); source = fastReplaceAll(source, "\t", "\\u0009"); source = fastReplaceAll(source, "\n", "\\u000a"); return source; } /** * 将可在字符串中表达的转义字符,转义成系统转义字符 * 例如:将字符串中的 \\\" 转转成 \" * * @param source 源字符串 * @return 转换后的字符串 */ public static String unConvertEscapeChar(String source) { if (source == null) { return null; } source = fastReplaceAll(source, "\\\\u005c", "\\"); source = fastReplaceAll(source, "\\\\u000c", "\f"); source = fastReplaceAll(source, "\\\\u0027", "\'"); source = fastReplaceAll(source, "\\\\u000d", "\r"); source = fastReplaceAll(source, "\\\\u0022", "\""); source = fastReplaceAll(source, "\\\\u0008", "\b"); source = fastReplaceAll(source, "\\\\u0009", "\t"); source = fastReplaceAll(source, "\\\\u000a", "\n"); return source; } /** * 字符串转 Unicode * * @param source 字符串 * @return unicode 字符串 */ public static String toUnicode(String source) { if (source == null) { return null; } StringBuffer result = new StringBuffer(); for (int i = 0; i < source.length(); i++) { // 取出一个字符 char c = source.charAt(i); // 转换为unicode result.append("\\u" + leftPad(Integer.toHexString(c), 4, '0')); } return result.toString(); } /** * Unicode 转 字符串 * * @param source unicode 字符串 * @return string 字符串 */ public static String fromUnicode(String source) { if (source == null) { return null; } if (source.contains("\\u")) { StringBuffer result = new StringBuffer(); String[] hex = source.split("\\\\u"); for (int i = 0; i < hex.length; i++) { String element = hex[i]; if (element.length() >= 4) { String codePoint = element.substring(0, 4); // 转换码点 int charCode = Integer.parseInt(codePoint, 16); result.append((char) charCode); element = element.substring(4, element.length()); } // 追加成string result.append(element); } return result.toString(); } else { return source; } } /** * 字符串转换为 Java 基本类型 * * @param value 字符串字面值 * @param type Type类型 * @param ignoreCase 是否在字段匹配时忽略大小写 * @param 范型 * @return 基本类型对象 */ public static T toObject(String value, Type type, boolean ignoreCase) { if(value==null || type==null) { return null; } Class clazz = null; if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; clazz = (Class) parameterizedType.getRawType(); } else if (type instanceof Class) { clazz = (Class) type; } else { return (T) value; } if (value == null && !clazz.isPrimitive()) { return null; } if(value.equals("null") && !clazz.isPrimitive()){ value = null; } if (clazz == int.class || clazz == Integer.class) { value = value == null ? "0" : value; return (T) Integer.valueOf(value); } else if (clazz == float.class || clazz == Float.class) { value = value == null ? "0" : value; return (T) Float.valueOf(value); } else if (clazz == double.class || clazz == Double.class) { value = value == null ? "0" : value; return (T) Double.valueOf(value); } else if (clazz == boolean.class || clazz == Boolean.class) { value = value == null ? "false" : value; return (T) Boolean.valueOf(value); } else if (clazz == long.class || clazz == Long.class) { value = value == null ? "0" : value; return (T) Long.valueOf(value); } else if (clazz == short.class || clazz == Short.class) { value = value == null ? "0" : value; return (T) Short.valueOf(value); } else if (clazz == byte.class || clazz == Byte.class) { value = value == null ? "0" : value; return (T) Byte.valueOf(value); } else if (clazz == char.class || clazz == Character.class) { Object tmpValue = value != null ? value.charAt(0) : null; return (T) tmpValue; } else if (clazz == Date.class || TReflect.isExtendsByClass(clazz, Date.class)) { try { SimpleDateFormat dateFormat = new SimpleDateFormat(TDateTime.STANDER_DATETIME_TEMPLATE); return (T) (value != null ? TReflect.newInstance(clazz, dateFormat.parse(value).getTime()): null); } catch (Exception e){ Logger.error("TString.toObject error: ", e); return null; } } else if ((TReflect.isImpByInterface(clazz, Collection.class) || clazz.isArray()) && JSON.isJSONList(value)) { return JSON.toObject(value, type, ignoreCase); } else if (TReflect.isImpByInterface(clazz, Map.class) && JSON.isJSONMap(value)) { return JSON.toObject(value, type, ignoreCase); } else if (JSON.isJSON(value) && !TReflect.isSystemType(clazz)) { return JSON.toObject(value, type, ignoreCase); } else if (value.startsWith("\"") && value.endsWith("\"")) { return (T) value.substring(1, value.length() - 1); } else if(clazz == BigDecimal.class){ return (T)new BigDecimal(value); } else { return (T) value; } } /** * 字符串转换为 Java 基本类型 * * @param value 字符串字面值 * @param type Type类型 * @param 范型 * @return 基本类型对象 */ @SuppressWarnings("unchecked") public static T toObject(String value, Type type) { return (T) toObject(value, type, false); } public static char[] chars = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; public static Map unChars = new HashMap(); static { initUnchars(); } public static void setChars(char[] argChars) { argChars = chars; initUnchars(); } private static void initUnchars() { for(int i=0;i 62) { return null; } num = num < 0 ? num*-1 : num; String result = ""; long tmpValue = num; while (true) { long value = (int) (tmpValue % radix); result = chars[(int) value] + result; value = tmpValue / radix; if (value >= radix) { tmpValue = value; } else { result = chars[(int) value] + result; break; } } return result; } public static long radixUnConvert(String str, int radix) { long result = unChars.get(str.charAt(0)); for(int i=1; i 62) { return null; } BigDecimal num = n_num; BigDecimal radix = BigDecimal.valueOf(n_radix); num = num.compareTo(BigDecimal.ZERO) < 0 ? num.multiply(BigDecimal.valueOf(-1)) : num; String result = ""; BigDecimal tmpValue = num; while (true) { BigDecimal[] drValue = tmpValue.divideAndRemainder(radix); BigDecimal value = drValue[1]; result = chars[value.intValue()] + result; value = drValue[0]; if (value.compareTo(radix)>=0) { tmpValue = value; } else { result = chars[value.intValue()] + result; break; } } return result; } public static BigDecimal radixBigUnConvert(String str, int n_radix) { BigDecimal radix = BigDecimal.valueOf(n_radix); BigDecimal result = BigDecimal.valueOf(unChars.get(str.charAt(0))); for(int i=1; i items = new ArrayList(); while (stringTokenizer.hasMoreTokens()){ items.add(stringTokenizer.nextToken()); } return items.toArray(new String[items.size()]); } /** * 在字符串中插入字符 * @param source 源字符串 * @param position 插入位置, 从 1 开始 * @param value 插入的字符串 * @return 插入后的字符串数据 */ public static String insert(String source, int position, String value){ if(position <=0 ){ throw new IllegalArgumentException("parameter position must lager than 0"); } return source.substring(0, position) + value + source.substring(position); } /** * 移除字符串尾部的换行符 * @param source 源字符串 * @return 处理后的字符串 */ public static String trimEndLF(String source){ return source.replaceAll("[\r\n]*$", ""); } /** * 获取字符串的缩进 * @param source 源字符串 * @return 缩进 */ public static int retract(String source){ int currentRetract; for (currentRetract = 0; currentRetract < source.length(); currentRetract++) { if (source.charAt(currentRetract) != ' ') { if (currentRetract > 0) { currentRetract--; } break; } } return currentRetract; } /** * 驼峰命名转下划线命名 * @param param 驼峰命名字符串 * @return 下划线命名字符串 */ public static String camelToUnderline(String param){ if (param == null||"".equals(param.trim())){ return ""; } int len = param.length(); StringBuilder sb = new StringBuilder(len); sb.append(param.charAt(0)); for (int i = 1; i < len; i++) { char c=param.charAt(i); if (Character.isUpperCase(c)){ sb.append("_"); sb.append(Character.toLowerCase(c)); }else{ sb.append(c); } } return sb.toString(); } /** * 下划线命名转驼峰命名 * @param param 下划线命名字符串 * @return 驼峰命名字符串 */ public static String underlineToCamel(String param){ if (param == null||"".equals(param.trim())){ return ""; } int len=param.length(); StringBuilder sb=new StringBuilder(len); sb.append(param.charAt(0)); for (int i = 1; i < len; i++) { char c = param.charAt(i); if (c == '_'){ if (++i