com.sunchenbin.store.feilong.core.lang.StringUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.sunchenbin.store.feilong.core.lang.StringUtil.java

Source

/*
 * 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.sunchenbin.store.feilong.core.lang;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sunchenbin.store.feilong.core.bean.ConvertUtil;
import com.sunchenbin.store.feilong.core.bean.IntrospectorUtil;
import com.sunchenbin.store.feilong.core.tools.slf4j.Slf4jUtil;
import com.sunchenbin.store.feilong.core.util.Validator;

/**
 * {@link String},? ,?,format,?16?.
 * 
 * <h3>(split)</h3>
 * 
 * <blockquote>
 * <ul>
 * <li>{@link #split(String, String)}</li>
 * </ul>
 * </blockquote>
 * 
 * <h3>(tokenize)</h3> <blockquote>
 * <ul>
 * <li>{@link #tokenizeToStringArray(String, String)}</li>
 * <li>{@link #tokenizeToStringArray(String, String, boolean, boolean)}</li>
 * </ul>
 * 
 * <p>
 * ,split  ? {@link Pattern#split(CharSequence)} (?, $|()[{^?*+\\ ???), {@link StringTokenizer} ,
 * StringTokenizer<br>
 * ,?,{@link StringTokenizer}
 * </p>
 * </blockquote>
 * 
 * <h3>{@link String#String(byte[] )}  {@link String#String(byte[], Charset)} </h3>
 * 
 * <blockquote>
 * <p>
 * {@link String#String(byte[] )} {@link String#String(byte[], Charset)};  {@link Charset#defaultCharset()}, ? ISO-8859-1,
 * ?? {@link java.lang.StringCoding#decode(byte[], int, int)}
 * </p>
 * </blockquote>
 * 
 * <h3>{@link StringBuffer} && {@link StringBuilder} && {@link String} </h3>
 * 
 * <blockquote>
 * <ul>
 * <li>{@link StringBuffer} ??</li>
 * <li>{@link StringBuilder} ???</li>
 * <li>{@link String} ?</li>
 * <li> {@link StringBuffer} {@code >} {@link String}</li>
 * <li> {@link StringBuilder} {@code >} {@link StringBuffer}</li>
 * </ul>
 * </blockquote>
 *
 * @author feilong
 * @version 1.4.0 201583 ?3:06:20
 * @see "org.springframework.util.StringUtils#tokenizeToStringArray(String, String)"
 * @see "org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#MULTI_VALUE_ATTRIBUTE_DELIMITERS"
 * @see java.util.StringTokenizer
 * @see org.apache.commons.lang3.StringUtils
 * @since 1.4.0
 */
public final class StringUtil {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(StringUtil.class);

    /** 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 <code>String</code> by decoding the specified array of bytes using the given charset.
     *
     * @param bytes
     *            The bytes to be decoded into characters, may be {@code null}
     * @param charsetType
     *            {@link CharsetType}
     * @return A new <code>String</code> decoded from the specified array of bytes using the given charset,
     *         or {@code null} if the input byte array was {@code null}.
     * @see String#String(byte[], String)
     * @see org.apache.commons.lang3.StringUtils#toString(byte[], String)
     * @see org.apache.commons.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] search

    /**
     * ? (<code>target</code>) ( <code>source</code>).
     * 
     * <pre>
     *  StringUtil.searchTimes("xin", "xin")
     *  return  1
     *  
     * StringUtil.searchTimes("xiiiin", "ii")
     *  return  2
     * 
     * </pre>
     *
     * @param source
     *            ?
     * @param target
     *            ?
     * @return count of target string in source
     * @see org.apache.commons.lang3.StringUtils#countMatches(CharSequence, CharSequence)
     * @since 1.0.2
     */
    public static int searchTimes(final CharSequence source, final CharSequence target) {
        return org.apache.commons.lang3.StringUtils.countMatches(source, target);
    }

    // [end]
    /**
     * ???.
     * 
     * <pre>
     * String text = &quot;jinxin.feilong&quot;;
     * LOGGER.info(StringUtil.addDoubleQuotes(text));
     * 
     * :  "jinxin.feilong"
     * </pre>
     * 
     * @param text
     *            ?
     * @return "\"" + text + "\""
     */
    public static String addDoubleQuotes(String text) {
        return "\"" + text + "\"";
    }

    /**
     * ???.
     * 
     * <p>
     * Example 1: jinxin ---> Jinxin
     * </p>
     * 
     * <pre>
     * StringUtils.capitalize(null)  = null
     * StringUtils.capitalize(&quot;&quot;)    = &quot;&quot;
     * StringUtils.capitalize(&quot;cat&quot;) = &quot;Cat&quot;
     * StringUtils.capitalize(&quot;cAt&quot;) = &quot;CAt&quot;
     * </pre>
     * 
     * @param word
     *            ??
     * @return ???
     * @see org.apache.commons.lang3.StringUtils#swapCase(String)
     * @see org.apache.commons.lang3.StringUtils#capitalize(String)
     */
    public static String firstCharToUpperCase(String word) {
        return StringUtils.capitalize(word);
    }

    /**
     * ????.
     * 
     * <p>
     * Example 1: Jinxin ---> jinxin
     * </p>
     * 
     * <pre>
     * StringUtils.capitalize(null)  = null
     * StringUtils.capitalize(&quot;&quot;)    = &quot;&quot;
     * StringUtils.capitalize(&quot;Jinxin&quot;) = &quot;jinxin&quot;
     * StringUtils.capitalize(&quot;CAt&quot;) = &quot;cAt&quot;
     * </pre>
     * 
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * <ol>
     * <li> {@link IntrospectorUtil#decapitalize(String)} .</li>
     * <li>?,?????, ? {@link org.apache.commons.lang3.text.WordUtils#uncapitalize(String, char...)}</li>
     * </ol>
     * </blockquote>
     * 
     * @param word
     *            ??
     * @return ????
     * @see org.apache.commons.lang3.StringUtils#uncapitalize(String)
     */
    public static String firstCharToLowerCase(String word) {
        return StringUtils.uncapitalize(word);
    }

    // [start]Contain

    /**
     *  <code>seq</code> ??  <code>searchSeq</code>.
     * 
     * @param seq
     *             jinxin,the CharSequence to check, may be null
     * @param searchSeq
     *            ? in,the CharSequence to find, may be null
     * @return ?true,text null false
     * @see org.apache.commons.lang3.StringUtils#contains(CharSequence, CharSequence)
     */
    public static boolean contains(final CharSequence seq, final CharSequence searchSeq) {
        return org.apache.commons.lang3.StringUtils.contains(seq, searchSeq);
    }

    /**
     *  ? ??.
     * 
     * <pre>
     * StringUtil.containsIgnoreCase(null, &quot;&quot;)  return false
     * StringUtil.containsIgnoreCase(text, null) return false
     * StringUtil.containsIgnoreCase(text, &quot;&quot;) return true
     * StringUtil.containsIgnoreCase(text, &quot;feilong&quot;) return true
     * StringUtil.containsIgnoreCase(text, &quot;feilong1&quot;)  return false
     * StringUtil.containsIgnoreCase(text, &quot;feiLong&quot;)  return true
     * 
     * </pre>
     * 
     * @param str
     *            the CharSequence to check, may be null
     * @param searchStr
     *            the CharSequence to find, may be null
     * @return true if the CharSequence contains the search CharSequence irrespective of
     *         case or false if not or {@code null} string input
     */
    public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr) {
        return org.apache.commons.lang3.StringUtils.containsIgnoreCase(str, searchStr);
    }

    // [end] 

    // [start]replace

    // ********************************replace************************************************
    /**
     *  replacement ????..
     * 
     * @param content
     *            ??
     * @param regex
     *            ???
     * @param replacement
     *            ????
     * @return String,?,""
     */
    public static String replaceAll(Object content, String regex, String replacement) {
        if (null == content) {
            return StringUtils.EMPTY;
        }
        return content.toString().replaceAll(regex, replacement);
    }

    /**
     * ????????.
     * 
     * <p>
     * ??,, "b" ? "aaa"  "aa" ? "ba" ? "ab".
     * </p>
     * 
     * <pre>
     * ?replacement
     * </pre>
     * 
     * @param content
     *            
     * @param target
     *            ?? char ?
     * @param replacement
     *            char ??
     * @return ????
     */
    public static String replace(Object content, String target, Object replacement) {
        if (null == content) {
            return StringUtils.EMPTY;
        }
        // ??null
        String useReplacement = Validator.isNullOrEmpty(replacement) ? StringUtils.EMPTY : replacement.toString();
        return content.toString().replace(target, useReplacement);
    }

    /**
     * The following example demonstrates this:
     * 
     * <pre>
     * Map valuesMap = HashMap();
     * valuesMap.put(&quot;animal&quot;, &quot;quick brown fox&quot;);
     * valuesMap.put(&quot;target&quot;, &quot;lazy dog&quot;);
     * 
     * StrSubstitutor sub = new StrSubstitutor(valuesMap);
     * String templateString = &quot;The ${animal} jumped over the ${target}.&quot;;
     * String resolvedString = sub.replace(templateString);
     * </pre>
     * 
     * yielding:
     * 
     * <pre>
     *      The quick brown fox jumped over the lazy dog.
     * </pre>
     *
     * @param <V>
     *            the value type
     * @param templateString
     *            the template string
     * @param valuesMap
     *            the values map
     * @return the string
     * @see org.apache.commons.lang3.text.StrSubstitutor#replace(String)
     * @since 1.1.1
     */
    public static <V> String replace(String templateString, Map<String, V> valuesMap) {
        StrSubstitutor strSubstitutor = new StrSubstitutor(valuesMap);
        return strSubstitutor.replace(templateString);
    }

    // [end]

    // [start]startsWith

    /**
     * ??..
     * 
     * @param value
     *            value
     * @param prefix
     *            ?
     * @return ????, true? false.??,?, String  equals(Object) , true.
     */
    public static boolean startsWith(Object value, String prefix) {
        return ConvertUtil.toString(value).startsWith(prefix);
    }

    // [end]
    /**
     * ?,(???).
     * 
     * <pre>
     * {@code
     * stringAddInt("002",2); return 004
     * stringAddInt("000002",1200); return 001202
     * }
     * </pre>
     * 
     * @param str
     *            ?  002
     * @param i
     *            
     * @return ?,(???).
     * @see NumberUtil#toString(Number, String)
     */
    public static String stringAddInt(String str, int i) {
        int length = str.length();
        String pattern = "";
        for (int j = 0; j < length; ++j) {
            pattern += "0";
        }
        return NumberUtil.toString(Integer.parseInt(str) + i, pattern);
    }

    // [start]substring

    // ********************************substring************************************************
    /**
     * [?](beginIndex),.
     * 
     * <p>
     * Gets a substring from the specified String avoiding exceptions.
     * </p>
     *
     * <p>
     *  beginIndex ,??,?,? {@link #substringLast(String, int)}
     * </p>
     *
     * <p>
     * A {@code null} String will return {@code null}. An empty ("") String will return "".
     * </p>
     *
     * <pre>
     * 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"
     * </pre>
     * 
     * <pre>
     * substring("jinxin.feilong",6) 
     * return .feilong
     * </pre>
     * 
     * @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 substring from start position, {@code null} if null String input
     * @see org.apache.commons.lang3.StringUtils#substring(String, int)
     * @see #substringLast(String, int)
     */
    public static String substring(final String text, final int beginIndex) {
        return org.apache.commons.lang3.StringUtils.substring(text, beginIndex);
    }

    /**
     * [?]?(startIndex),?(length).
     * 
     * <pre>
     * StringUtil.substring("jinxin.feilong", 6, 2)
     * 
     * renturn .f
     * </pre>
     *
     * @param textString
     *            ?
     * @param startIndex
     *            ?,0
     * @param length
     *             {@code >=1} 1 ? <br>
     *            ,??
     * @return the string
     * @see org.apache.commons.lang3.StringUtils#substring(String, int, int)
     */
    public static String substring(final String textString, int startIndex, int length) {
        return org.apache.commons.lang3.StringUtils.substring(textString, startIndex, startIndex + length);
    }

    /**
     * [?]:?(?)??.
     * 
     * <p>
     * {@link #substring(String, String, int)},  shift=0 ?? beginString.
     * </p>
     * 
     * <pre>
     * substring(&quot;jinxin.feilong&quot;,&quot;.&quot;)======&gt;&quot;.feilong&quot;
     * </pre>
     * 
     * @param text
     *            text
     * @param beginString
     *            beginString?
     * @return {@link #substring(String, String, int)},  shift=0 ?? beginString.
     * @see #substring(String, String, int)
     */
    public static String substring(final String text, String beginString) {
        return substring(text, beginString, 0);
    }

    /**
     * [?]:?(?)??,shift?????.
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * <ul>
     * <li>substring(&quot;jinxin.feilong&quot;,&quot;.&quot;,0)======&gt;&quot;.feilong&quot;</li>
     * <li>substring(&quot;jinxin.feilong&quot;,&quot;.&quot;,1)======&gt;&quot;feilong&quot;</li>
     * </ul>
     * </blockquote>
     *
     * @param text
     *            text
     * @param beginString
     *            beginString
     * @param shift
     *            ??,??,0??
     * @return <ul>
     *         <li>if isNullOrEmpty(text),return null</li>
     *         <li>if isNullOrEmpty(beginString),return null</li>
     *         <li>if text.indexOf(beginString)==-1,return null</li>
     *         <li>{@code  beginIndex + shift > text.length()},return null</li>
     *         <li>else,return text.substring(beginIndex + shift)</li>
     *         </ul>
     * @see org.apache.commons.lang3.StringUtils#substringAfter(String, String)
     */
    public static String substring(final String text, String beginString, int shift) {
        if (Validator.isNullOrEmpty(text)) {
            return StringUtils.EMPTY;
        }

        if (Validator.isNullOrEmpty(beginString)) {
            return StringUtils.EMPTY;
        }
        //****************************************************
        int beginIndex = text.indexOf(beginString);
        if (beginIndex == -1) {// ?
            return StringUtils.EMPTY;
        }
        //****************************************************
        int startIndex = beginIndex + shift;
        int textLength = text.length();

        if (startIndex < 0) {
            String pattern = "beginIndex+shift<0,beginIndex:{},shift:{},text:{},text.length:{}";
            throw new IllegalArgumentException(
                    Slf4jUtil.formatMessage(pattern, beginIndex, shift, text, textLength));
        }

        if (startIndex > textLength) {
            LOGGER.warn("beginIndex+shift>text.length(),beginIndex:{},shift:{},text:{},text.length:{}", beginIndex,
                    shift, text, textLength);
            return StringUtils.EMPTY;
        }
        // 0
        return text.substring(startIndex);
    }

    /**
     * [?]:?.
     * 
     * <p>
     * ?startString,???endString.
     * </p>
     * 
     * @param text
     *            
     * @param startString
     *            ,null?
     * @param endString
     *            ?
     * @return
     *         <ul>
     *         <li>Validator.isNullOrEmpty(text),return null;</li>
     *         <li>Validator.isNullOrEmpty(startString),return text.substring(0, text.indexOf(endString))</li>
     *         </ul>
     * @see org.apache.commons.lang3.StringUtils#substringBetween(String, String, String)
     */
    public static String substring(final String text, final String startString, final String endString) {
        if (Validator.isNullOrEmpty(text)) {
            return StringUtils.EMPTY;
        }
        if (Validator.isNullOrEmpty(startString)) {
            return text.substring(0, text.indexOf(endString));
        }
        int beginIndex = text.indexOf(startString);
        int endIndex = text.indexOf(endString);
        return text.substring(beginIndex, endIndex);
    }

    /**
     * [?]:???.
     * 
     * <p>
     *  {@link String#substring(int)}
     * </p>
     * 
     * <pre>
     * Example 1:
     * {@code
     * StringUtil.substringLast("jinxin.feilong", 5)---->ilong
     * }
     * </pre>
     * 
     * @param text
     *            
     * @param lastLenth
     *            ??
     * @return ??
     * @see java.lang.String#substring(int)
     */
    public static String substringLast(final String text, int lastLenth) {
        return text.substring(text.length() - lastLenth);
    }

    /**
     * [?]:??.
     * 
     * <p>
     *  {@link java.lang.String#substring(int, int)}
     * </p>
     * 
     * <pre>
     * Example 1:
     * {@code
     * StringUtil.substringWithoutLast("jinxin.feilong", 5)---->jinxin.fe
     * }
     * </pre>
     * 
     * @param text
     *            
     * @param lastLenth
     *            ??
     * @return ??,text,""
     * @see java.lang.String#substring(int, int)
     * @see org.apache.commons.lang3.StringUtils#left(String, int)
     */
    public static String substringWithoutLast(final String text, final int lastLenth) {
        if (Validator.isNullOrEmpty(text)) {
            return StringUtils.EMPTY;
        }
        return text.substring(0, text.length() - lastLenth);
    }

    /**
     * [?]:?(<code>text</code> <code>lastString</code>).
     *
     * @param text
     *            the text
     * @param lastString
     *            the last string
     * @return the string
     * @since 1.4.0
     */
    public static String substringWithoutLast(final CharSequence text, final String lastString) {
        if (Validator.isNullOrEmpty(text)) {
            return StringUtils.EMPTY;
        }

        //?,??nullempty,?,,,????
        String returnValue = text.toString();
        if (Validator.isNullOrEmpty(lastString)) {
            return returnValue;
        }

        if (returnValue.endsWith(lastString)) {
            //?
            return substringWithoutLast(returnValue, lastString.length());
        }
        return returnValue;
    }

    // [end]

    // [start]toBytes

    // ********************************************************************************
    /**
     * ??byte.
     * 
     * @param value
     *            
     * @return byte
     * @since 1.3.0
     */
    public static byte[] getBytes(String value) {
        return value.getBytes();
    }

    /**
     * ??byte.
     * 
     * @param value
     *            
     * @param charsetName
     *            ?? charset ??, utf-8, {@link CharsetType}
     * @return  byte 
     * @see String#getBytes(String)
     * @see CharsetType
     * @since 1.3.0
     */
    public static byte[] getBytes(String value, String charsetName) {
        try {
            return value.getBytes(charsetName);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error(e.getClass().getName(), e);
        }
        return ArrayUtils.EMPTY_BYTE_ARRAY;
    }

    // [end]

    // [start]splitToT

    /**
     * ? .
     * 
     * <h3>?</h3>
     * 
     * <blockquote>
     * <p>
     * ????, .$|()[{^?*+\\ ??,.,<br>
     * <span style="color:red">"\"??"\\\\"</span> <br>
     *  {@link java.util.regex.Pattern#split(CharSequence)}
     * </p>
     * </blockquote>
     * 
     *  {@link #tokenizeToStringArray(String, String)}  {@link StringUtils#split(String)}
     * 
     * @param value
     *            value
     * @param regexSpliter
     *            ,????, .$|()[{^?*+\\ ??,.,<br>
     *            <span style="color:red">"\"??"\\\\"</span> <br>
     *             {@link java.util.regex.Pattern#split(CharSequence)}
     * @return value null,null
     * @see String#split(String)
     * @see String#split(String, int)
     * @see java.util.regex.Pattern#split(CharSequence)
     * @see StringUtils#split(String)
     * @see #tokenizeToStringArray(String, String)
     */
    public static String[] split(String value, String regexSpliter) {
        if (Validator.isNullOrEmpty(value)) {
            return ArrayUtils.EMPTY_STRING_ARRAY;
        }
        return value.split(regexSpliter);
    }

    // [end]

    // [start]tokenizeToStringArray

    /**
     * ( {@link "org.springframework.util.StringUtils#tokenizeToStringArray"}).
     * 
     * <p>
     * Tokenize the given String into a String array via a StringTokenizer. <br>
     * Trims tokens and omits empty tokens.
     * </p>
     * 
     * <p>
     * The given delimiters string is supposed to consist of any number of delimiter characters. Each of those characters can be used to
     * separate tokens. A delimiter is always a single character; for multi-character delimiters, consider using
     * {@code delimitedListToStringArray}
     * 
     * @param str
     *            the String to tokenize
     * @param delimiters
     *            the delimiter characters, assembled as String<br>
     *            ?,?? ";, " ,spring?/?
     * @return an array of the tokens
     * @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 = true;
        boolean ignoreEmptyTokens = true;
        return tokenizeToStringArray(str, delimiters, trimTokens, ignoreEmptyTokens);
    }

    /**
     * ( {@link "org.springframework.util.StringUtils#tokenizeToStringArray"}).
     * <p>
     * Tokenize the given String into a String array via a StringTokenizer.
     * </p>
     * <p>
     * The given delimiters string is supposed to consist of any number of delimiter characters. <br>
     * Each of those characters can be used to separate tokens. <br>
     * A delimiter is always a single character; <br>
     * for multi-character delimiters, consider using {@code delimitedListToStringArray}
     * 
     * @param str
     *            the String to tokenize
     * @param delimiters
     *            the delimiter characters, assembled as String<br>
     *            ?,?? ";, " ,spring?/?
     * @param trimTokens
     *            ? {@link String#trim()}?token
     * @param ignoreEmptyTokens
     *            ?token,true,token {@code >} 0;false?=0 <br>
     *            omit empty tokens from the result array
     *            (only applies to tokens that are empty after trimming; StringTokenizer
     *            will not consider subsequent delimiters as token in the first place).
     * @return an array of the tokens ({@code null} if the input String
     *         was {@code null})
     * @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 ArrayUtils.EMPTY_STRING_ARRAY;
        }
        //StringTokenizer implements Enumeration<Object>
        // Enumeration?,   hasMoreTokens nextToken
        //Enumeration?  hasMoreElements nextElement   hasMoreTokens nextToken
        StringTokenizer st = new StringTokenizer(str, delimiters);
        List<String> tokens = new ArrayList<String>();
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            if (trimTokens) {
                token = token.trim();
            }
            if (!ignoreEmptyTokens || token.length() > 0) {
                tokens.add(token);
            }
        }
        return ConvertUtil.toArray(tokens, String.class);
    }

    // [end]
    // [start]format

    /**
     * ?.
     * 
     * <ul>
     * <li>StringUtil.format("%03d", 1)?? StringUtil.format("%03d", "1")</li>
     * </ul>
     * 
     * <p>
     * %index$,index1?,index???.<br>
     * ?:?4?:%[index$][][?]??<br>
     * ?:%[index$][][][.]??<br>
     * ?? ?<br>
     * </p>
     * 
     * <h3>?</h3>
     * 
     * <blockquote>
     * <table border="1" cellspacing="0" cellpadding="4">
     * <tr style="background-color:#ccccff">
     * <th align="left">?</th>
     * <th align="left"></th>
     * <th align="left"></th>
     * </tr>
     * <tr valign="top">
     * <td>%s</td>
     * <td></td>
     * <td>"mingrisoft"</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%c</td>
     * <td></td>
     * <td>'m'</td>
     * </tr>
     * <tr valign="top">
     * <td>%b</td>
     * <td></td>
     * <td>true</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%d</td>
     * <td>??</td>
     * <td>99</td>
     * </tr>
     * <tr valign="top">
     * <td>%x</td>
     * <td>??</td>
     * <td>FF</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%o</td>
     * <td></td>
     * <td>77</td>
     * </tr>
     * <tr valign="top">
     * <td>%f</td>
     * <td></td>
     * <td>99.99</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%a</td>
     * <td>??</td>
     * <td>FF.35AE</td>
     * </tr>
     * <tr valign="top">
     * <td>%e</td>
     * <td></td>
     * <td>9.38e+5</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%g</td>
     * <td>fe</td>
     * <td></td>
     * </tr>
     * <tr valign="top">
     * <td>%h</td>
     * <td>?</td>
     * <td></td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%%</td>
     * <td></td>
     * <td></td>
     * </tr>
     * <tr valign="top">
     * <td>%n</td>
     * <td>?</td>
     * <td></td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>%tx</td>
     * <td>x???</td>
     * <td></td>
     * </tr>
     * </table>
     * </blockquote>
     * 
     * 
     * <h3></h3>
     * 
     * <blockquote>
     * <table border="1" cellspacing="0" cellpadding="4">
     * <tr style="background-color:#ccccff">
     * <th align="left"></th>
     * <th align="left"></th>
     * <th align="left"></th>
     * <th align="left"></th>
     * </tr>
     * <tr valign="top">
     * <td>+</td>
     * <td>?</td>
     * <td>("%+d",15)</td>
     * <td>+15</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>-</td>
     * <td>?(??0??)</td>
     * <td>("%-5d",15)</td>
     * <td>|15 |</td>
     * </tr>
     * <tr valign="top">
     * <td>0</td>
     * <td>??0</td>
     * <td>("%04d", 99)</td>
     * <td>0099</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td></td>
     * <td>??</td>
     * <td>("% 4d", 99)</td>
     * <td>| 99|</td>
     * </tr>
     * <tr valign="top">
     * <td>,</td>
     * <td>,?</td>
     * <td>("%,f", 9999.99)</td>
     * <td>9,999.990000</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>(</td>
     * <td>??</td>
     * <td>("%(f", -99.99)</td>
     * <td>(99.990000)</td>
     * </tr>
     * <tr valign="top">
     * <td>#</td>
     * <td>??,1680x0</td>
     * <td>("%#x", 99) <br>
     * ("%#o", 99)</td>
     * <td>0x63<br>
     * 0143</td>
     * </tr>
     * <tr valign="top" style="background-color:#eeeeff">
     * <td>{@code <}</td>
     * <td>??????</td>
     * <td>("%f%{@code <}3.2f", 99.45)</td>
     * <td>99.45000099.45</td>
     * </tr>
     * <tr valign="top">
     * <td>$</td>
     * <td>??</td>
     * <td>("%1$d,%2$s", 99,"abc")</td>
     * <td>99,abc</td>
     * </tr>
     * </table>
     * </blockquote>
     * 
     * @param format
     *            the format
     * @param args
     *            the args
     * @return A formatted string
     * @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 String.format(format, args);
    }

    // [end]

}