package io.craft.atom.util; import java.text.NumberFormat; import java.util.Locale; import java.util.Random; /** * A string utility class that manipulates string. * It is <code>null</code> safe, means it handles input string quietly. * That is to say if a <code>null</code> input will return <code>null</code>, * there is no <code>NullPointerException</code> will be thrown. * * @author mindwind * @version 1.0, 2006-12-23 */ public class StringUtil { /** * Convert from DBC case to SBC case. * * @param src * @return SBC case string */ public static String dbc2sbcCase(String src) { if (src == null) { return null; } char[] c = src.toCharArray(); for (int i = 0; i < c.length; i++) { // WHITESPCE ASCII-32 if (c[i] == 32) { c[i] = (char) 12288; continue; } // ASCII character 33-126 <-> unicode 65281-65374 if (c[i] < 127) c[i] = (char) (c[i] + 65248); } return new String(c); } /** * Convert from SBC case to DBC case * * @param src * @return DBC case */ public static String sbc2dbcCase(String src) { if (src == null) { return null; } char[] c = src.toCharArray(); for (int i = 0; i < c.length; i++) { // WHITESPCE ASCII-32 if (c[i] == 12288) { c[i] = (char) 32; continue; } // ASCII character 33-126 <-> unicode 65281-65374 if (c[i] > 65280 && c[i] < 65375) { c[i] = (char) (c[i] - 65248); } } return new String(c); } /** * Convert a string array to a string using delim as separator. If array == null return null. * * @param array * @param delim if delim == null, convert to "" * @return a new concatenated string */ public static String toString(String[] array, String delim) { if (array == null) { return null; } int length = array.length - 1; if (delim == null) { delim = ""; } StringBuilder buf = new StringBuilder(length * 8); for (int i = 0; i < length; i++) { buf.append(array[i]); buf.append(delim); } buf.append(array[length]); return buf.toString(); } /** * Judge the string within a string array or not.<br> * <li>strings == null("") return false * <li>string == null("") return false * * @param strings * @param string * @param caseSensitive * @return true if string within the string array, otherwise false */ public static boolean contains(String[] strings, String string, boolean caseSensitive) { if (strings == null || strings.length == 0) { return false; } if (string == null || string.length() == 0) { return false; } for (int i = 0; i < strings.length; i++) { if (caseSensitive == true) { if (strings[i].equals(string)) { return true; } } else { if (strings[i].equalsIgnoreCase(string)) { return true; } } } return false; } /** * Judge the string within a string array or not, if the string is a substring of any string in the array return true. <br> * <li>strings == null("") return false * <li>string == null("") return false * * @param strings * @param string * @param caseSensitive * @return true if string or its substring within the string array, otherwise false */ public static boolean containSubstring(String[] strings, String string, boolean caseSensitive) { if (strings == null || strings.length == 0) { return false; } if (string == null || string.length() == 0) { return false; } for (int i = 0; i < strings.length; i++) { if (caseSensitive == true) { if (strings[i].equals(string) || strings[i].indexOf(string) > -1) { return true; } } else { if (strings[i].equalsIgnoreCase(string) || strings[i].toLowerCase().indexOf(string.toLowerCase()) > -1) { return true; } } } return false; } /** * Count the number of target string occur in the source. * * @param src * @param target * @return the number of target string occur in the source */ public static int count(String src, String target) { int count = 0; int index = src.indexOf(target); while (index != -1) { count++; index = src.indexOf(target, index + 1); } return count; } /** * Convert first char to lower case * * @param src * @return string which first char converted to lower case */ public static String firstCharToLowerCase(String src) { if (src.length() == 1) { return src.substring(0, 1).toLowerCase(); } else { return src.substring(0, 1).toLowerCase() + src.substring(1); } } /** * Convert first char to upper case * * @param src * @return string which first char converted to upper case */ public static String firstCharToUpperCase(String src) { if (src.length() == 1) { return src.substring(0, 1).toUpperCase(); } else { return src.substring(0, 1).toUpperCase() + src.substring(1); } } /** * Convert a string to currency string * * @param src * @param locale * @return The currency format string */ public static String toCurrencyString(String src, Locale locale) { Double currency = Double.parseDouble(src); return toCurrencyString(currency, locale); } /** * Convert a double to currency string. * * @param src * @param locale * @return The currency format string */ public static String toCurrencyString(Double src, Locale locale) { if (src == null) { throw new NullPointerException("src == null"); } NumberFormat nf = NumberFormat.getCurrencyInstance(locale); nf.setMaximumFractionDigits(2); nf.setMinimumFractionDigits(2); return nf.format(src); } /** * Using value to replace variable which with a specified prefix in the src string. * <br> * Note: it's not a nested process, if the values array has variable ignore it. * * <pre> * variable = prefix + num (num start from 1)<br> * eg: * abc%1def%2ghi%3jk, like %1 is variable * abc$1def$2, like $1 is variable and prefix is $ * </pre> * * <li> if src == null or values == null or values.length == 0 return src itself. * <li> if values.length > variable num, ignore redundant value. * <li> if values.length < variable num, use the last value replace the redundant variable. * * @param prefix variable prefix, if prefix is null using default prefix "%" * @param src * @param value * @return replaced string */ public static String replace(String prefix, String src, String value) { String[] values = new String[1]; values[0] = value; return replace(prefix, src, values); } public static String getReplaceString(String src, String[] values) { return replace("%", src, values); } /** * Using values string array to replace variable which with a specified prefix in the src string. * <br> * Note: it's not a nested process, if the values array has variable ignore it. * * <pre> * variable = prefix + num (num start from 1)<br> * eg: * abc%1def%2ghi%3jk, like %1 is variable * abc$1def$2, like $1 is variable and prefix is $ * </pre> * * <li> if src == null or values == null or values.length == 0 return src itself. * <li> if values.length > variable num, ignore redundant value. * <li> if values.length < variable num, use the last value replace the redundant variable. * * @param prefix variable prefix, if prefix is null using default prefix "%" * @param src * @param values * @return replaced string */ public static String replace(String prefix, String src, String[] values) { if (src == null || values == null || values.length < 1) { return src; } if (prefix == null) { prefix = "%"; } StringBuilder result = new StringBuilder(); int beginIndex = 0; for (int i = 0, count = 0; true; i++) { String argument = prefix + Integer.toString(i + 1); int endIndex = src.indexOf(argument, beginIndex); count++; if (endIndex != -1) { int len = Integer.valueOf(count).toString().length() + 1; StringBuilder part = new StringBuilder(src.substring(beginIndex, endIndex)); if (i < values.length) { part.append(values[i]); } else { part.append(values[values.length - 1]); } result.append(part); beginIndex = endIndex + len; } else { result.append(src.substring(beginIndex)); break; } } return result.toString(); } /** * Insert target string to src string at index position. If index is invalid return original string. * * @param src * @param target * @param index * @return string after inserted. */ public static String insert(String src, String target, int index) { if (src == null) { return src; } if (index < 0 || index > src.length()) { return src; } StringBuilder sb = new StringBuilder(); if (index != 0) { sb.append(src.substring(0, index)); } sb.append(target); sb.append(src.substring(index)); return sb.toString(); } /** * <p>Checks if a String is empty ("") or null.</p> * * <pre> * StringUtils.isEmpty(null) = true * StringUtils.isEmpty("") = true * StringUtils.isEmpty(" ") = false * StringUtils.isEmpty("bob") = false * StringUtils.isEmpty(" bob ") = false * </pre> * * @param str the String to check, may be null * @return <code>true</code> if the String is empty or null */ public static boolean isEmpty(String str) { return str == null || str.length() == 0; } /** * <p>Checks if a String is whitespace, empty ("") or null.</p> * * <pre> * StringUtils.isBlank(null) = true * StringUtils.isBlank("") = true * StringUtils.isBlank(" ") = true * StringUtils.isBlank("bob") = false * StringUtils.isBlank(" bob ") = false * </pre> * * @param str the String to check, may be null * @return <code>true</code> if the String is null, empty or whitespace */ public static boolean isBlank(String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } return true; } /** * <p> * Checks if some strings has any empty string. * </p> * If strings == null, return true * * @param strings * @return true is any string is empty, otherwise false. */ public static boolean isAnyEmpty(String... strings) { if (strings == null) { return true; } for (String s : strings) { if (isEmpty(s)) { return true; } } return false; } /** * Checks if some strings has any blank string.<br> * If strings == null, return true * * @param strings * @return true if any string is blank, otherwise false. */ public static boolean isAnyBlank(String... strings) { if (strings == null) { return true; } for (String s : strings) { if (isBlank(s)) { return true; } } return false; } /** * Checks if all string is empty. If strings == null, return true * * @param strings * @return true if all string is empty, otherwise false. */ public static boolean isAllEmpty(String... strings) { if (strings == null) { return true; } boolean b = true; for (String s : strings) { b &= isEmpty(s); } return b; } /** * Checks if all string is blank. If strings == null, return true * * @param strings * @return true if all string is blank, otherwise false. */ public static boolean isAllBlank(String... strings) { if (strings == null) { return true; } boolean b = true; for (String s : strings) { b &= isBlank(s); } return b; } /** * Checks if all the strings is not blank. * * @param strings * @return true if all string is not blank, otherwise false. */ public static boolean isAllNotBlank(String... strings) { if (isAnyBlank(strings)) { return false; } return true; } /** * Checks if all the strings is not empty. * * @param strings * @return true if all string is not empty, otherwise false. */ public static boolean isAllNotEmpty(String... strings) { if (isAnyEmpty(strings)) { return false; } return true; } /** * Check if the string is a digital string, eg: 123 or 123.58 etc. * * @param src * @return true if string is digital */ public static boolean isDigitalString(String src) { if (src == null) { return false; } for (int i = 0; i < src.length(); i++) { if (Character.isDigit(src.charAt(i)) || src.charAt(i) == '.') { continue; } else { return false; } } return true; } /** * Check that the given CharSequence is neither <code>null</code> nor of * length 0. Note: Will return <code>true</code> for a CharSequence that * purely consists of whitespace. * <p> * * <pre> * StringUtils.hasLength(null) = false * StringUtils.hasLength("") = false * StringUtils.hasLength(" ") = true * StringUtils.hasLength("Hello") = true * </pre> * * @param src * the CharSequence to check (may be <code>null</code>) * @return <code>true</code> if the CharSequence is not null and has length * @see #hasText(CharSequence) */ public static boolean hasLength(CharSequence src) { return (src != null && src.length() > 0); } /** * Check whether the given CharSequence has actual text. More specifically, * returns <code>true</code> if the string not <code>null</code>, its length * is greater than 0, and it contains at least one non-whitespace character. * <p> * * <pre> * StringUtils.hasText(null) = false * StringUtils.hasText("") = false * StringUtils.hasText(" ") = false * StringUtils.hasText("12345") = true * StringUtils.hasText(" 12345 ") = true * </pre> * * @param str * the CharSequence to check (may be <code>null</code>) * @return <code>true</code> if the CharSequence is not <code>null</code>, * its length is greater than 0, and it does not contain whitespace * only * @see java.lang.Character#isWhitespace */ public static boolean hasText(CharSequence str) { if (!hasLength(str)) { return false; } int strLen = str.length(); for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(str.charAt(i))) { return true; } } return false; } /** * Trim <i>all</i> whitespace from the given string: leading, trailing, and inbetween characters. * * @param src * @return string trimmed. * @see java.lang.Character#isWhitespace */ public static String trimAll(String src) { if (!hasLength(src)) { return src; } StringBuilder sb = new StringBuilder(src); int index = 0; while (sb.length() > index) { if (Character.isWhitespace(sb.charAt(index))) { sb.deleteCharAt(index); } else { index++; } } return sb.toString(); } /** * Trim leading whitespace from the given string. * * @param str * the String to check * @return the trimmed String * @see java.lang.Character#isWhitespace */ public static String trimLeading(String str) { if (!hasLength(str)) { return str; } StringBuilder sb = new StringBuilder(str); while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { sb.deleteCharAt(0); } return sb.toString(); } /** * Trim trailing whitespace from the given string. * * @param str * @return the trimmed String * @see java.lang.Character#isWhitespace */ public static String trimTrailing(String str) { if (!hasLength(str)) { return str; } StringBuilder sb = new StringBuilder(str); while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { sb.deleteCharAt(sb.length() - 1); } return sb.toString(); } /** * Random split a string into number of segments. * * @param num * @return the array of strings split. */ public static String[] split(String str, int num) { if (str == null) { return null; } if (num <= 1) { return new String[] { str }; } String[] sarr = null; int len = str.length(); if (num >= len) { sarr = new String[len]; for (int i = 0; i < len; i++) { sarr[i] = Character.toString(str.charAt(i)); } return sarr; } Random ran = new Random(); int scope = len / num; int start = 0; int end = 0; sarr = new String[num]; for (int i = 0; i < num; i++) { if (i == num - 1) { sarr[i] = str.substring(start); } else { end = ran.nextInt(scope) + start; sarr[i] = str.substring(start, end); start = end; } } return sarr; } // ~ -------------------------------------------------------------------------------------------------------------- private StringUtil() { throw new UnsupportedOperationException(); } }