com.feilong.core.lang.StringUtil Maven / Gradle / Ivy
Show all versions of feilong Show documentation
/*
* Copyright (C) 2008 feilong
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.feilong.core.lang;
import static com.feilong.core.Validator.isNullOrEmpty;
import static com.feilong.core.bean.ConvertUtil.toArray;
import static com.feilong.core.lang.ArrayUtil.EMPTY_STRING_ARRAY;
import static com.feilong.core.util.CollectionsUtil.newArrayList;
import java.io.UncheckedIOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import com.feilong.core.CharsetType;
import com.feilong.core.Validate;
import com.feilong.lib.lang3.StringUtils;
import com.feilong.lib.lang3.text.StrSubstitutor;
import com.feilong.tools.slf4j.Slf4jUtil;
/**
* {@link String}工具类,可以查询,截取,format.
*
* 分隔(split)
*
*
*
* - {@link #split(String, String)}
*
*
*
* 分隔(tokenize)
*
*
*
* - {@link #tokenizeToStringArray(String, String)}
* - {@link #tokenizeToStringArray(String, String, boolean, boolean)}
*
*
*
* 区别在于,split 使用的是 正则表达式 {@link Pattern#split(CharSequence)} 分隔(特别注意,一些特殊字符 $|()[{^?*+\\ 需要转义才能做分隔符),而 {@link StringTokenizer} 使用索引机制,在性能上
* StringTokenizer更高
* 因此,在注重性能的场景,还是建议使用{@link StringTokenizer}
*
*
*
*
* 查询(search)
*
*
*
* - {@link StringUtils#countMatches(CharSequence, CharSequence)} 查询出现的次数
*
*
*
* 其他
*
*
*
* - {@link StringUtils#capitalize(String)} 首字母大写
* - {@link StringUtils#uncapitalize(String)} 单词首字母小写
* - org.apache.commons.lang3.text.WordUtils#uncapitalize(String, char...) 如果要使用一段文字,每个单词首字母小写
*
*
*
* {@link String#String(byte[] )} 和 {@link String#String(byte[], Charset)} 区别
*
*
*
* {@link String#String(byte[] )} 其实调用了{@link String#String(byte[], Charset)};
* 先使用 {@link Charset#defaultCharset()},如果有异常再用 ISO-8859-1, 具体参见 java.lang.StringCoding#decode(byte[], int, int)
*
*
*
* {@link StringBuffer} 和 {@link StringBuilder} 和 {@link String} 对比
*
*
*
* - {@link StringBuffer} 字符串变量(线程安全)
* - {@link StringBuilder} 字符串变量(非线程安全)
* - {@link String} 字符串常量
* - 在大部分情况下 {@link StringBuffer} {@code >} {@link String}
* - 在大部分情况下 {@link StringBuilder} {@code >} {@link StringBuffer}
*
*
*
* String s1 = new String("xyz"); 到底创建几个对象?
*
*
*
* 要看虚拟机的实现.而且要联系上下文
*
*
*
* - 假设:HotSpot1.6,之前没有创建过"xyz" 则创建2个,之前创建过"xyz"则只创建1个
* - 假设:HotSpot1.7,之前不管有没有创建过"xyz" 都创建1个
*
*
*
* String s3 = s1 + s2;
* s3.intern() == s3 到底相不相等?
*
* 要看虚拟机的实现
*
*
*
* - 假设:HotSpot1.6,则false不相等
* - 假设:HotSpot1.7,则在之前没有创建过"abcabc"时,true相等
*
*
*
* {@link StringUtil#replace(String, String, String) replace} 和 {@link #replaceAll(CharSequence, String, String) replaceAll} 和
* {@link String#replaceFirst(String, String) replaceFirst}区别:
*
*
*
*
*
* 字段
* 说明
*
*
* {@link StringUtil#replace(String, String, String)}
* 将字符串中出现的target替换成replacement
*
*
* {@link #replaceAll(CharSequence, String, String)}
* regex是一个正则表达式,将字符串中匹配的子字符串替换为replacement
*
*
* {@link String#replaceFirst(String, String)}
* 和{@link StringUtil#replace(String, String, String)}类似,只不过只替换第一个出现的地方。
*
*
*
*
* 对比以下代码:
*
*
*
* StringUtil.replaceAll("SH1265,SH5951", "([a-zA-Z]+[0-9]+)", "'$1'") ='SH1265','SH5951'
* StringUtil.replace("SH1265,SH5951", "([a-zA-Z]+[0-9]+)", "'$1'") =SH1265,SH5951
* "SH1265,SH5951".replaceFirst("([a-zA-Z]+[0-9]+)", "'$1'") ='SH1265',SH5951
*
*
*
*
* @author feilong
* @see java.util.StringTokenizer
* @see "org.springframework.util.StringUtils#tokenizeToStringArray(String, String)"
* @see "org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#MULTI_VALUE_ATTRIBUTE_DELIMITERS"
* @see com.feilong.lib.lang3.StringUtils
* @see "com.google.common.base.Strings"
* @since 1.4.0
*/
public final class StringUtil{
/**
* A String for a space character.
*
* @since 3.0.0
*/
public static final String SPACE = " ";
/**
* The empty String {@code ""}.
*
* @since 3.0.0
*/
public static final String EMPTY = "";
/**
* A String for linefeed LF ("\n").
*
* @see JLF: Escape Sequences
* for Character and String Literals
* @since 3.0.0
*/
public static final String LF = "\n";
/**
* A String for carriage return CR ("\r").
*
* @see JLF: Escape Sequences
* for Character and String Literals
* @since 3.0.0
*/
public static final String CR = "\r";
//---------------------------------------------------------------
/** Don't let anyone instantiate this class. */
private StringUtil(){
//AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
//see 《Effective Java》 2nd
throw new AssertionError("No " + getClass().getName() + " instances for you!");
}
//---------------------------------------------------------------
/**
* Constructs a new String
by decoding the specified array of bytes using the given charset.
*
* @param bytes
* The bytes to be decoded into characters, may be null
* @param charsetType
* 字符编码,建议使用 {@link CharsetType} 定义好的常量
* @return A new String
decoded from the specified array of bytes using the given charset,
* or null
if the input byte array was null
.
* @see String#String(byte[], String)
* @see "org.apache.commons.lang3.StringUtils#toString(byte[], String)"
* @see com.feilong.lib.lang3.StringUtils#toEncodedString(byte[], Charset)
* @see "org.apache.commons.codec.binary.StringUtils#newString(byte[], String)"
* @since 1.3.0
*/
public static String newString(byte[] bytes,String charsetType){
return StringUtils.toEncodedString(bytes, Charset.forName(charsetType));
}
// [start]toBytes
//---------------------------------------------------------------
/**
* 字符串转换成byte数组.
*
* @param value
* 字符串
* @return 如果 value
是null,抛出 {@link NullPointerException}
* @see String#getBytes()
* @since 1.3.0
*/
public static byte[] getBytes(String value){
Validate.notNull(value, "value can't be null!");
return value.getBytes();
}
/**
* 字符串 value
转换成byte数组.
*
* @param value
* 字符串
* @param charsetName
* 受支持的 charset 名称,比如 utf-8, {@link CharsetType}
* @return 如果 value
是null,抛出 {@link NullPointerException}
* 如果 charsetName
是null,抛出 {@link NullPointerException}
* 如果 charsetName
是blank,抛出 {@link IllegalArgumentException}
* @see String#getBytes(String)
* @since 1.3.0
*/
public static byte[] getBytes(String value,String charsetName){
Validate.notNull(value, "value can't be null!");
Validate.notBlank(charsetName, "charsetName can't be blank!");
//---------------------------------------------------------------
try{
return value.getBytes(charsetName);
}catch (UnsupportedEncodingException e){
String pattern = "value:[{}],charsetName:[{}],suggest you use [{}] constants";
String message = Slf4jUtil.format(pattern, value, charsetName, CharsetType.class.getCanonicalName());
throw new UncheckedIOException(message, e);
}
}
// [end]
// [start]replace
//---------------------------------------------------------------
/**
* 将 text
中的 searchString
替换成 replacement
.
*
* 示例:
*
*
*
*
* A {@code null} reference passed to this method is a no-op.
*
*
*
* StringUtil.replace(null, *, *) = null
* StringUtil.replace("", *, *) = ""
* StringUtil.replace("any", null, *) = "any"
* StringUtil.replace("any", *, null) = "any"
* StringUtil.replace("any", "", *) = "any"
* StringUtil.replace("aba", "a", null) = "aba"
* StringUtil.replace("aba", "a", "") = "b"
* StringUtil.replace("aba", "a", "z") = "zbz"
*
* StringUtil.replace("黑色/黄色/蓝色", "/", "_") = "黑色_黄色_蓝色"
* StringUtil.replace(null, "/", "_") = null
* StringUtil.replace("黑色/黄色/蓝色", "/", null) = "黑色/黄色/蓝色"
*
*
* 此外注意的是:
*
*
* StringUtil.replace("SH1265,SH5951", "([a-zA-Z]+[0-9]+)", "'$1'") = SH1265,SH5951
*
*
* (注意和 {@link #replaceAll(CharSequence, String, String)} 的区别)
*
*
*
* 注意:
*
*
* - 该替换从字符串的开头朝末尾执行,例如,用 "b" 替换字符串 "aaa" 中的 "aa" 将生成 "ba" 而不是 "ab".
* - 虽然底层调用了{@link java.util.regex.Matcher#replaceAll(String) Matcher.replaceAll()},但是使用了
* {@link java.util.regex.Matcher#quoteReplacement(String) Matcher.quoteReplacement()} 处理了特殊字符
*
*
*
* @param text
* text to search and replace in, may be null
* @param searchString
* the String to search for, may be null
* @param replacement
* the String to replace it with, may be null
* @return 如果 text
是null,返回 null
* 如果 searchString
是null,原样返回 text
* 如果 replacement
是null,原样返回 text
* @see java.lang.String#replace(CharSequence, CharSequence)
* @see com.feilong.lib.lang3.StringUtils#replace(String, String, String)
* @since jdk 1.5
*/
public static String replace(final String text,final String searchString,final String replacement){
return StringUtils.replace(text, searchString, replacement);
}
/**
* 使用给定的replacement
替换 content
此字符串所有匹配给定的正则表达式 regex
的子字符串.
*
* 说明:
*
*
* -
* 此方法底层调用的是 {@link java.util.regex.Matcher#replaceAll(String)},相同于
*
Pattern.compile(regex).matcher(str).replaceAll(repl)
*
*
*
*
* 示例:
*
*
*
*
* StringUtil.replaceAll("SH1265,SH5951,SH6766,SH7235,SH1265,SH5951,SH6766,SH7235", "([a-zA-Z]+[0-9]+)", "'$1'")
*
*
* 返回:
*
*
* 'SH1265','SH5951','SH6766','SH7235','SH1265','SH5951','SH6766','SH7235'
*
*
*
*
* 请注意:
*
*
*
*
* 在替代字符串replacement
中,使用 backslashes反斜杆(\)和 dollar signs美元符号 ($)与将其视为字面值替代字符串所得的结果可能不同.
*
* 请参阅 {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll};如有需要,可使用 {@link java.util.regex.Matcher#quoteReplacement
* Matcher.quoteReplacement}取消这些字符的特殊含义
*
*
*
* $ may be treated as references to captured subsequences as described above,$这个特殊的字符,因为替换串使用这个引用正则表达式匹配的组,
* $0代表匹配项,$1代表第1个匹配分组,$1代表第2个匹配分组
*
* 并且 \ are used to escape literal characters in the replacement string.
*
*
*
* 对于以下代码:
*
*
*
*
*
* //分隔字符串并添加引号.
* public void splitAndAddYinHao(){
* String a = "12345,56789,1123456";
* String[] aStrings = a.split(",");
* StringBuilder sb = new StringBuilder();
* int size = aStrings.length;
* for (int i = 0; i {@code <} size; i++){
* sb.append("'" + aStrings[i] + "'");
* if (i != size - 1){
* sb.append(",");
* }
* }
* LOGGER.debug(sb.toString());
* }
*
*
*
* 可以重构成:
*
*
* StringUtil.replaceAll("12345,56789,1123456", "([0-9]+)", "'$1'")
*
*
* 结果都是:
*
*
* '12345','56789','1123456'
*
*
*
*
* @param content
* 需要被替换的字符串
* @param regex
* 用来匹配此字符串的正则表达式,规则参见 RegexPattern 注释
* @param replacement
* 用来替换每个匹配项的字符串
* @return 如果 content
是null,返回 {@link StringUtils#EMPTY}
* 如果 content
中,没有 regex匹配的字符串或者格式,返回content
* @see String字符串替换的一个诡异问题
* @see java.lang.String#replaceAll(String, String)
* @since jdk 1.4
*/
public static String replaceAll(CharSequence content,String regex,String replacement){
return null == content ? EMPTY : content.toString().replaceAll(regex, replacement);
}
/**
* 使用给定的字符串 templateString
作为模板,解析匹配的变量 .
*
* 示例:
*
*
*
*
* String template = "/home/webuser/expressdelivery/${yearMonth}/${expressDeliveryType}/vipQuery_${fileName}.log";
* Date date = now();
*
* Map{@code } valuesMap = newHashMap();
* valuesMap.put("yearMonth", DateUtil.toString(date, DatePattern.YEAR_AND_MONTH));
* valuesMap.put("expressDeliveryType", "sf");
* valuesMap.put("fileName", DateUtil.toString(date, DatePattern.TIMESTAMP));
* LOGGER.debug(StringUtil.replace(template, valuesMap));
*
*
* 返回:
*
*
* /home/webuser/expressdelivery/2016-06/sf/vipQuery_20160608214846.log
*
*
*
*
*
* 注意:此方法只能替换字符串,而不能像el表达式一样使用对象属性之类的来替换
*
*
* 比如:
*
*
*
*
* Map{@code } valuesMap = newHashMap();
* valuesMap.put("today", DateUtil.toString(now(), COMMON_DATE));
* valuesMap.put("user", new User(1L));
* LOGGER.debug(StringUtil.replace("${today}${today1}${user.id}${user}", valuesMap) + "");
*
*
* 返回:
*
*
* 2016-07-16${today1}${user.id}com.feilong.test.User@16f9a31
*
*
*
*
* @param
* the value type
* @param templateString
* the template string
* @param valuesMap
* the values map
* @return 如果 templateString
是 StringUtils.isEmpty(templateString)
,返回 {@link StringUtils#EMPTY}
* 如果 valuesMap
是null或者empty,原样返回 templateString
* @see com.feilong.lib.lang3.text.StrSubstitutor#replace(String)
* @see com.feilong.lib.lang3.text.StrSubstitutor#replace(Object, Map)
* @since 1.1.1
*/
public static String replace(CharSequence templateString,Map valuesMap){
return StringUtils.isEmpty(templateString) ? EMPTY : StrSubstitutor.replace(templateString, valuesMap);
}
// [end]
// [start]substring
//---------------------------------------------------------------
/**
* [截取]从指定索引处(beginIndex
)的字符开始,直到此字符串末尾.
*
*
* 如果 beginIndex
是负数,那么表示倒过来截取,从结尾开始截取长度,此时等同于 {@link #substringLast(String, int)}
*
*
*
* StringUtil.substring(null, *) = null
* StringUtil.substring("", *) = ""
* StringUtil.substring("abc", 0) = "abc"
* StringUtil.substring("abc", 2) = "c"
* StringUtil.substring("abc", 4) = ""
* StringUtil.substring("abc", -2) = "bc"
* StringUtil.substring("abc", -4) = "abc"
* StringUtil.substring("jinxin.feilong",6) =.feilong
*
*
* @param text
* 内容 the String to get the substring from, may be null
* @param beginIndex
* 从指定索引处 the position to start from,negative means count back from the end of the String by this many characters
* @return 如果 text
是null,返回 null
* An empty ("") String 返回 "".
* @see com.feilong.lib.lang3.StringUtils#substring(String, int)
* @see #substringLast(String, int)
*/
public static String substring(final String text,final int beginIndex){
return StringUtils.substring(text, beginIndex);
}
/**
* [截取]从开始位置(startIndex
),截取固定长度(length
)字符串.
*
*
* StringUtil.substring(null, 6, 8) = null
* StringUtil.substring("jinxin.feilong", 6, 2) = .f
*
*
* @param text
* 被截取文字
* @param startIndex
* 索引开始位置,0开始
* @param length
* 长度 {@code >=1}
* @return 如果 text
是null,返回 null
* 如果 startIndex + length
{@code >} text.length
,那么截取 从 startIndex 开始截取,截取到最后
* @see com.feilong.lib.lang3.StringUtils#substring(String, int, int)
*/
public static String substring(final String text,int startIndex,int length){
return StringUtils.substring(text, startIndex, startIndex + length);
}
/**
* [截取]:获取文字最后位数 lastLenth
的字符串.
*
* 示例:
*
*
*
*
* StringUtil.substringLast("jinxin.feilong", 5) = ilong
*
*
*
*
* @param text
* 文字
* @param lastLenth
* 最后的位数
* @return 如果 text
是null,返回 null
* 如果 {@code lastLenth<0},返回 {@link StringUtils#EMPTY}
* 如果 {@code text.length() <= lastLenth},返回text
* 否则返回 text.substring(text.length() - lastLenth)
* @see com.feilong.lib.lang3.StringUtils#right(String, int)
*/
public static String substringLast(final String text,int lastLenth){
return StringUtils.right(text, lastLenth);
}
/**
* [截取]:去除最后几位 lastLenth
.
*
*
* 调用了 {@link java.lang.String#substring(int, int)}
*
*
* 示例:
*
*
*
*
* StringUtil.substringWithoutLast("jinxin.feilong", 5) //jinxin.fe
*
*
*
*
* @param text
* 文字
* @param lastLenth
* 最后的位数
* @return 如果 text
是null,返回 {@link StringUtils#EMPTY}
* @see java.lang.String#substring(int, int)
* @see com.feilong.lib.lang3.StringUtils#left(String, int)
*/
public static String substringWithoutLast(final String text,final int lastLenth){
return null == text ? EMPTY : text.substring(0, text.length() - lastLenth);
}
/**
* [截取]:去除最后的字符串 lastString
.
*
* 示例:
*
*
*
*
* StringUtil.substringWithoutLast(null, "222") = ""
* StringUtil.substringWithoutLast("jinxin.feilong", "ng") = "jinxin.feilo"
* StringUtil.substringWithoutLast("jinxin.feilong ", " ") = "jinxin.feilong"
*
*
*
*
* @param text
* the text
* @param lastString
* the last string
* @return 如果 text
是null,返回 {@link StringUtils#EMPTY}
* 如果 lastString
是null,返回 text.toString()
* @since 1.4.0
*/
public static String substringWithoutLast(final CharSequence text,final String lastString){
if (null == text){
return EMPTY;
}
String textString = text.toString();
if (null == lastString){
return textString;
}
return textString.endsWith(lastString) ? substringWithoutLast(textString, lastString.length()) : textString;
}
// [end]
// [start]splitToT
/**
* 将字符串 value
使用分隔符 regexSpliter
分隔成 字符串数组.
*
*
* 建议使用 {@link #tokenizeToStringArray(String, String)} 或者 {@link StringUtils#split(String)}
*
*
* @param value
* value
* @param regexSpliter
* 此处不是简单的分隔符,是正则表达式,.$|()[{^?*+\\ 有特殊的含义,因此我们使用.的时候必须进行转义,"\"转义时要写成"\\\\"
* 最终调用了 {@link java.util.regex.Pattern#split(CharSequence)}
* @return 如果 value
是null或者empty,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* @see String#split(String)
* @see String#split(String, int)
* @see StringUtils#split(String)
* @see java.util.regex.Pattern#split(CharSequence)
*/
public static String[] split(String value,String regexSpliter){
return isNullOrEmpty(value) ? EMPTY_STRING_ARRAY : value.split(regexSpliter);
}
// [end]
// [start]tokenizeToStringArray
/**
* 使用StringTokenizer分隔给定的字符串到字符串数组,去除 tokens的空格并且忽略empty tokens.
*
*
* (此方法借鉴 "org.springframework.util.StringUtils#tokenizeToStringArray").
*
*
*
* 调用了 {@link #tokenizeToStringArray(String, String, boolean, boolean)},本方法默认使用参数 trimTokens = true;
* ignoreEmptyTokens = true;
*
*
* 示例:
*
*
*
* String str = "jin.xin feilong ,jinxin;venusdrogon;jim ";
* String delimiters = ";, .";
* String[] tokenizeToStringArray = StringUtil.tokenizeToStringArray(str, delimiters);
* LOGGER.info(JsonUtil.format(tokenizeToStringArray));
*
*
* 返回:
*
*
* [
* "jin",
* "xin",
* "feilong",
* "jinxin",
* "venusdrogon",
* "jim"
* ]
*
*
*
*
* 说明:
*
*
*
* 给定的delimiters字符串支持任意数量的分隔字符characters.
* 每一个characters可以用来分隔tokens.一个delimiter分隔符常常是一个single字符;
* 如果你要使用多字符 multi-character delimiters分隔, 你可以考虑使用delimitedListToStringArray
*
*
*
* @param str
* 需要被分隔的字符串
* @param delimiters
* delimiter characters, assembled as String
* 参数中的所有字符都是分隔标记的分隔符,比如这里可以设置成 ";, " ,spring就是使用这样的字符串来分隔数组/集合的
* @return 如果 str
是null,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* 如果 str
是blank,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* @see java.util.StringTokenizer
* @see String#trim()
* @see "org.springframework.util.StringUtils#delimitedListToStringArray"
* @see "org.springframework.util.StringUtils#tokenizeToStringArray"
*
* @see #tokenizeToStringArray(String, String, boolean, boolean)
* @since 1.0.7
*/
public static String[] tokenizeToStringArray(String str,String delimiters){
boolean trimTokens = true;
boolean ignoreEmptyTokens = true;
return tokenizeToStringArray(str, delimiters, trimTokens, ignoreEmptyTokens);
}
/**
* 使用StringTokenizer分隔给定的字符串到字符串数组.
*
*
* (此方法借鉴 "org.springframework.util.StringUtils#tokenizeToStringArray").
*
*
* 说明:
*
*
*
* 给定的delimiters字符串支持任意数量的分隔字符characters.
* 每一个characters可以用来分隔tokens.一个delimiter分隔符常常是一个single字符;
* 如果你要使用多字符 multi-character delimiters分隔, 你可以考虑使用delimitedListToStringArray
*
*
*
* 关于 {@link StringTokenizer}:
*
*
*
* {@link StringTokenizer} implements {@code Enumeration
*
* @param str
* 需要被分隔的字符串
* @param delimiters
* delimiter characters, assembled as String
* 参数中的所有字符都是分隔标记的分隔符,比如这里可以设置成 ";, " ,spring就是使用这样的字符串来分隔数组/集合的
* @param trimTokens
* 是否使用 {@link String#trim()}操作token
* @param ignoreEmptyTokens
* 是否忽视空白的token,如果为true,那么token必须长度 {@code >} 0;如果为false会包含长度=0 空白的字符
* (仅仅用于那些 trim之后是empty的tokens,StringTokenizer不会考虑subsequent delimiters as token in the first place).
* @return 如果 str
是null,返回 {@link ArrayUtil#EMPTY_STRING_ARRAY}
* @see java.util.StringTokenizer
* @see String#trim()
* @see "org.springframework.util.StringUtils#delimitedListToStringArray"
* @see "org.springframework.util.StringUtils#tokenizeToStringArray"
* @since 1.0.7
*/
public static String[] tokenizeToStringArray(String str,String delimiters,boolean trimTokens,boolean ignoreEmptyTokens){
if (null == str){
return EMPTY_STRING_ARRAY;
}
List tokens = newArrayList();
StringTokenizer stringTokenizer = new StringTokenizer(str, delimiters);
while (stringTokenizer.hasMoreTokens()){
String token = stringTokenizer.nextToken();
token = trimTokens ? token.trim() : token;//去空
if (!ignoreEmptyTokens || token.length() > 0){
tokens.add(token);
}
}
return toArray(tokens, String.class);
}
// [end]
// [start]format
/**
* 将各类数据,使用{@link String#format(String, Object...)}格式化为字符串.
*
* 规则:
*
*
*
*
* -
*
*
* 对整数进行格式化:
*
*
*
* 由4部分组成:%[index$][标识][最小宽度]转换方式
*
*
*
* 此外,StringUtil.format("%03d", 1) 不能写成 StringUtil.format("%03d", "1")
*
*
*
* -
*
* 对浮点数进行格式化:
*
*
*
* %[index$][标识][最少宽度][.精度]转换方式
*
*
*
*
* - %index$开头,index从1开始取值,表示将第index个参数拿进来进行格式化.
*
*
*
*
*
*
* 转换符和标志的说明:
*
*
* 转换符
*
*
*
*
* 转换符
* 说明
* 示例
*
*
*
* %s
* 字符串类型
* "mingrisoft"
*
*
*
* %c
* 字符类型
* 'm'
*
*
*
* %b
* 布尔类型
* true
*
*
*
* %d
* 整数类型(十进制)
* 99
*
*
*
* %x
* 整数类型(十六进制)
* FF
*
*
*
* %o
* 整数类型(八进制)
* 77
*
*
*
* %f
* 浮点类型
* 99.99
*
*
*
* %a
* 十六进制浮点类型
* FF.35AE
*
*
*
* %e
* 指数类型
* 9.38e+5
*
*
*
* %g
* 通用浮点类型(f和e类型中较短的)
*
*
*
*
* %h
* 散列码
*
*
*
*
* %%
* 百分比类型
* %
*
*
*
* %n
* 换行符
*
*
*
*
* %tx
* 日期与时间类型(x代表不同的日期与时间转换符
*
*
*
*
*
* 标志
*
*
*
*
* 标志
* 说明
* 示例
* 结果
*
*
*
* +
* 为正数或者负数添加符号
* ("%+d",15)
* +15
*
*
*
* -
* 左对齐(不可以与"用0填充"同时使用)
* ("%-5d",15)
* |15 |
*
*
*
* 0
* 数字前面补0
* ("%04d", 99)
* 0099
*
*
*
* 空格
* 在整数之前添加指定数量的空格
* ("% 4d", 99)
* | 99|
*
*
*
* ,
* 以","对数字分组
* ("%,f", 9999.99)
* 9,999.990000
*
*
*
* (
* 使用括号包含负数
* ("%(f", -99.99)
* (99.990000)
*
*
*
* #
* 如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0
* ("%#x", 99)
* ("%#o", 99)
* 0x63
* 0143
*
*
*
* {@code <}
* 格式化前一个转换符所描述的参数
* ("%f和%{@code <}3.2f", 99.45)
* 99.450000和99.45
*
*
*
* $
* 被格式化的参数索引
* ("%1$d,%2$s", 99,"abc")
* 99,abc
*
*
*
*
*
* @param format
* the format
* @param args
* the args
* @return 如果 format
是null,返回 {@link StringUtils#EMPTY}
* 如果 format
包含不需要转化的字符串,这些字符串是你写什么,最终就输出什么
* 否则返回 {@link String#format(String, Object...)}
* @see java.util.Formatter
* @see String#format(String, Object...)
* @see String#format(java.util.Locale, String, Object...)
* @since JDK 1.5
*/
public static String format(String format,Object...args){
return null == format ? EMPTY : String.format(format, args);
}
// [end]
}