2010-04-28 9 views
5

Necesito poder dividir una cadena de entrada por comas, punto y coma o espacio en blanco (o una combinación de los tres). También me gustaría tratar múltiples delimitadores consecutivos en la entrada como un único delimitador. Esto es lo que tengo hasta ahora:String.split() - haciendo coincidir la cadena vacía principal antes del primer delimitador?

String regex = "[,;\\s]+";  
return input.split(regex); 

Esto funciona, a excepción de cuando la cadena de entrada comienza con uno de los caracteres delimitadores, en cuyo caso el primer elemento de la matriz resultado es una cadena vacía. No quiero que mi resultado tenga cadenas vacías, por lo que algo como ",,,, ZERO;;; ONE, DOS ;," devuelve solo una matriz de tres elementos que contiene las cadenas en mayúsculas.

¿Hay una forma mejor de hacerlo que eliminando los caracteres iniciales que coinciden con mi reg-ex antes de invocar String.split?

¡Gracias de antemano!

+0

No se publica como respuesta, ya que no recuerdo la API de expresiones regulares de Java, pero podría simplemente buscar cadenas de no delimitadores en lugar de dividir en delimitadores, por ejemplo usando una expresión regular como '[^,; \ s] +'. –

+0

Pregunta aparentemente idéntica, más reciente pero con mejor respuesta aceptada: https://stackoverflow.com/questions/9389503/how-to-prevent-java-lang-string-split-from-creating-a-leading-empty-string –

Respuesta

3

Si por "mejor" quiere decir un mayor rendimiento, entonces puede intentar crear una expresión regular que coincida con lo que quiere hacer coincidir y utilizando Matcher.find en un bucle y sacar las coincidencias a medida que las encuentre. Esto ahorra la modificación de la cadena primero. Pero mídelo para ver cuál es más rápido para sus datos.

Si con "mejor" quiere decir más simple, entonces no, no creo que haya una manera más sencilla que la que sugirió: eliminar los separadores iniciales antes de aplicar la división.

6

No, no lo hay. Sólo se puede ignorar delimitadores una desventaja de proporcionar 0 como segundo parámetro para dividir de String) (:

return input.split(regex, 0); 

sino de dirigir delimitadores, que tendrá que quitar primero:

return input.replaceFirst("^"+regex, "").split(regex, 0); 
+0

Un parámetro negativo? 'Si n es cero, entonces el patrón se aplicará tantas veces como sea posible, la matriz puede tener cualquier longitud, y las cadenas vacías posteriores se descartarán. Desde http://java.sun.com/javase/6/docs/ api/java/lang/String.html # split% 28java.lang.String,% 20int% 29 –

+0

Vaya, sí, quise decir 0. ¡Gracias! –

+0

+1 por arreglarlo :) –

1

También es posible usar potencialmente StringTokenizer para construir la lista, dependiendo de lo que hay que hacer con él:

StringTokenizer st = new StringTokenizer(",,,ZERO;,ONE TWO", ",; ", false); 
while(st.hasMoreTokens()) { 
    String str = st.nextToken(); 
    //add to list, process, etc... 
} 

A modo de advertencia, sin embargo, tendrá que definir cada espacio en blanco potencial por separado en el segundo argumento para el constructor.

2

Casi todas las instalaciones de división integradas en el JDK se rompen de una forma u otra. Usted sería mejor usar una clase de terceros, tales como Splitter, que es a la vez flexible y correcto en la forma en que maneja símbolos vacíos y espacios en blanco:

Splitter.on(CharMatcher.anyOf(";,").or(CharMatcher.WHITESPACE)) 
    .omitEmptyStrings() 
    .split(",,,ZERO;,ONE TWO"); 

producirán un Iterable < String> contiene "CERO", "ONE", "TWO"

Cuestiones relacionadas