213 votes

Quelle est la manière canonique de couper une chaîne de caractères en Ruby sans créer une nouvelle chaîne ?

Voici ce que j'ai maintenant - qui semble trop verbeux pour le travail qu'il fait.

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

Supposons que tokens soit un tableau obtenu en divisant une ligne CSV. maintenant les fonctions comme strip ! chomp ! et. toutes retournent nil si la chaîne n'a pas été modifiée

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

Quelle est la façon Ruby de dire de le couper s'il contient des espaces supplémentaires en tête ou en queue sans créer de copies ?

Ça devient plus moche si je veux faire tokens[Title].chomp!.strip!

310voto

Igor Points 1963

Je suppose que ce que vous voulez est :

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

El #strip! retournera nil s'il n'a rien enlevé, et la variable elle-même si elle a été enlevée.

Selon les normes Ruby, une méthode suffixée par un point d'exclamation modifie la variable en place.

J'espère que cela vous aidera.

Mise à jour : C'est la sortie de irb à démontrer :

>> @title = "abc"
=> "abc"
>> @title.strip!
=> nil
>> @title
=> "abc"
>> @title = " abc "
=> " abc "
>> @title.strip!
=> "abc"
>> @title
=> "abc"

61voto

gaRex Points 2422

En fait, ruby supporte déjà le strip sans " !".

Comparez :

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

Il est également impossible de strip sans doublons. Voir les sources dans string.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]

Mise à jour 1 : Comme je le vois maintenant -- il a été créé en 1999 (cf. rev #372 dans le SVN) :

Mise à jour2 : strip! ne créera pas de doublons - à la fois dans les versions 1.9.x, 2.x et trunk.

10voto

karldaborg Points 64

Il n'est pas nécessaire d'utiliser à la fois le strip et le chomp, car le strip supprimera également les retours chariot de fin de ligne - à moins que vous n'ayez modifié le séparateur d'enregistrement par défaut et que ce soit ce que vous chompiez.

La réponse d'Olly présente déjà la manière canonique de faire cela en Ruby, mais si vous vous retrouvez à faire cela souvent, vous pouvez toujours définir une méthode pour cela :

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

Donner :

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

Gardez également à l'esprit que l'instruction if empêchera @title d'être assigné si le jeton est nul, ce qui aura pour effet de lui faire conserver sa valeur précédente. Si vous voulez ou ne voulez pas @title étant toujours affecté, vous pouvez déplacer le contrôle dans la méthode et réduire davantage la duplication :

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

Comme alternative, si vous vous sentez aventureux, vous pouvez définir une méthode sur la chaîne elle-même :

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

Donner un de :

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

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

4voto

Olly Points 4314

Je pense que votre exemple est une approche raisonnable, bien que vous puissiez le simplifier légèrement comme suit :

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

Une alternative serait de le mettre sur deux lignes :

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

1voto

hauleth Points 8253

A ma façon :

> (@title = " abc ").strip!
 => "abc" 
> @title
 => "abc"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X