at.spardat.enterprise.util.StringSplitter Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
//@(#) $Id: StringSplitter.java 2093 2007-11-28 14:23:36Z s3460 $
package at.spardat.enterprise.util;
/**
* Extracts substrings, that are delimited by a provided delimiter-character, from a given String.
*
* hasMoreTokens may be used to check if there are more tokens left, nextToken
* returns the next String-token. Example: Suppose, you want to iterate over the
* substrings that are separated by a comma in the String 'a,b,,c', then successive calls
* to nextToken return
*
* "a", "b", "", "c"
*
* Empty strings are returned if two delimiter-characters follow up (or are at the beginning
* or at the end of the string).
*
* An optional escape-character may be specified (that's the feature that makes this class
* worth using). For example, using the percent character as escape-character and a
* comma as delimiter, then
*
* StringSplitter ss = new StringSplitter ("aa,bb,cc,%,%,", ',', '%');
*
* yields the substrings
*
* "aa", "bb", "cc", ",,"
*
*
* @author YSD
*/
public class StringSplitter {
private String str_;
private char delimiter_;
private char escape_;
/**
* Holds str_.length()-1
*/
private int last_;
private String nextToken_;
/**
* Holds the index where grabNextToken() should look for the next token.
* After an call to grabNextToken(), next_ points to the
* delimiter-character that ends a token.
*/
private int next_;
private boolean firstToken_ = true;
/**
* Constructor where no escape character is set.
*
* @param str the input string
* @param delimiter separator character
*/
public StringSplitter (String str, char delimiter) {
this (str, delimiter, (char)0);
}
/**
* Constructor.
*
* @param str the input string
* @param delimiter delimiter character
* @param escapeCharacter escape character used
*/
public StringSplitter (String str, char delimiter, char escapeCharacter) {
str_ = str;
delimiter_ = delimiter;
escape_ = escapeCharacter;
last_ = str.length()-1;
grabNextToken();
}
/**
* Returns true if nextToken() will yield a token
*/
public boolean hasMoreTokens () {
return nextToken_ != null;
}
/**
* Returns the next token. Must not be called if !hasMoreTokens().
*/
public String nextToken () {
if (nextToken_ == null) throw new RuntimeException ("no more tokens available");
String toReturn = nextToken_;
grabNextToken();
return toReturn;
}
/**
* See the next token without advancing the counter.
* @author s2877
*/
public String peekNextToken() {
return nextToken_;
}
/**
* Internal method that actually finds the next token
*/
private final void grabNextToken () {
if (next_ > last_) {
nextToken_ = null;
return;
}
/**
* if we are grabbing not the first token and next_ points
* to a delimiter_-char, this is the trailing delimiter of
* the last token; we skip that
*/
if (!firstToken_) {
if (str_.charAt(next_) == delimiter_) next_++;
} else {
firstToken_ = false;
}
int act = next_;
int start = next_;
StringBuffer token = new StringBuffer();
for (;;) {
// beyond
if (act > last_) {
// the end of the string
next_ = last_ + 1;
nextToken_ = token.toString();
break;
}
// character is a delimiter
char ch = str_.charAt (act);
if (ch == delimiter_) {
next_ = act;
nextToken_ = token.toString();
break;
} else if (ch != escape_) {
// an ordinary character
token.append(ch);
act++;
} else {
// an escape character
if (act == last_) throw new RuntimeException (str_ + " is not allowed to end with an escape character ");
char chNext = str_.charAt(act+1);
// the character to append is that following the escape char
token.append(chNext);
act += 2;
}
}
}
/**
* Returns the input string set at construction time.
*/
public String getString () {
return str_;
}
public static void main(String[] args) {
StringSplitter ss = new StringSplitter ("%,a,b", ',','%');
while (ss.hasMoreTokens()) {
String tok = ss.nextToken();
System.out.println ("tok: -->" + tok + "<--");
}
}
}