package org.voovan.tools; import org.voovan.tools.json.JSON; import org.voovan.tools.reflect.TReflect; import java.util.ArrayList; import java.util.Collection; import java.util.Hashtable; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * String 工具类 * * @author helyho * * Voovan Framework. * WebSite: https://github.com/helyho/Voovan * Licence: Apache v2 License */ public class TString { private static Hashtable<Integer,Pattern> regexPattern = new Hashtable<Integer,Pattern>(); /** * 单词首字母大写 * @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 floadString 浮点数字符串 * @return 是否是浮点数 */ public static boolean isFloat(String floadString){ if(floadString!=null && regexMatch(floadString, "^-?\\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; } } /** * 正则表达式查找,匹配的被提取出来做数组 * @param source 目标字符串 * @param regex 正则表达式 * @return 匹配的字符串数组 */ public static String[] searchByRegex(String source,String regex){ if(source==null){ return null; } Pattern pattern = null; if(regexPattern.containsKey(regex.hashCode())){ pattern = regexPattern.get(regex.hashCode()); }else{ pattern = Pattern.compile(regex); regexPattern.put(regex.hashCode(), pattern); } Matcher matcher = pattern.matcher(source); ArrayList<String> result = new ArrayList<String>(); while(matcher.find()){ result.add(matcher.group()); } return result.toArray(new String[0]); } /** * 正则匹配 * @param source 目标字符串 * @param regex 正则表达式 * @return 正则搜索后得到的匹配数量 */ public static int regexMatch(String source,String regex){ return searchByRegex(source,regex).length; } /** * 判断字符串空指针或者内容为空 * @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<String, String> tokens){ if(source==null){ return null; } for(Entry<String, String> entry : tokens.entrySet()){ String value = entry.getValue(); if(value==null){ value="null"; } source = tokenReplace(source,entry.getKey(),entry.getValue()); } return source; } /** * 按照标识符进行替换 * @param source 源字符串,标识符使用"{{标识}}"进行包裹 * @param tokenName 标识符 * @param tokenValue 标志符值 * @return 替换后的字符串 */ public static String tokenReplace(String source,String tokenName,String tokenValue){ if(source==null){ return null; } return source.replaceAll("\\{\\{"+tokenName+"\\}\\}",Matcher.quoteReplacement(tokenValue)); } /** * 按位置格式化字符串 * TString.format("aaaa{}bbbb{}cccc{}", "1","2","3") * 输出aaaa1bbbb2cccc3 * @param source 字符串 * @param args 多个参数 * @return 格式化后的字符串 */ public static String format(String source,String ...args){ if(source==null){ return null; } for(String arg : args){ source = replaceFirst(source,"{}",arg); } 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 = source.replaceAll("\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; } return source.replace("\\","\\u005c") .replace("\f","\\u000c") .replace("\'","\\u0027") .replace("\r","\\u000d") .replace("\"","\\u0022") .replace("\b","\\u0008") .replace("\t","\\u0009") .replace("\n","\\u000a"); } /** * 将可在字符串中表达的转义字符,转义成系统转义字符 * 例如:将字符串中的 \\\" 转转成 \" * @param source 源字符串 * @return 转换后的字符串 */ public static String unConvertEscapeChar(String source){ if(source==null){ return null; } return source.replace("\\\\","\\") .replace("\\f","\f") .replace("\\'","\'") .replace("\\r","\r") .replace("\\\"","\"") .replace("\\b","\b") .replace("\\t","\t") .replace("\\n","\n"); } /** * 字符串转 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 clazz Class类,仅支持基本类型 * @param ignoreCase 是否在字段匹配时忽略大小写 * @return 基本类型对象 */ public static Object toObject(String value, Class clazz, boolean ignoreCase){ if(value == null){ return null; }else if(clazz == int.class || clazz == Integer.class){ return Integer.valueOf(value); }else if(clazz == float.class || clazz == Float.class){ return Float.valueOf(value); }else if(clazz == double.class || clazz == Double.class){ return Double.valueOf(value); }else if(clazz == boolean.class || clazz == Boolean.class){ return Boolean.valueOf(value); }else if(clazz == long.class || clazz == Long.class){ return Long.valueOf(value); }else if(clazz == short.class || clazz == Short.class){ return Short.valueOf(value); }else if(clazz == byte.class || clazz == Byte.class){ return Byte.valueOf(value); }else if(clazz == char.class || clazz == Character.class){ return value!=null ? value.charAt(0) : null; }else if(TReflect.isImpByInterface(clazz,Collection.class) || TReflect.isImpByInterface(clazz,Map.class) || clazz.isArray()){ return JSON.toObject(value, clazz, ignoreCase); }else if(TString.searchByRegex(value,"^\\s*\\{[\\s\\S]*\\}\\s*$").length > 0 || TString.searchByRegex(value,"^\\s*\\[[\\s\\S]*\\]\\s*$").length > 0 ){ return JSON.toObject(value, clazz, ignoreCase); }else{ return value; } } /** * 字符串转换为 Java 基本类型 * @param value 字符串字面值 * @param clazz Class类,仅支持基本类型 * @return 基本类型对象 */ public static Object toObject(String value,Class clazz){ return toObject(value, clazz, false); } }