¿Cuál es la forma canónica de recortar una cadena en Ruby sin crear una nueva cadena?


Esto es lo que tengo ahora - que parece demasiado detallado para el trabajo que está haciendo.

@title        = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil?

Asumir tokens es una matriz obtenida dividiendo una línea CSV. ahora las funciones como tira! chomp! et. all devuelve nil si la cadena no fue modificada

"abc".strip!    # => nil
" abc ".strip!  # => "abc"

¿Cuál es la forma Ruby de decir trim it si contiene espacios adicionales iniciales o finales sin crear copias?

Se pone más feo si quiero hacer tokens[Title].chomp!.strip!

 166
Author: Gishu, 2009-06-16

9 answers

, supongo que lo que quieres es:

@title = tokens[Title]
@title.strip!

El #strip! method devolverá nil si no eliminó nada, y la variable en sí si fue eliminada.

De acuerdo con los estándares Ruby, un método sufijo con un signo de exclamación cambia la variable en su lugar.

Espero que esto ayude.

Actualización: Esta es la salida de irb para demostrar:

>> @title = "abc"
=> "abc"
>> @title.strip!
=> nil
>> @title
=> "abc"
>> @title = " abc "
=> " abc "
>> @title.strip!
=> "abc"
>> @title
=> "abc"
 243
Author: Igor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-24 05:38:11

Por cierto, ahora ruby ya soporta solo strip sin "!".

Comparar:

p "abc".strip! == " abc ".strip!  # false, because "abc".strip! will return nil
p "abc".strip == " abc ".strip    # true

También es imposible strip sin duplicados. Ver fuentes en cadena.c:

static VALUE
rb_str_strip(VALUE str)
{
    str = rb_str_dup(str);
    rb_str_strip_bang(str);
    return str;
}

ruby 1.9. 3p0 (2011-10-30) [i386-mingw32]

Actualización 1: Como veo ahora was fue creado en 1999 año (ver rev #372 en SVN):

Actualización2: strip! no creará duplicados - ambos en 1.9.x, 2.versiones x y trunk.

 47
Author: gaRex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-29 13:50:51

No es necesario tanto el strip como el chomp, ya que el strip también eliminará los retornos de carro finales, a menos que haya cambiado el separador de registros predeterminado y eso es lo que está masticando.

La respuesta de Olly ya tiene la forma canónica de hacer esto en Ruby, aunque si te encuentras haciendo esto mucho siempre podrías definir un método para ello:

def strip_or_self!(str)
  str.strip! || str
end

Dando:

@title = strip_or_self!(tokens[Title]) if tokens[Title]

También tenga en cuenta que la instrucción if evitará que @title se asigne si el token es nil, que resultará en que mantenga su valor anterior. Si quiere o no le importa @title que siempre se le asigne, puede mover el cheque al método y reducir aún más la duplicación:

def strip_or_self!(str)
  str.strip! || str if str
end

Como alternativa, si te sientes aventurero puedes definir un método en la propia cadena:

class String
  def strip_or_self!
    strip! || self
  end
end

Dando uno de:

@title = tokens[Title].strip_or_self! if tokens[Title]

@title = tokens[Title] && tokens[Title].strip_or_self!
 8
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-16 13:17:36

Si estás usando Ruby on Rails hay un squish

> @title = " abc "
 => " abc " 

> @title.squish
 => "abc"
> @title
 => " abc "

> @title.squish!
 => "abc"
> @title
 => "abc" 

Si estás usando solo Ruby, quieres usar strip

Aquí yace el gotcha.. en su caso que desea utilizar la tira sin la explosión !

Mientras tira! ciertamente devuelve nil si no hubo acción todavía actualiza la variable así que tira! no se puede usar en línea. Si desea utilizar tira en línea se puede utilizar la versión sin la explosión !

Tira! usando varias líneas enfoque

> tokens["Title"] = " abc "
 => " abc "
> tokens["Title"].strip!
 => "abc"
> @title = tokens["Title"]
 => "abc"

Strip single line approach... SU RESPUESTA

> tokens["Title"] = " abc "
 => " abc "
> @title = tokens["Title"].strip if tokens["Title"].present?
 => "abc"
 7
Author: gateblues,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-27 21:56:43

Creo que su ejemplo es un enfoque sensato, aunque podría simplificarlo ligeramente como:

@title = tokens[Title].strip! || tokens[Title] if tokens[Title]

Alternativa podría ponerlo en dos líneas:

@title = tokens[Title] || ''
@title.strip!
 2
Author: Olly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-16 11:33:02

Si quieres usar otro método después de necesitar algo como esto:

( str.strip || str ).split(',')

De esta manera puedes desnudarte y seguir haciendo algo después:)

 2
Author: Diogo Neves - Mangaru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-01 12:25:55

A mi manera:

> (@title = " abc ").strip!
 => "abc" 
> @title
 => "abc" 
 1
Author: Hauleth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-08 10:51:45

Si tiene ruby 1.9 o activesupport, puede hacer simplemente

@title = tokens[Title].try :tap, &:strip!

Esto es realmente genial, ya que aprovecha el método :try y el método :tap, que son las construcciones funcionales más poderosas en ruby, en mi opinión.

Una forma aún más linda, pasando funciones como símbolos en conjunto:

@title = tokens[Title].send :try, :tap, &:strip!
 1
Author: rewritten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-15 20:39:56
@title = tokens[Title].strip! || tokens[Title]

Es completamente posible que no esté entendiendo el tema, pero ¿no haría esto lo que necesitas?

" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"
 -1
Author: Brent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-30 04:48:04