2010-09-23 19 views
5

que quiero dividir una cadena supresión de todos los campos nulosSeparar una cadena supresión de todos los campos nulos

Comando:

",1,2,,3,4,,".split(',') 

Resultado:

["", "1", "2", "", "3", "4", ""] 

esperado:

["1", "2", "3", "4"] 

¿Como hacer esto?


Editar

Ok. Solo para resumir todas las buenas preguntas publicadas.

Lo que quería es que el método de división (u otro método) no generara cadenas vacías. Parece que no es posible.

Por lo tanto, la solución es un proceso de dos pasos: dividir la cadena como de costumbre, y de alguna manera eliminar las cadenas vacías de la matriz resultante.

La segunda parte es exactamente this question (y su duplicate)

Así que usaría

",1,2,,3,4,,".split(',').delete_if(&:empty?) 

La solución propuesta por Nikita Rybak y por user229426 es utilizar el método de rechazo. De acuerdo con docs rechazo devuelve una nueva matriz. Mientras que el método delete_if es más eficiente ya que no quiero una copia. Usar select propuesto por Mark Byers es aún más ineficiente.

steenslag propone sustituir comas con el espacio y luego usar dividida por el espacio:

",1,2,,3,4,,".gsub(',', ' ').split(' ') 

En realidad, the documentation dice que el espacio es en realidad un espacio en blanco. Pero los resultados de "split (/ \ s /)" y "split ('')" no son lo mismo. ¿Porque eso?

Mark Byers propuso otra solución, simplemente usando expresiones regulares. Parece que esto es lo que necesito. Pero esta solución implica que debes ser un maestro de regexp. ¡Pero esta es una gran solución! Por ejemplo, si necesito espacios para ser separadores, así como cualquier símbolo que no sea alfanumérico que puedo volver a escribir esto a

",1,2, ,3 3,4 4 4,,".scan(/\w+[\s*\w*]*/) 

el resultado es:

["1", "2", "3 3", "4 4 4"] 

Pero de nuevo las expresiones regulares son muy poco intuitivo y necesitan una experiencia.

Resumen

espero esa fracción de trabajar con espacios en blanco, como si los espacios blancos eran una coma o incluso la expresión regular. Espero que no produzca cadenas vacías. Creo que esto es un error en Ruby o mi malentendido.

He aquí una pregunta de la comunidad.

+0

No es un experto en ruby, pero parece que http://stackoverflow.com/questions/3774509/eliminating-nil-lines es la misma pregunta más o menos, donde asigna la eliminación en la matriz, hable sobre el tiempo. – Novikov

+0

Sí, lo es. Gracias – Vanuan

+0

También me resulta extraño que se devuelva una cadena vacía ('" "') cuando dos valores no coinciden con la Regexp en una fila. – NotAnAmbiTurner

Respuesta

10

Hay una reject método en el Array:

",1,2,,3,4,,".split(',').reject { |s| s.empty? } 

O si lo prefiere Symbol#to_proc:

",1,2,,3,4,,".split(',').reject(&:empty?) 
+0

He encontrado una solución similar: ", 1,2,, 3,4 ,,". Split (','). Delete_if (&: empty?) – Vanuan

+0

@vanuan Yo votaría esa respuesta si la escribes @ Nikita esto podría simplificarse utilizando s.empty? en lugar de compararlo con un hilo vacío, y hacer más frío aplicando el símbolo # to_proc truco vanuan utilizado en su comentario. es decir, reescribiendo el rechazo como .reject &: empty? –

+0

Aún más corto: ", 1,2,, 3,4 ,,". Split (','). Reject (&: empty?) –

1

usted podría utilizar split seguido por select:

",1,2,,3,4,,".split(',').select{|x|!x.empty?} 

o puede utilizar un regu lar la expresión a la que usted quiere mantener en lugar de la división en el delimitador:

",1,2,,3,4,,".scan(/[^,]+/) 
0
",1,2,,3,4,,".split(/,/).reject(&:empty?) 

",1,2,,3,,,4,,".squeeze(",").sub(/^,*|,*$/,"").split(",") 
0

Cadena # dividida (patrón) se comporta como se desee cuando el patrón es un único espacio (ruby-doc).

",1,2,,3,4,,".gsub(',', ' ').split(' ') 
+0

Hm ... ¿Qué pasa si quiero que se incluyan espacios en las subcadenas? (", 1 2,, 3 4 ,,") Eso no funcionará – Vanuan

2

Con la esperanza de iluminar un poco aquí:

pero los resultados de "split (/ \ s /)" y "split (' ')" no son lo mismo. ¿Porque eso?

Si nos fijamos en la documentación para Cadena # dividida verá que split con '' es un caso especial:

If pattern is a single space, str is split on whitespace, 
with leading whitespace and runs of contiguous whitespace characters ignored. 

También mencionan:

espero que no producir cadenas vacías Creo que esto es un error en Ruby o mi malentendido.

El problema probablemente se encuentra entre el teclado y la silla. ;-)

split felizmente producirá cadenas vacías como debería, porque hay ocasiones en las que definitivamente querrías esta habilidad, y hay muchas formas fáciles de evitarla. Considere si estaba dividiendo un csv de un archivo de Excel. En cualquier lugar que vea ',,' sería una columna vacía, no una columna de la que debería deshacerse.

De todos modos, ha visto un montón de soluciones, ¡y aquí hay otra que podría mostrarle las cosas que puede hacer con ruby ​​y split!

Parece que desea dividir los datos entre comillas múltiples, así que ¿por qué no probar eso y ver qué pasa?

a = ",1,2,,3,4,,5,,,,6,,,".split(/,+/) 

Es una expresión regular bastante simple: /, +/significa uno o más comas, lo que vamos a dividir en eso.

Esto casi le da lo que quiere, excepto que también quiere ignorar el campo principal vacío.Se habrá dado cuenta de que hace caso omiso de dividir el campo vacío en el extremo porque (a partir de los documentos de cuerdas divididas #):

If the limit parameter is omitted, trailing null fields are suppressed. 

Por lo que significa que cualquiera puede usar algo que va a quitar esa nulo en la parte frontal de la matriz o solo elimina las comas iniciales. Podemos utilizar gsub para eso:

a = ",1,2,,3,4,,5,,,,6,,,".gsub(/^,+/,'') 

Si imprime eso verá que nuestro "campo" se arrastra vacío se ha ido. Así que podemos combinarlos todos en una sola línea:

a = ",1,2,,3,4,,5,,,,6,,,".gsub(/^,+/,'').split(/,+/) 

¡Y usted tiene otra solución!

Y, por cierto, esto indica otra posibilidad, que podemos simplemente limpiar nuestra cadena por completo antes de enviarlo a dividir si queremos una división simple. Lo dejo a usted para averiguar lo que éste está haciendo:

a = ",1,2,,3,4,,5,,,,6,,,".gsub(/,+/,',').gsub(/^,/,'').split(',') 

Hay un montón de maneras de hacer las cosas de rubí. Si parece que el rubí no está haciendo lo que usted quiere, entonces eche un vistazo a los documentos y descubra que probablemente funciona de la manera que lo hace por una razón (hay muchas personas que se molestarían si la división no fuera posible para escupir campos vacíos :)

Espero que ayude!

Cuestiones relacionadas