⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strings.java

📁 ZK 基础介绍 功能操作 模块 结合数据库操作
💻 JAVA
字号:
/* Strings.java{{IS_NOTE	Purpose: String utilities and constants	Description:	History:	 2001/4/17, Tom M. Yeh: Created.}}IS_NOTECopyright (C) 2001 Potix Corporation. All Rights Reserved.{{IS_RIGHT	This program is distributed under GPL Version 2.0 in the hope that	it will be useful, but WITHOUT ANY WARRANTY.}}IS_RIGHT*/package org.zkoss.lang;import java.util.Date;import java.util.Locale;import java.util.TimeZone;import java.lang.reflect.InvocationTargetException;import java.text.ParseException;import java.math.BigDecimal;import java.math.BigInteger;import org.zkoss.mesg.MCommon;import org.zkoss.text.DateFormats;import org.zkoss.util.Locales;import org.zkoss.util.IllegalSyntaxException;/** * String utilties and constants * * @author tomyeh */public class Strings {	/**	 * Returns true if the string is null or empty.	 */	public static final boolean isEmpty(String s) {		return s == null || s.length() == 0;	}	/**	 * Returns true if the string is null or empty or pure blank.	 */	public static final boolean isBlank(String s) {		return s == null || s.trim().length() == 0;	}	/** Returns an encoded string buffer, faster and shorter than	 * Integer.toHexString. It uses numbers and lower-case leters only.	 * Thus it is a valid variable name if prefix with an alphabet.	 * At least one character is generated.	 *	 * <p>It works even in system that is case-insensitive, such as IE.	 *	 * <p>It is useful to generate a string to represent a number.	 */	public static final StringBuffer encode(StringBuffer sb, int val) {		if (val < 0) {			sb.append('z');			val = -val;		}		do {			int v = val & 31;			if (v < 10) {				sb.append((char)('0' + v));			} else {				sb.append((char)(v + ((int)'a' - 10)));			}		} while ((val >>>= 5) != 0);		return sb;	}	/** Returns an encoded string buffer, faster and shorter than	 * Long.toHexString. It uses numbers and lower-case letters only.	 * Thus it is a valid variable name if prefix with an alphabet.	 * At least one character is generated.	 *	 * <p>It works even in system that is case-insensitive, such as IE.	 *	 * <p>It is useful to generate a string to represent a number.	 */	public static final StringBuffer encode(StringBuffer sb, long val) {		if (val < 0) {			sb.append('z');			val = -val;		}		do {			int v = ((int)val) & 31;			if (v < 10) {				sb.append((char)('0' + v));			} else {				sb.append((char)(v + ((int)'a' - 10)));			}		} while ((val >>>= 5) != 0);		return sb;	}	/** Returns an encoded string, faster and shorter than	 * Long.toHexString.	 */	public static final String encode(int val) {		return encode(new StringBuffer(12), val).toString();	}	/** Returns an encoded string, faster and shorter than	 * Long.toHexString.	 */	public static final String encode(long val) {		return encode(new StringBuffer(20), val).toString();	}	/**	 * Returns the index that is one of delimiters, or the length if none	 * of delimiter is found.	 *	 * <p>Unlike String.indexOf(String, int), this method returns the first	 * occurrence of <i>any</i> character in the delimiters.	 *	 * <p>This method is optimized to use String.indexOf(char, int)	 * if it found the length of dilimiter is 1.	 *	 * @param src the source string to search	 * @param from the index to start the search from	 * @param delimiters the set of characters to search for	 *	 * @return the index that is one of delimiters.	 * If return >= src.length(), it means no such delimiters	 * @see #lastAnyOf	 */	public static final int anyOf(String src, String delimiters, int from) {		switch (delimiters.length()) {		case 0:			return src.length();		case 1:			final int j = src.indexOf(delimiters.charAt(0), from);			return j >= 0 ? j: src.length();		}		for (int len = src.length();		from < len && delimiters.indexOf(src.charAt(from)) < 0; ++from)			;		return from;	}	/**	 * The backward version of {@link #anyOf}.	 *	 * <p>This method is optimized to use String.indexOf(char, int)	 * if it found the length of dilimiter is 1.	 *	 * @return the previous index that is one of delimiter.	 * If it is negative, it means no delimiter in front of	 * <code>from</code>	 * @see #anyOf	 */	public static final int lastAnyOf(String src, String delimiters, int from) {		switch (delimiters.length()) {		case 0:			return -1;		case 1:			return src.lastIndexOf(delimiters.charAt(0), from);		}		int len = src.length();		if (from >= len)			from = len - 1;		for (; from >= 0 && delimiters.indexOf(src.charAt(from)) < 0; --from)			;		return from;	}	/**	 * Returns the next index after skipping whitespaces.	 */	public static final int skipWhitespaces(CharSequence src, int from) {		for (final int len = src.length();		from < len && Character.isWhitespace(src.charAt(from)); ++from)			;		return from;	}	/**	 * The backward version of {@link #skipWhitespaces}.	 *	 * @return the next index that is not a whitespace.	 * If it is negative, it means no whitespace in front of it.	 */	public static final int skipWhitespacesBackward(CharSequence src, int from) {		final int len = src.length();		if (from >= len)			from = len - 1;		for (; from >= 0 && Character.isWhitespace(src.charAt(from)); --from)			;		return from;	}	/** Returns the next whitespace.	 */	public static final int nextWhitespace(CharSequence src, int from) {		for (final int len = src.length();		from < len && !Character.isWhitespace(src.charAt(from)); ++from)			;		return from;	}	/** Escapes (aka, quote) the special characters with backslash.	 * It prefix a backslash to any characters specfied in the specials	 * argument.	 *	 * <p>Note: specials usually contains '\\'.		 *	 * <p>For example, {@link org.zkoss.util.Maps#parse} will un-quote	 * backspace. Thus, if you want to preserve backslash, you have	 * invoke escape(s, "\\") before calling Maps.parse().	 *	 * @param s the string to process. If null, null is returned.	 * @param specials a string of characters that shall be escaped/quoted	 * @see #unescape	 */	public static final String escape(String s, String specials) {		if (s == null)			return null;		StringBuffer sb = null;		int j = 0;		for (int k, len = s.length(); (k = anyOf(s, specials, j)) < len;) {			if (sb == null)				sb = new StringBuffer(len + 4);						char cc = s.charAt(k);			switch (cc) {			case '\n': cc = 'n'; break;			case '\t': cc = 't'; break;			case '\r': cc = 'r'; break;			case '\f': cc = 'f'; break;			}			sb.append(s.substring(j, k)).append('\\').append(cc);			j = k + 1;		}		if (sb == null)			return s; //nothing changed		return sb.append(s.substring(j)).toString();	}	/** Escapes (aka. quote) the special characters with backslash	 * and appends it the specified string buffer.	 */	public static final StringBuffer	appendEscape(StringBuffer sb, String s, String specials) {		if (s == null)			return sb;		for (int j = 0, len = s.length();;) {			final int k = Strings.anyOf(s, specials, j);			if (k >= len)				return sb.append(s.substring(j));			char cc = s.charAt(k);			switch (cc) {			case '\n': cc = 'n'; break;			case '\t': cc = 't'; break;			case '\r': cc = 'r'; break;			case '\f': cc = 'f'; break;			}			sb.append(s.substring(j, k)).append('\\').append(cc);			j = k + 1;		}	}	/** Un-escape the quoted string.	 * @see #escape	 * @see #appendEscape	 */	public static final String unescape(String s) {		if (s == null)			return null;		StringBuffer sb = null;		int j = 0;		for (int k; (k = s.indexOf('\\', j)) >= 0;) {			if (sb == null)				sb = new StringBuffer(s.length());			char cc = s.charAt(k + 1);			switch (cc) {			case 'n': cc = '\n'; break;			case 't': cc = '\t'; break;			case 'r': cc = '\r'; break;			case 'f': cc = '\f'; break;			}			sb.append(s.substring(j, k)).append(cc);			j = k + 2;		}		if (sb == null)			return s; //nothing changed		return sb.append(s.substring(j)).toString();	}	/**	 * Returns the substring from the <code>from</code> index up to the	 * <code>until</code> character or end-of-string.	 * Unlike String.subsring, it converts \f, \n, \t and \r. It doesn't	 * handle u and x yet.	 *	 * @return the result (never null). Result.next is the position of	 * the <code>until</code> character if found, or	 * a number larger than length() if no such character.	 */	public static final Result substring(String src, int from, char until) {		return substring(src, from, until, true);	}	/**	 * Returns the substring from the <code>from</code> index up to the	 * <code>until</code> character or end-of-string.	 *	 * @param escBackslash whether to treat '\\' specially (as escape char)	 * It doesn't handle u and x yet.	 * @return the result (never null). Result.next is the position of	 * the <code>until</code> character if found, or	 * a number larger than length() if no such character.	 * You can tell which case it is by examining {@link Result#separator}.	 */	public static final	Result substring(String src, int from, char until, boolean escBackslash) {		final int len = src.length();		final StringBuffer sb = new StringBuffer(len);		for (boolean quoted = false; from < len; ++from) {			char cc = src.charAt(from);			if (quoted) {				quoted = false;				switch (cc) {				case 'f': cc = '\f'; break;				case 'n': cc = '\n'; break;				case 'r': cc = '\r'; break;				case 't': cc = '\t'; break;				}			} else if (cc == until) {				break;			} else if (escBackslash && cc == '\\') {				quoted = true;				continue; //skip it			}			sb.append(cc);		}		return new Result(from, sb.toString(), from < len ? until: (char)0);	}	/** Returns the next token with unescape.	 * <ul>	 * <li>It trims whitespaces before and after the token.</li>	 * <li>It handles both '\'' and '"'. All characters between them are	 * considered as a token.</li>	 * <li>If nothing found before end-of-string, null is returned</li>	 * </ul>	 *	 * If a separator is found, it is returned in	 * {@link Strings.Result#separator}.	 *	 * @exception IllegalSyntaxException if the quoted string is unclosed.	 */	public static final 	Result nextToken(String src, int from, char[] separators)	throws IllegalSyntaxException {		return nextToken(src, from, separators, true, true);	}		/** Returns the next token with unescape option.	 *	 * <ul>	 * <li>It trims whitespaces before and after the token.</li>	 * <li>If quotAsToken is true, all characters between quotations	 * ('\'' or '"') are considered as a token.</li>	 * <li>Consider '\\' as the escape char if escBackslash is true.</li>	 * <li>If nothing found before end-of-string, null is returned</li>	 * </ul>	 *	 * If a separator is found, it is returned in	 * {@link Strings.Result#separator}.	 *	 * @param escBackslash whether to treat '\\' specially (as escape char)	 * It doesn't handle u and x yet.	 * @param quotAsToken whether to treat characters inside '\'' or '"'	 * as a token	 * @exception IllegalSyntaxException if the quoted string is unclosed.	 */	public static final Result nextToken(String src, int from,	char[] separators, boolean escBackslash, boolean quotAsToken)	throws IllegalSyntaxException {		final int len = src.length();		from = skipWhitespaces(src, from);		if (from >= len)			return null; //end-of-string		//1. handle quoted		final char cc = src.charAt(from);		if (quotAsToken && (cc == '\'' || cc == '"')) {			final Result res = substring(src, from + 1, cc, escBackslash);			if (res.separator != cc)				throw new IllegalSyntaxException(MCommon.QUOTE_UNMATCHED, src);			res.next = skipWhitespaces(src, res.next + 1);			if (res.next < len && isSeparator(src.charAt(res.next), separators))				++res.next;			return res;		}		//2. handle not-quoted		final int j = nextSeparator(src, from, separators,			escBackslash, false, quotAsToken);		int next = j;		if (j < len) {			if (quotAsToken) {				final char c = src.charAt(j);				if (c != '\'' && c != '"')					++next;			} else {				++next;			}		}		if (j == from) //nothing but separator			return new Result(next, "", src.charAt(j));		int k = 1 + skipWhitespacesBackward(src, j - 1);		return new Result(next,			k > from ? escBackslash ?				unescape(src.substring(from, k)) : src.substring(from, k): "",			j < len ? src.charAt(j): (char)0);			//if the token is nothing but spaces, k < from	}		/** Returns the next seperator index in the src string.	 *	 * @param escQuot whether to escape characters inside quotations	 * ('\'' or '"'). In other words, ignore separators inside quotations	 * @param quotAsSeparator whether to consider quotations as one of	 * the separators	 * @since 2.4.0	 */	public static int nextSeparator(String src, int from, char[] separators,	boolean escBackslash, boolean escQuot, boolean quotAsSeparator) {		boolean esc = false;		char quot = (char)0;		for (final int len = src.length(); from < len; ++from) {			if (esc) {				esc = false;				continue;			}			final char cc = src.charAt(from);			if (escBackslash && cc == '\\') {				esc = true;			} else if (quot != (char)0) {				if (cc == quot)					quot = (char)0;			} else if (escQuot && (cc == '\'' || cc == '"')) {				quot = cc;			} else if ((quotAsSeparator && (cc == '\'' || cc == '"'))			|| isSeparator(cc, separators)) {				return from;			}		}		return from;	}	private static final boolean isSeparator(char cc, char[] separators) {		for (int j = 0; j < separators.length; ++j) {			if (cc == separators[j]			|| (separators[j] == ' ' && Character.isWhitespace(cc)))				return true;		}		return false;	}		/** The result of {@link #substring}.	 */	public static class Result {		/** The next index. */		public int next;		/** The converted string. */		public String token;		/** The separator found. If no separator but end-of-line found,		 * ((char)0) is returned.		 */		public char separator;		protected Result(int next, String token, char separator) {			this.next = next;			this.token = token;			this.separator = separator;		}		protected Result(int next, char separator) {			this.next = next;			this.separator = separator;		}		//-- Object --//		public String toString() {			return "[next="+next+", token="+token+" separator="+separator+']';		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -