📄 stringpairtokenizer.java
字号:
/*------------------------------------------------------------------------------Name: StringPairTokenizer.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE file------------------------------------------------------------------------------*/package org.xmlBlaster.util;import java.util.Iterator;import java.util.List;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.StringTokenizer;//import java.util.regex.Matcher;//import java.util.regex.Pattern;import org.xmlBlaster.util.qos.ClientProperty;/** * StringPairTokenizer is a utility class used to parse a string giving * back a map containing pairs of key/value strings. * <br /> * The method parseLine respects quoted '"' tokens and ignores the separator inside the quotes. * * @author <a href="mailto:michele@laghi.eu">Michele Laghi</a> * @author <a href="mailto:mr@marcelruff.info">Marcel Ruff</a> */public class StringPairTokenizer { public static final char DEFAULT_QUOTE_CHARACTER = '"'; public static final char ESCAPE_CHARACTER = '\\'; public static final char DEFAULT_SEPARATOR = ','; public static final char DEFAULT_INNER_SEPARATOR = '='; /** * @see #parseLine(String[] nextLines, char separator, char quotechar, boolean trimEmpty) */ public static String[] parseLine(String nextLine) { return parseLine(nextLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER, true); } /** * @see #parseLine(String[] nextLines, char separator, char quotechar, boolean trimEmpty) */ public static String[] parseLine(String nextLine, char separator) { return parseLine(nextLine, separator, DEFAULT_QUOTE_CHARACTER, true); } /** * @see #parseLine(String[] nextLines, char separator, char quotechar, boolean trimEmpty, boolean) */ public static String[] parseLine(String nextLine, char separator, char quotechar, boolean trimEmpty) { return parseLine(nextLine, separator, quotechar, trimEmpty, false); } /** * @see #parseLine(String[] nextLines, char separator, char quotechar, boolean trimEmpty, boolean) */ public static String[] parseLine(String nextLine, char separator, char quotechar, boolean trimEmpty, boolean preserveInsideQuoteChar) { if (nextLine == null || nextLine.length()==0) return new String[0]; String[] nextLines = new String[1]; nextLines[0] = nextLine; return parseLine(nextLines, separator, quotechar, trimEmpty, preserveInsideQuoteChar); } /** * Split string to tokens and respect quotes. * *<pre> * /node/heron/client/\"joe/the/great\" * * 'node' * 'heron' * 'client' * 'joe/the/great' *</pre> * * Thanks to http://opencsv.sourceforge.net/ (under Apache license) * * @param nextLines An array of lines, followup lines will only be parsed if an open quotechar exists * @param separator Defaults to StringPairTokenizer.DEFAULT_SEPARATOR=',' * @param quotechar Defaults to StringPairTokenizer.DEFAULT_QUOTE_CHARACTER='"' * @param trimEmpty if true removes silently empy tokens * @param preserveInsideQuoteChar true: Preserve the inside quotes of "bla, bla, "blu blu", bli" * @return Never null, if nextLines is null or empty we return an empty array */ public static String[] parseLine(String[] nextLines, char separator, char quotechar, boolean trimEmpty, boolean preserveInsideQuoteChar) { List tokensOnThisLine = new ArrayList(); StringBuffer sb = new StringBuffer(); boolean inQuotes = false; int jj=0; String nextLine = nextLines[jj]; do { if (sb.length() > 0) { // continuing a quoted section, reappend newline sb.append("\n"); jj++; if (jj >= nextLines.length) break; nextLine = nextLines[jj]; } for (int i = 0; i < nextLine.length(); i++) { char c = nextLine.charAt(i); if (c == quotechar) { inQuotes = !inQuotes; if (preserveInsideQuoteChar && i>0 && i<(nextLine.length()-1)) sb.append(c); } else if (c == separator && !inQuotes) { String tmp = sb.toString(); if (trimEmpty && tmp.trim().length() == 0) { ; } else { tokensOnThisLine.add(tmp); } sb = new StringBuffer(); // start work on next token } else { sb.append(c); } } } while (inQuotes); String tmp = sb.toString(); if (trimEmpty && tmp.trim().length() == 0) { ; } else { tokensOnThisLine.add(tmp); } return (String[]) tokensOnThisLine.toArray(new String[0]); } /** * Split string to tokens and respect quotes, then parse key/values into the returned map. * * If a value is missing then a null object will be put into the map as value. * The map returns pairs 'String,ClientProperty' if wantClientProperties is true, * otherwise it returns 'String,String' pairs. * * @param nextLines e.g. * <code>String[] nextLines = { "org.xmlBlaster.protocol.soap.SoapDriver,\"classpath=xerces.jar:soap.jar,all\",MAXSIZE=100,a=10,\"b=", "20\",c=30" };</code> * Followup lines will only be parsed if an open quotechar exists * @param innerSeparator is for example StringPairTokenizer.DEFAULT_INNER_SEPARATOR "=" or " " * @param wantClientProperties if set to <code>true</code> returns pairs 'String,ClientProperty', returns 'String,String' pairs otherwise. * @param trimValue If true the value is trimmed (removed white spaces in front and back) * @return Never null, * <pre> * classpath=xerces.jar:soap.jar,all * org.xmlBlaster.protocol.soap.SoapDriver=null * MAXSIZE=100 * a=10 * c=30 * b=20 * </pre> * @see #parseLine(String[] nextLines, char separator, char quotechar, boolean trimEmpty) */ public static Map parseLine(String[] nextLines, char separator, char quotechar, char innerSeparator, boolean trimEmpty, boolean wantClientProperties, boolean trimValue) { String[] toks = parseLine(nextLines, separator, quotechar, trimEmpty, false); Map ret = new HashMap(); for (int i=0; i<toks.length; i++) { String tok = toks[i]; int pos = tok.indexOf(innerSeparator); if (pos < 0) { ret.put(tok.trim(), null); } else { String key = tok.substring(0,pos).trim(); String value = tok.substring(pos+1); if (trimValue) value = value.trim(); if (wantClientProperties) ret.put(key, new ClientProperty(key, null, null, value)); else ret.put(key, value); } } return ret; } /** * @see #parseLine(String[] nextLines, char separator, char quotechar, char innerSeparator, boolean trimEmpty, boolean wantClientProperties, boolean trimEmpty) */ public static Map parseLine(String nextLine, char separator, char quotechar, char innerSeparator, boolean trimEmpty, boolean wantClientProperties) { if (nextLine == null || nextLine.length()==0) return new HashMap(); String[] nextLines = new String[1]; nextLines[0] = nextLine; return parseLine(nextLines, separator, quotechar, innerSeparator, trimEmpty, wantClientProperties, true); } /** * Parsing for example >org.xmlBlaster.protocol.soap.SoapDriver,"classpath=xerces.jar:soap.jar,all",MAXSIZE=100,a=10<. * <p> * Using default separator chars and quote chars: * <code>return parseLine(nextLines, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER, DEFAULT_INNER_SEPARATOR, true, false, false);</code> * @see #parseLine(String[] nextLines, char separator, char quotechar, char innerSeparator, boolean trimEmpty, boolean wantClientProperties, boolean trimEmpty) */ public static Map parseLineToProperties(String nextLine) { if (nextLine == null || nextLine.length()==0) return new HashMap(); String[] nextLines = new String[1]; nextLines[0] = nextLine; return parseLine(nextLines, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER, DEFAULT_INNER_SEPARATOR, true, false, false); } /* * Split a string (similar to StringTokenizer) but respect escape quotes. * <br /> *<pre> * String[] arr = split("now,DATE,\"dd,MM,yyyy\"", ",", "\""); * now * DATE * "dd,MM,yyyy" *</pre> *<pre> * ,node,\"h,,eron\",client,\"X,\,[],X,X\" * 'node' * '"h,,eron"' * 'client' * '"X,,[],X,X"' *</pre> * * Caution: I don't think this is very stable * We should change to something like http://opencsv.sourceforge.net/ * * @see http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm#FileFormat * @see http://www.jguru.com/faq/view.jsp?EID=809266 public static String[] split(String field, String separator, String quotechar) { // This can't handle leading ',' see hack below
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -