package com.yanzuoguang.util.helper; import com.yanzuoguang.util.base.ObjectHelper; import com.yanzuoguang.util.exception.CodeException; import com.yanzuoguang.util.exception.ExceptionHelper; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 字符串帮主类 * * @author 颜佐光 */ public class StringHelper { /** * 空字符串常量 */ public static final String EMPTY = ""; public static final String TYPE_FLOAT = "float"; public static final String TYPE_DOUBLE = "double"; public static final String TYPE_INT = "int"; public static final String TYPE_BOOL = "boolean"; public static final String TYPE_OBJECT = "System.Object"; public static final String UNDER_FLAG = "_"; //------------------------------------------------------ 空值判断和处理 ----------------------------------------------------------------------- /** * 检测字符是否为空 * * @param p 需要检测的字符 * @return 检测结果 */ public static boolean isEmptyChar(char p) { if (p == '\r' || p == '\n' || p == '\t' || p == ' ') { return true; } return false; } /** * 判断传入的字符串是否为空 * * @param froms 需要检测的字符串 * @return 是否为空 */ public static boolean isEmpty(Object... froms) { for (Object from : froms) { boolean isEmpty = from == null || from.toString().length() < 1; if (isEmpty) { return isEmpty; } } return false; } /** * 是否属于空数组 * * @param val * @return */ public static boolean isEmptyArray(Object val) { if (val == null) { return true; } boolean isArray = val instanceof List || val.getClass().isArray(); if (!isArray) { return false; } List list; // 判断处理 if (val instanceof List) { list = (List) val; } else { Object[] arr = (Object[]) val; list = Arrays.asList(arr); } int length = list.size(); return length == 0; } /** * 判断字符串是否为空 * * @param from 来源数据 * @return 是否为空 */ public static boolean isEmpty(String from) { return from == null || from.length() < 1; } /** * 获取空字符串 * * @param str * @return */ public static String getEmpty(Object str) { if (isEmpty(str)) { return ""; } return str.toString(); } /** * 传入很多值,返回第一个不等于排除值、空值的值,当全部为排除值时,返回默认值 * * @param expandValue 排除值 * @param defReturn 默认返回值 * @param froms 其他值 * @param <T> * @return 返回值 */ public static <T extends Object> T getFirstRun(T expandValue, T defReturn, T... froms) { if (froms != null) { for (T from : froms) { if (isEmpty(from)) { continue; } if (expandValue != null && (expandValue == from || expandValue.equals(from))) { continue; } return from; } } return defReturn; } /** * 传入很多字符串,获取第一个非空的字符串,至少需要两个参数 * * @param froms 参数列表 * @return 第一个非空字符串 */ public static String getFirst(String... froms) { return getFirstRun(EMPTY, EMPTY, froms); } /** * 传入很多整形,获取第一个非0的值,至少需要两个参数 * * @param froms 参数列表 * @return 第一个非0值 */ public static Integer getFirst(Integer... froms) { return getFirstRun(0, 0, froms); } /** * 传入很多整形,获取第一个非0的值,至少需要两个参数 * * @param froms 参数列表 * @return 第一个非0值 */ public static Long getFirst(Long... froms) { return getFirstRun(0L, 0L, froms); } /** * 传入很多整形,获取第一个非0的值,至少需要两个参数 * * @param froms 参数列表 * @return 第一个非0值 */ public static Double getFirst(Double... froms) { return getFirstRun(0.0, 0.0, froms); } /** * 获取第一个非空值 * * @param froms 返回值 * @return 默认返回false */ public static Boolean getFirst(Boolean... froms) { return getFirstRun(null, false, froms); } /** * 传入很多字符串,获取第一个非空的字符串,至少需要两个参数 * * @param froms 参数列表 * @return 第一个非空字符串 */ public static String getFirstNull(String... froms) { return getFirstRun(EMPTY, null, froms); } /** * 检测值是否为数字 * * @param from 需要检测的值 * @return 检测结果 */ public static boolean isNumber(String from) { if (StringHelper.isEmpty(from)) { return false; } final char[] chars = from.toCharArray(); int sz = chars.length; boolean hasExp = false; boolean hasDecPoint = false; boolean allowSigns = false; boolean foundDigit = false; // deal with any possible sign up front final int start = (chars[0] == '-') ? 1 : 0; // leading 0 if (sz > start + 1 && chars[start] == '0') { if ( (chars[start + 1] == 'x') || (chars[start + 1] == 'X') ) { // leading 0x/0X int i = start + 2; if (i == sz) { // str == "0x" return false; } // checking hex (it can't be anything else) for (; i < chars.length; i++) { boolean inputHex = (chars[i] < '0' || chars[i] > '9') && (chars[i] < 'a' || chars[i] > 'f') && (chars[i] < 'A' || chars[i] > 'F'); if (inputHex) { return false; } } return true; } else if (Character.isDigit(chars[start + 1])) { // leading 0, but not hex, must be octal int i = start + 1; for (; i < chars.length; i++) { if (chars[i] < '0' || chars[i] > '7') { return false; } } return true; } } sz--; // don't want to loop to the last char, check it afterwords // for type qualifiers int i = start; // loop to the next to last char or to the last char if we need another digit to // make a valid number (e.g. chars[0..5] = "1234E") while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) { if (chars[i] >= '0' && chars[i] <= '9') { foundDigit = true; allowSigns = false; } else if (chars[i] == '.') { if (hasDecPoint || hasExp) { // two decimal points or dec in exponent return false; } hasDecPoint = true; } else if (chars[i] == 'e' || chars[i] == 'E') { // we've already taken care of hex. if (hasExp) { // two E's return false; } if (!foundDigit) { return false; } hasExp = true; allowSigns = true; } else if (chars[i] == '+' || chars[i] == '-') { if (!allowSigns) { return false; } allowSigns = false; // we need a digit after the E foundDigit = false; } else { return false; } i++; } if (i < chars.length) { if (chars[i] >= '0' && chars[i] <= '9') { // no type qualifier, OK return true; } if (chars[i] == 'e' || chars[i] == 'E') { // can't have an E at the last byte return false; } if (chars[i] == '.') { if (hasDecPoint || hasExp) { // two decimal points or dec in exponent return false; } // single trailing decimal point after non-exponent is ok return foundDigit; } boolean allowD = !allowSigns && (chars[i] == 'd' || chars[i] == 'D' || chars[i] == 'f' || chars[i] == 'F'); if (allowD) { return foundDigit; } if (chars[i] == 'l' || chars[i] == 'L') { // not allowing L with an exponent or decimal point return foundDigit && !hasExp && !hasDecPoint; } // last character is illegal return false; } // allowSigns is true iff the val ends in 'E' // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass return !allowSigns && foundDigit; } //------------------------------------------------------ 转换值 ----------------------------------------------------------------------- /** * 类型匹配 * * @param type 类型 * @param vBase 类型的名称 * @return 读取的结果 */ public static boolean isType(Class<?> type, Class<?> vBase) { if (type == null) { return false; } else if (type.equals(vBase)) { return true; } if (TYPE_OBJECT.equals(type.toString())) { return false; } else { return isType(type.getSuperclass(), vBase); } } /** * 根据类型来获取值 * * @param cls 类型 * @param from 对象 * @return 返回获取的值 */ public static <T> T to(Class<T> cls, Object from) { String vName = cls.getName(); Object to = null; if (isType(cls, String.class)) { to = toString(from); } else if (TYPE_BOOL.equals(vName) || (isType(cls, Boolean.class) && from != null)) { String strValue = toString(from); to = toBoolean(strValue); } else if (TYPE_INT.equals(vName) || (isType(cls, Integer.class) && from != null)) { to = toInt(from); } else if (TYPE_DOUBLE.equals(vName) || (isType(cls, Double.class) && from != null)) { to = toDouble(from); } else if (TYPE_FLOAT.equals(vName) || (isType(cls, Float.class) && from != null)) { to = toDouble(from); } else if (isType(cls, Date.class)) { to = DateHelper.getDateTime(from); } else if (cls.isEnum()) { String strValue = toString(from); if (strValue != null) { to = EnumHelper.toEnum(cls, strValue); } } if (to == null && from == null) { return null; } else if (to != null) { return (T) to; } else { if (ObjectHelper.isSub(cls, from.getClass())) { return (T) from; } return (T) to; } } /** * 将 object 转换为String * * @param obj 需要转换的object * @return 转换成功的字符串 */ public static String toString(Object obj) { return obj == null ? null : obj.toString(); } /** * 将字符串转换为 bool ,当不能转换时,则默认为false * * @param from 需要转换的字符串 * @param defValue 默认值 * @return 转换成功后的值 */ public static boolean toBoolean(Object from, boolean defValue) { boolean result = defValue; try { if (!isEmpty(from)) { result = (!compare(from, "0", true) && !compare(from, "false", true) && !compare(from, "no", true) && !isEmpty(from)); } } catch (Exception ex) { ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将字符串转换为 bool ,当不能转换时,则默认为false * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static boolean toBoolean(Object from) { return toBoolean(from, false); } /** * 将字符串转换为 Int,当不能转换时,则默认为0 * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static short toShort(Object from) { short result = 0; try { if (!isEmpty(from)) { result = Short.parseShort(from.toString()); } } catch (Exception ex) { ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将字符串转换为 Int,当不能转换时,则默认为0 * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static int toInt(Object from) { int result = 0; try { if (!isEmpty(from)) { // String类型的小数转int会出错 result = Integer.parseInt(from.toString()); } } catch (Exception ex) { try { double d = Double.parseDouble(from.toString()); int i = (int) d; result = Integer.parseInt(String.valueOf(i)); } catch (Exception e) { ExceptionHelper.handleException(StringHelper.class, ex, from); } ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将字符串转换为 long,当不能转换时,则默认为0 * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static long toLong(Object from) { long result = 0; try { if (!isEmpty(from)) { result = Long.parseLong(from.toString()); } } catch (Exception ex) { ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将字符串转换为 long,当不能转换时,则默认为0 * * @param from 需要转换的字节数组 * @return 转换成功后的值 */ public static long toLong(byte[] from) { if (from.length > 0) { return ByteHelper.toLongByLH(from); } return 0L; } /** * 将字符串转换为 Float,当不能转换时,则默认为0 * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static float toFloat(Object from) { float result = 0; try { if (!isEmpty(from)) { result = Float.parseFloat(from.toString()); } } catch (Exception ex) { ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将字符串转换为 Double,当不能转换时,则默认为0 * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static double toDouble(Object from) { double result = 0.0; try { if (!isEmpty(from)) { result = Double.parseDouble(from.toString()); } } catch (Exception ex) { ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将字符串转换为Decimal,当不能转换时,则默认值为0 * * @param from 需要转换的字符串 * @return 转换成功后的值 */ public static double toDecimal(Object from) { double result = 0; try { if (!isEmpty(from)) { result = Double.valueOf(from.toString()); } } catch (Exception ex) { ExceptionHelper.handleException(StringHelper.class, ex, from); } return result; } /** * 将对象转换为价格,空值用'-'表示 * * @param from 需要转换的价格 * @return 价格字符串 */ public static String toPrice(Object from) { String str = "-"; if (!isEmpty(from) && toDouble(from) != 0) { str = "" + toDouble(from); } return str; } //------------------------------------------------------ 字符串编码 ----------------------------------------------------------------------- /** * 使用Unicode转码 * * @param str * @return */ public static String encoding(String str) { return encoding("UTF-8", str); } /** * 字符串编码转换 * * @param charset 输入字符串 * @param from 输入字符串 * @return */ public static String encoding(String charset, String from) { byte[] buff; try { buff = from.getBytes(charset); // 将字节流转换为字符串 from = new String(buff, charset); from = from.replace("\0", "").replace("\n", ""); } catch (UnsupportedEncodingException e) { ExceptionHelper.handleException(StringHelper.class, e, from); } return from; } //------------------------------------------------------ 常用函数 ----------------------------------------------------------------------- /** * 将字符串进行分割 * * @param from 需要分割的字符串 * @param regex 分割的正则表达式 * @return 分割后的字符串 */ public static String[] split(String from, String regex) { return from.split(regex); } /** * 将 list 转换为字符串 * * @param list * @return */ public static String join(Object... list) { return join(Arrays.asList(list)); } /** * 将 list 转换为字符串 * * @param list 需要处理的字符串列表 * @return 处理后的字符串 */ public static String join(List list) { StringBuilder sb = new StringBuilder(); for (Object item : list) { if (item == null) { continue; } String to = item.toString(); if (isEmpty(to)) { continue; } if (sb.length() > 0) { sb.append(","); } sb.append(to); } return sb.toString(); } /** * 去掉两边的空格 * * @param from 需要去掉空格的字符串 * @return 去掉字符串的值 */ public static String trim(String from) { if (from == null) { return EMPTY; } return from.trim(); } /** * 去掉左边的字符串 * * @param from * @param left * @return */ public static String trimLeft(String from, String... left) { int pos = 0; boolean isHandle; do { isHandle = false; for (String item : left) { int size = item.length(); if (from.indexOf(item, pos) == pos) { isHandle = true; pos += size; continue; } } } while (isHandle); if (pos > 0) { return from.substring(pos); } else { return from; } } /** * 对比字符串是否相等,不区分大小写 * * @param from 第一个字符串 * @param to 第二个字符串 * @return 相等时返回true */ public static boolean compare(Object from, Object to) { return compare(String.valueOf(from), String.valueOf(to), false); } /** * 对比字符串是否相等,不区分大小写 * * @param from 第一个字符串 * @param to 第二个字符串 * @return 相等时返回true */ public static boolean compare(String from, String to) { return compare(from, to, false); } /** * 比较两个字符串是否相等 * * @param from 字符串1 * @param to 字符串2 * @param ignoreCase 是否区分大小写 * @return 比较结果 */ public static boolean compare(String from, String to, boolean ignoreCase) { if (from == null && to == null) { return true; } else if (from == null || to == null) { return false; } else if (from.length() != to.length()) { return false; } else if (ignoreCase) { return from.compareToIgnoreCase(to) == 0; } else { return from.compareTo(to) == 0; } } /** * 比较两个对象转换为字符串是否相等 * * @param from 字符串1 * @param to 字符串2 * @param ignoreCase 是否区分大小写 * @return 比较结果 */ public static boolean compare(Object from, Object to, boolean ignoreCase) { String fromStr = toString(from); String toStr = toString(to); return compare(fromStr, toStr, ignoreCase); } //------------------------------------------------------ 转换值 ----------------------------------------------------------------------- /** * 计算分页数量 * * @param count 数据条数 * @param size 每页大小 * @return */ public static int getPage(int count, int size) { if (size != 0) { return count / size + (count % size > 0 ? 1 : 0); } return 0; } /** * 将字符串转换为菜单 * * @param args 需要获取的路径,会自动剔除空字符串 ["a" ,"b" ] * @return 获取到的路径, 结果为 a => b */ public static String getGo(String... args) { StringBuilder sb = new StringBuilder(); for (String arg : args) { if (isEmpty(arg)) { continue; } if (sb.length() > 0) { sb.append(" => "); } sb.append(arg); } return sb.toString(); } /** * 判断字符串是否是整数 */ public static boolean isInteger(String value) { try { Integer.parseInt(value); return true; } catch (NumberFormatException e) { return false; } } /** * 获取UUID * * @return */ public static String getUUID() { return UUID.randomUUID().toString().replace("-", ""); } /** * 获取主键 * * @return */ public static String getNewID() { String tag = getNewIdTag(System.currentTimeMillis()); String id = getUUID(); return tag + id.substring(tag.length()); } /** * MD5加密 * * @param string 源字符串 * @return 加密后的字符串 */ public static String md5(String string) { try { byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8")); StringBuilder hex = new StringBuilder(hash.length * 2); for (byte b : hash) { if ((b & 0xFF) < 0x10) { hex.append("0"); } hex.append(Integer.toHexString(b & 0xFF)); } return hex.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return StringHelper.EMPTY; } /** * MD5加密 * * @param from 需要加密的字符串 * @return 加密的结果 */ public static String md51(String from) { String to = from; try { // 生成实现指定摘要算法的 MessageDigest 对象。 MessageDigest md = MessageDigest.getInstance("MD5"); // 使用指定的字节数组更新摘要。 md.update(from.getBytes(Charset.forName("utf-8"))); // 通过执行诸如填充之类的最终操作完成哈希计算。 byte[] b = md.digest(); // 生成具体的md5密码到buf数组 int i; StringBuilder buf = new StringBuilder(); for (int offset = 0; offset < b.length; offset++) { i = b[offset]; if (i < 0) { i += 256; } if (i < 16) { buf.append("0"); } buf.append(Integer.toHexString(i)); } to = buf.toString(); // Log.info(class, "32位: " + buf.toString());// 32位的加密 // Log.info(class, "16位: " + buf.toString().substring(8, 24));// 16位的加密,其实就是32位加密后的截取 } catch (Exception e) { ExceptionHelper.handleException(StringHelper.class, e, from); } return to; } /** * 获取组合编号的MD5值 * * @param froms 需要组合的编号 * @return MD5后的值 */ public static String getNewMD5Id(Date date, Object... froms) { if (date == null) { throw new CodeException("生成时间搓 MD5 ID 时,时间不能为空"); } String tag = getNewIdTag(date.getTime()); String id = md51(getId(froms)); return tag + id.substring(tag.length()); } /** * 获取新Id标价 * * @param time * @return */ private static String getNewIdTag(long time) { return String.format("z%015d", time); } /** * 获取组合编号的MD5值 * * @param date 需要组合的编号 * @param args 需要组合的编号 * @return MD5后的值 */ public static String getNewIdMD5(Date date, Object... args) { return getNewMD5Id(date, args); } /** * 获取组合编号的MD5值 * * @param froms 需要组合的编号 * @return MD5后的值 */ public static String getMD5Id(Object... froms) { return md51(getId(froms)); } /** * 获取组合编号的MD5值 * * @param froms 需要组合的编号 * @return MD5后的值 */ public static String getIdMD5(Object... froms) { return getMD5Id(froms); } /** * 获取组合编号 * * @param args 需要组合的编号 * @return 将ID列表进行组合生成ID */ public static String getId(Object... args) { StringBuilder sb = new StringBuilder(); for (Object arg : args) { if (sb.length() > 0) { sb.append(":"); } sb.append(arg); } return sb.toString(); } /** * 获取组合的SQL语句 * * @param froms SQL语句 * @return */ public static String getSql(String... froms) { StringBuilder sb = new StringBuilder(); for (String sql : froms) { if (isEmpty(sql)) { continue; } if (sb.length() > 0) { sb.append(" "); } sb.append(sql.trim()); } return sb.toString(); } /** * 获取CamelCase命名,去掉下划线 * * @param from 原名称 * @return 修改后的名称 */ public static String getCamelCase(String from) { StringBuilder result = new StringBuilder(); String[] a = from.split("_"); for (String s : a) { if (result.length() == 0) { result.append(s.substring(0, 1).toLowerCase()); result.append(s.substring(1)); } else { result.append(s.substring(0, 1).toUpperCase()); result.append(s.substring(1)); } } return result.toString(); } /*** * 驼峰命名转为下划线命名大写 * * @param from * 驼峰命名的字符串 */ public static String getUnderLine(String from) { if (from.contains(UNDER_FLAG)) { return from; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < from.length(); i++) { char c = from.charAt(i); if (Character.isUpperCase(c)) { sb.append(UNDER_FLAG); } sb.append(c); } return sb.toString().toUpperCase(); } /** * 讲guid转换为32位长度的guid * * @param from * @return */ public static String guidTo32(String from) { if (isEmpty(from)) { return from; } return from.replaceAll("-", ""); } /** * 获取字段替换值 * * @param from 来源字符串 * @param target 值对象 * @return 处理后的值对象 */ public static String getCodeString(String from, Object target) { String regex = "\\{(.*?)\\}"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(from); // 寻找到的代码片段 不包含分括号 while (m.find()) { String name = m.group(); String key = m.group(1); String value = StringHelper.getFirst(ObjectHelper.getString(target, key), EMPTY); from = from.replace(name, value); } return from; } }