¿Cómo eliminar caracteres específicos de una cadena en Ruby?

82

Tengo varias cadenas que se ven así:

"((String1))"

Todos tienen diferentes longitudes. ¿Cómo podría eliminar los paréntesis de todas estas cadenas en un bucle?

Cristiano
fuente
2
¿Quitar paréntesis o quitar los dos primeros y los dos últimos caracteres de una cadena "aleatoria"? (¿En realidad al azar?)
Reincorporar a Monica - notmaynard
"((String1))" [2 ...- 2] # => "String1"
Restablecer a Monica - notmaynard
1
ruby-doc.org/core-1.9.3/String.html
Restablecer a Monica - notmaynard
Está pidiendo un bucle para cambiar muchas cadenas, ¿cómo se almacenan las cadenas?
hirolau
Sé cómo hacer un bucle a través de todas las cuerdas, solo quería la parte de manipulación de cuerdas, lo siento, lo dije de manera extraña
Cristiano

Respuestas:

165

Haga lo siguiente usando String#tr:

 "((String1))".tr('()', '')
 # => "String1"
Arup Rakshit
fuente
7
También hay una versión destructiva tr!que modificará una cadena en el lugar, comomy_string.tr!(')(','')
bonh
8
Tenga en cuenta que esta función no está recortando desde el principio o el final, sino un reemplazo completo en todo el texto dentro de la cadena.
Jordania
3
Engañoso e incorrecto. Tr no es una función de recorte, es una función de reemplazo. Las dos son operaciones muy diferentes.
Zane Claes
1
@ZaneClaes Sí. OP usó un término incorrecto para explicar lo que realmente quiere el OP. La respuesta ha mostrado cómo lograr el resultado.
Arup Rakshit
39

Si solo desea eliminar los dos primeros caracteres y los dos últimos, puede usar índices negativos en la cadena:

s = "((String1))"
s = s[2...-2]
p s # => "String1"

Si desea eliminar todos los paréntesis de la cadena, puede usar el método de eliminación en la clase de cadena:

s = "((String1))"
s.delete! '()'
p s #  => "String1"
jbr
fuente
8
Esto eliminará todos los paréntesis, incluso los que están en el medio de la cadena, que (aparentemente) no es lo que OP quiere. Si eso es lo que se busca, esta es la solución más elegante.
Restablecer a Monica - notmaynard
20

Usando String#gsubcon expresión regular:

"((String1))".gsub(/^\(+|\)+$/, '')
# => "String1"
"(((((( parentheses )))".gsub(/^\(+|\)+$/, '')
# => " parentheses "

Esto eliminará solo los paréntesis que rodean.

"(((((( This (is) string )))".gsub(/^\(+|\)+$/, '')
# => " This (is) string "
falsetru
fuente
2
+1 para el segundo ejemplo (elimine solo los paréntesis que lo rodean).
Bhavneet Singh Bajwa
20

Para aquellos que se encuentran con esto y buscan rendimiento, parece #deletey #trson aproximadamente iguales en velocidad y 2-4 veces más rápidos que gsub.

text = "Here is a string with / some forwa/rd slashes"
tr = Benchmark.measure { 10000.times { text.tr('/', '') } }
# tr.total => 0.01
delete = Benchmark.measure { 10000.times { text.delete('/') } }
# delete.total => 0.01
gsub = Benchmark.measure { 10000.times { text.gsub('/', '') } }
# gsub.total => 0.02 - 0.04
daino3
fuente
3
Cuatro años después ... :-) Encuentro que si subo su evaluación comparativa en un par de órdenes de magnitud (1_000_000 ejecuciones), con el mismo código que usa arriba, hago que la eliminación se ejecute un poco más rápido que tr, con la eliminación en aproximadamente una proporción de 0,92 de tr, y gsub un poco menos de 1,5x de eliminación (en realidad ~ 1,46 de eliminación y ~ 1,39 de tr). ymmv por supuesto. Esto está en Ruby 2.6.3 en un MBP 13 de 2018. ¡Gracias por comparar estos tres métodos!
likethesky
1

Aquí hay una forma aún más corta de lograr esto:

1) usando Negative character class pattern matching

irb(main)> "((String1))"[/[^()]+/]
=> "String1"

^- Coincide con cualquier cosa que NO esté en la clase de personaje. Dentro de la clase charachter, tenemos (y)

O con sustitución global "AKA: gsub" como otros han mencionado.

irb(main)> "((String1))".gsub(/[)(]/, '')
=> "String1"
zee
fuente
Tus dos respuestas tienen resultados diferentes ((a))b. El primero solo regresará a, el segundo regresaráab
Ulysse BN