StringSplitter nur für nicht quotierte Tokens

nrg

Top Contributor
Hallo Zusammen,

ich benutze zz einen StringSplitter in meinen Projekt. Dieser soll nur Splitten, wenn es aktuell keinen Quote gibt.

Bsp ( Delimiter ; ):
Code:
test;test2;"test3;test4" -> test     test2     test3;test4

natürlich will ich auch ermöglichen, dass ganz normales Hochkommas im String genutzt werden können. Da dachte ich mir escaped man diese einfach:

Bsp ( Delimiter ; ):
Code:
test;test2;test\"3;test4 -> test     test2     test"3     test4

so habe ich es implementiert:
Java:
	public static String[] splitOnlyNonQuoted( String str, char delim ) {
		StringBuilder sb = new StringBuilder();
		List<String> tokens = new ArrayList<String>();
		boolean isDoubleQuoted = false, isSingleQuoted = false, isEscaped = false;
		for ( int i = 0; i < str.length(); i++ ) {
			char c = str.charAt( i );
			if ( isEscaped )
				isEscaped = false;
			if ( c == '\\' && ( i + 1 < str.length() && str.charAt( i + 1 ) != '\\' ) ) {
				isEscaped = true;
				if ( ++i >= str.length() )
					throw new IllegalArgumentException( "Ungültiger SplitString: '" + str + "'. Backslashes müssen escaped werden" );
				c = str.charAt( i );
			}
			if ( c == '"' && !isEscaped && !isSingleQuoted ) {
				if ( isDoubleQuoted ) {
					isDoubleQuoted = false;
				} else {
					isDoubleQuoted = true;
				}
			} else if ( c == '\'' && !isEscaped && !isDoubleQuoted ) {
				if ( isSingleQuoted ) {
					isSingleQuoted = false;
				} else {
					isSingleQuoted = true;
				}
			} else if ( c == delim && !isDoubleQuoted && !isSingleQuoted ) {
				tokens.add( sb.toString() );
				sb = new StringBuilder();
			} else {
				sb.append( c );
			}
		}
		tokens.add( sb.toString() );
		String[] ret = new String[tokens.size()];
		return tokens.toArray( ret );
	}

aber iwie bereitet mir der Algo ein wenig Kopfschmerzen. Ich frag mich, ob das nicht ein weniger einfacher umzusetzen ist. Hat jemand einen Tipp, wie man es besser machen könnte oder sind meine Kopfschmerzen unbegründet? 😉
 
if ( isEscaped )
isEscaped = false;

->
isEscaped = false;


sb = new StringBuilder();
->
sb.setLength(0);


if ( isSingleQuoted ) {
isSingleQuoted = false;
} else {
isSingleQuoted = true;
}
->
isSingleQuoted = !isSingleQuoted;
 
if ( isEscaped )
isEscaped = false;

->
isEscaped = false;


sb = new StringBuilder();
->
sb.setLength(0);


if ( isSingleQuoted ) {
isSingleQuoted = false;
} else {
isSingleQuoted = true;
}
->
isSingleQuoted = !isSingleQuoted;

k danke. zum ersten dachte ich, dass eine zuweißung in jeden loop aufwändiger ist als eine abfrage in jedem und nur ab und zu (für jeden escape) eine zuweißung. die anderen klingen einleuchtend. vorallen sb.setLength(0) werd ich wohl an mehr stellen einbauen können. danke dir
 

Neue Themen


Zurück
Oben