Dividir en una cadena vacía devuelve una matriz de tamaño 1:
scala> "".split(',')
res1: Array[String] = Array("")
Considere que esto devuelve una matriz vacía:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Por favor explique :)
Dividir en una cadena vacía devuelve una matriz de tamaño 1:
scala> "".split(',')
res1: Array[String] = Array("")
Considere que esto devuelve una matriz vacía:
scala> ",,,,".split(',')
res2: Array[String] = Array()
Por favor explique :)
Respuestas:
Por la misma razón que
",test" split ','
y
",test," split ','
devolverá una matriz de tamaño 2. Todo lo anterior a la primera coincidencia se devuelve como primer elemento.
"".split("wtf").length
devuelve 0. Solo en JS es 1.: /
"," split ","
devuelve una matriz de 0?
Si divide una naranja por cero, tiene exactamente una pieza: la naranja.
"orange".split(',')
, pero obviamente no es relevante para dividir cadenas vacías. Si divido mi falta de naranja en cero veces, todavía no tengo naranja; ¿Representamos eso como una lista vacía de no-naranjas, una lista de exactamente una no-naranja, una lista de doce no-naranjas, o qué? No se trata de con qué terminamos, sino de cómo lo representamos.
Los métodos de división de Java y Scala operan en dos pasos como este:
",,,".split(",")
devuelve una matriz vacía.De acuerdo con esto, el resultado de "".split(",")
debería ser una matriz vacía debido al segundo paso, ¿verdad?
Debería. Desafortunadamente, este es un caso de esquina introducido artificialmente. Y eso es malo, pero al menos está documentado en java.util.regex.Pattern
, si recuerdas echarle un vistazo a la documentación:
Para n == 0, el resultado es como para n <0, excepto que no se devolverán cadenas vacías al final. (Tenga en cuenta que el caso en el que la entrada es en sí misma una cadena vacía es especial, como se describe anteriormente, y el parámetro de límite no se aplica allí).
Por lo tanto, le aconsejo que siempre pase n == -1
como el segundo parámetro (esto omitirá el paso dos anterior), a menos que sepa específicamente lo que desea lograr / esté seguro de que la cadena vacía no es algo que su programa obtendría como entrada.
Si ya está utilizando Guava en su proyecto, puede probar la clase Splitter (documentación) . Tiene una API muy rica y hace que su código sea muy fácil de entender.
Splitter.on(".").split(".a.b.c.") // "", "a", "b", "c", ""
Splitter.on(",").omitEmptyStrings().split("a,,b,,c") // "a", "b", "c"
Splitter.on(CharMatcher.anyOf(",.")).split("a,b.c") // "a", "b", "c"
Splitter.onPattern("=>?").split("a=b=>c") // "a", "b", "c"
Splitter.on(",").limit(2).split("a,b,c") // "a", "b,c"
"".split (",", n)
genera una matriz de un elemento para n en (-1, 0, 1) con Oracle JDK 8. Sería bueno obtener una lista de tokens no vacíos solamente - supongo que puede ser necesaria una expresión regular completa (algo así como "[^,\\s]+[^,]*[^,\\s]*"
).
Dividir una cadena vacía devuelve la cadena vacía como primer elemento. Si no se encuentra un delimitador en la cadena de destino, obtendrá una matriz de tamaño 1 que contiene la cadena original, incluso si está vacía.
",".split(",")
devuelve una matriz vacía.
En todos los lenguajes de programación, sé que una cadena en blanco sigue siendo una cadena válida. Entonces, hacer una división usando cualquier delimitador siempre devolverá una matriz de un solo elemento donde ese elemento es la Cadena en blanco. Si fuera una cadena nula (no en blanco), entonces sería un problema diferente.
Este split
comportamiento se hereda de Java, para bien o para mal ...
Scala no anula la definición de la String
primitiva.
Tenga en cuenta que puede usar el limit
argumento para modificar el comportamiento :
El parámetro de límite controla el número de veces que se aplica el patrón y, por lo tanto, afecta la longitud de la matriz resultante. Si el límite n es mayor que cero, entonces el patrón se aplicará como máximo n - 1 veces, la longitud de la matriz no será mayor que n, y la última entrada de la matriz contendrá todas las entradas más allá del último delimitador coincidente. Si n no es positivo, el patrón se aplicará tantas veces como sea posible y la matriz puede tener cualquier longitud. Si n es cero, el patrón se aplicará tantas veces como sea posible, la matriz puede tener cualquier longitud y las cadenas vacías finales se descartarán.
es decir, puede configurar el limit=-1
para obtener el comportamiento de (¿todos?) otros idiomas:
@ ",a,,b,,".split(",")
res1: Array[String] = Array("", "a", "", "b")
@ ",a,,b,,".split(",", -1) // limit=-1
res2: Array[String] = Array("", "a", "", "b", "", "")
Parece ser bien sabido que el comportamiento de Java es bastante confuso, pero:
El comportamiento anterior se puede observar desde al menos Java 5 hasta Java 8.
Se intentó cambiar el comportamiento para devolver una matriz vacía al dividir una cadena vacía en JDK-6559590 . Sin embargo, pronto se revirtió en JDK-8028321 cuando causa regresión en varios lugares. El cambio nunca llega a la versión inicial de Java 8.
Nota: El método de división no estaba en Java desde el principio (no está en 1.0.2 ) pero en realidad está ahí desde al menos 1.4 (por ejemplo, ver JSR51 alrededor de 2002). Sigo investigando ...
Lo que no está claro es por qué Java eligió esto en primer lugar (mi sospecha es que originalmente fue un descuido / error en un "caso marginal"), pero ahora irrevocablemente integrado en el lenguaje y así permanece .
"".split(",")
todavía devuelve una matriz de un solo elemento como [""]
.
La cadena vacía no tiene un estado especial al dividir una cadena. Puedes utilizar:
Some(str)
.filter(_ != "")
.map(_.split(","))
.getOrElse(Array())