que tienen una cadena:¿Cómo elimino espacios repetidos en una cadena?
"foo (2 plazas) bar (3 plazas) baaar (6 plazas) fooo"
¿Cómo se quita espacios repetitivos en ella por lo que no debería haber ningún más de un espacio entre dos palabras?
que tienen una cadena:¿Cómo elimino espacios repetidos en una cadena?
"foo (2 plazas) bar (3 plazas) baaar (6 plazas) fooo"
¿Cómo se quita espacios repetitivos en ella por lo que no debería haber ningún más de un espacio entre dos palabras?
>> str = "foo bar bar baaar"
=> "foo bar bar baaar"
>> str.split.join(" ")
=> "foo bar bar baaar"
>>
+1 por una forma divertida de hacerlo, pero -1 por una sugerencia ineficiente en comparación con otra, alternativas más apropiadas. – Phrogz
@Phrogz. ¿ineficiente? cualquier punto de referencia para probar eso? – kurumi
ver http://stackoverflow.com/questions/4907068/remove-repeated-spaces-in-ruby-string/4911709#4911709 :) – zetetic
Utilice una expresión regular para que coincida con la repetición de espacios en blanco (\s+)
y reemplácela por un espacio.
"foo bar foobar".gsub(/\s+/, ' ')
=> "foo bar foobar"
Esto coincide con todos los espacios en blanco, ya que sólo desea reemplazar espacios, utilizar / +/
en lugar de /\s+/
.
"foo bar \nfoobar".gsub(/ +/, ' ')
=> "foo bar \nfoobar"
Simplemente use gsub
y regexp. Por ejemplo:
str = "foo bar bar baaar"
str.gsub(/\s+/, " ")
volverá nueva cadena o puede modificar directamente mediante STR gsub!
.
BTW. Regexp es muy útil: hay muchos recursos en internet para probar tus propios regexpes, prueba rubular.com por ejemplo.
Para complementar las otras respuestas, tenga en cuenta que tanto Activesupport y Facets proporcionan String#squish (tenga en cuenta que también elimina las nuevas líneas dentro de la cadena):
>> "foo bar bar baaar".squish
=> "foo bar bar baaar"
Tenga en cuenta que '# squish' también elimina las líneas nuevas. – moveson
irb> "asd asd asd asd".squeeze(" ")
=> "asd asd asd asd"
No es cierto ... puede "dañar" la cadena ... ejemplo sería "50b2a6cc6d5a2fb4e7000006" donde obtendrá "50b2a6c6d5a2fb4e706". – xpepermint
@xpepermint, tenga en cuenta el parámetro '" "'. – Nakilon
ow ... lo extrañé, lo siento :) – xpepermint
Qué método se desempeña mejor?
$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]
$ cat squeeze.rb
require 'benchmark'
include Benchmark
string = "foo bar bar baaar"
n = 1_000_000
bm(6) do |x|
x.report("gsub ") { n.times { string.gsub(/\s+/, " ") } }
x.report("squeeze ") { n.times { string.squeeze } }
x.report("split/join") { n.times { string.split.join(" ") } }
end
$ ruby squeeze.rb
user system total real
gsub 4.970000 0.020000 4.990000 ( 5.624229)
squeeze 0.600000 0.000000 0.600000 ( 0.677733)
split/join 2.950000 0.020000 2.970000 ( 3.243022)
este punto de referencia no es del todo correcto. 'string.squeeze =>" barra de la barra de la barra "' que está eliminando cualquier carácter repetido. Cambiar a 'string.squeeze ('')' da como resultado unos tiempos que lo sitúan sólidamente entre 'gsub' y' split.join ('') ', siendo el último el más rápido. Ver mi respuesta para el código de punto de referencia actualizado. –
referencia Actualización de la respuesta de @ Zetetic:
require 'benchmark'
include Benchmark
string = "foo bar bar baaar"
n = 1_000_000
bm(12) do |x|
x.report("gsub ") { n.times { string.gsub(/\s+/, " ") } }
x.report("squeeze(' ')") { n.times { string.squeeze(' ') } }
x.report("split/join") { n.times { string.split.join(" ") } }
end
lo que resulta en estos valores cuando se ejecuta en el escritorio después de correr dos veces:
ruby test.rb; ruby test.rb
user system total real
gsub 6.060000 0.000000 6.060000 ( 6.061435)
squeeze(' ') 4.200000 0.010000 4.210000 ( 4.201619)
split/join 3.620000 0.000000 3.620000 ( 3.614499)
user system total real
gsub 6.020000 0.000000 6.020000 ( 6.023391)
squeeze(' ') 4.150000 0.010000 4.160000 ( 4.153204)
split/join 3.590000 0.000000 3.590000 ( 3.587590)
La cuestión es que squeeze
elimina cualquier carácter repetido, lo que da como resultado una cadena de salida diferente y no cumple con las necesidades del OP. squeeze(' ')
cumple con las necesidades, pero ralentiza su funcionamiento.
string.squeeze
=> "fo bar bar bar"
Estaba pensando en cómo el split.join
podría ser más rápido y que no parecía que mantendría en grandes cadenas, por lo que ajustar el punto de referencia para ver qué efecto tendrían cadenas largas:
require 'benchmark'
include Benchmark
string = (["foo bar bar baaar"] * 10_000).join
puts "String length: #{ string.length } characters"
n = 100
bm(12) do |x|
x.report("gsub ") { n.times { string.gsub(/\s+/, " ") } }
x.report("squeeze(' ')") { n.times { string.squeeze(' ') } }
x.report("split/join") { n.times { string.split.join(" ") } }
end
ruby test.rb ; ruby test.rb
String length: 250000 characters
user system total real
gsub 2.570000 0.010000 2.580000 ( 2.576149)
squeeze(' ') 0.140000 0.000000 0.140000 ( 0.150298)
split/join 1.400000 0.010000 1.410000 ( 1.396078)
String length: 250000 characters
user system total real
gsub 2.570000 0.010000 2.580000 ( 2.573802)
squeeze(' ') 0.140000 0.000000 0.140000 ( 0.150384)
split/join 1.400000 0.010000 1.410000 ( 1.397748)
Por lo tanto, las líneas largas hacen una gran diferencia.
Si usted hace uso de gsub continuación gsub/\ s {2} /, ' ') es un poco más rápido.
Realmente no. Aquí hay una versión del índice de referencia para probar simplemente que la afirmación:
require 'benchmark'
include Benchmark
string = "foo bar bar baaar"
puts string.gsub(/\s+/, " ")
puts string.gsub(/\s{2,}/, ' ')
puts string.gsub(/\s\s+/, " ")
string = (["foo bar bar baaar"] * 10_000).join
puts "String length: #{ string.length } characters"
n = 100
bm(18) do |x|
x.report("gsub") { n.times { string.gsub(/\s+/, " ") } }
x.report('gsub/\s{2,}/, "")') { n.times { string.gsub(/\s{2,}/, ' ') } }
x.report("gsub2") { n.times { string.gsub(/\s\s+/, " ") } }
end
# >> foo bar bar baaar
# >> foo bar bar baaar
# >> foo bar bar baaar
# >> String length: 250000 characters
# >> user system total real
# >> gsub 1.380000 0.010000 1.390000 ( 1.381276)
# >> gsub/\s{2,}/, "") 1.590000 0.000000 1.590000 ( 1.609292)
# >> gsub2 1.050000 0.010000 1.060000 ( 1.051005)
Si quieres velocidad, utilice gsub2
. squeeze(' ')
seguirá ejecutando círculos alrededor de una implementación de gsub
.
+1 buena captura señor – zetetic
@zetetic, creo que Benchmark es una herramienta esencial. No puedo contar cuántas veces he asumido que algo sería la manera más rápida de hacer una tarea en particular, y si un punto de referencia me hubiera demostrado que estaba equivocado. Nunca había considerado 'split/join' el más rápido, aunque lo he usado en aplicaciones para este propósito. –
@zetetic, verifique los resultados de las pruebas adicionales. –
Ya sabes, este tipo de pregunta se responde fácilmente mediante la revisión de todos los métodos de cadena. Recomiendo familiarizarse con la documentación de los métodos String, Array y Enumerable. –
En caso de que no sepa por dónde empezar, visite [http://ruby-doc.org/](http://ruby-doc.org/) y luego haga clic en [API principal] (http://ruby-doc.org/core) y luego haga clic en la clase String en la columna superior central. – Phrogz
Para la defensa del OP, eliminar los espacios se puede lograr de varias maneras, no todas son las más intuitivas, especialmente cuando se observan los resultados del índice de referencia. –