web-dev-qa-db-fra.com

Comment éliminer les guillemets en début et en fin de chaîne, en Ruby

Je veux enlever les guillemets en début et en fin, en Ruby, d'une chaîne. Le caractère de citation apparaît 0 ou 1 fois. Par exemple, tous les éléments suivants doivent être convertis en foo, bar:

  • "foo,bar"
  • "foo,bar
  • foo,bar"
  • foo,bar
33
ChrisInEdmonton

Vous pouvez également utiliser la fonction chomp, mais cela ne fonctionne malheureusement qu'en fin de chaîne, en supposant qu'il y ait un chomp inverse, vous pouvez:

'"foo,bar"'.rchomp('"').chomp('"')

La mise en œuvre de rchomp est simple:

class String
  def rchomp(sep = $/)
    self.start_with?(sep) ? self[sep.size..-1] : self
  end
end

Notez que vous pouvez également le faire en ligne, avec la version légèrement moins efficace:

'"foo,bar"'.chomp('"').reverse.chomp('"').reverse

EDIT: Depuis Ruby 2.5, rchomp(x) est disponible sous le nom delete_prefix, et chomp(x) est disponible en tant que delete_suffix, ce qui signifie que vous pouvez utiliser

'"foo,bar"'.delete_prefix('"').delete_suffix('"')
30
grddev

Je peux utiliser gsub pour rechercher la citation en tête ou en fin et la remplacer par une chaîne vide:

s = "\"foo,bar\""
s.gsub!(/^\"|\"?$/, '')

Comme suggéré par les commentaires ci-dessous, une meilleure solution est:

s.gsub!(/\A"|"\Z/, '')
35
ChrisInEdmonton

Comme d'habitude, tout le monde saisit regex dans la boîte à outils en premier. :-)

En tant que suppléant, je vous recommande de vous pencher sur .tr('"', '') (AKA "translate") qui, dans cette utilisation, efface vraiment les guillemets.

23
the Tin Man

Une autre approche serait 

remove_quotations('"foo,bar"')

def remove_quotations(str)
  if str.start_with?('"')
    str = str.slice(1..-1)
  end
  if str.end_with?('"')
    str = str.slice(0..-2)
  end
end 

C'est sans RegExps et start_with?/End_with? sont bien lisibles.

9
Yo Ludke

Cela me frustre que la bande ne fonctionne que sur les espaces blancs. J'ai besoin de dépouiller toutes sortes de personnages! Voici une extension de chaîne qui résoudra ce problème:

class String
  def trim sep=/\s/
    sep_source = sep.is_a?(Regexp) ? sep.source : Regexp.escape(sep)
    pattern = Regexp.new("\\A(#{sep_source})*(.*?)(#{sep_source})*\\z")
    self[pattern, 2]
  end
end

Sortie

'"foo,bar"'.trim '"'         # => "foo,bar"
'"foo,bar'.trim '"'          # => "foo,bar"
'foo,bar"'.trim '"'          # => "foo,bar"
'foo,bar'.trim '"'           # => "foo,bar"

'  foo,bar'.trim             # => "foo,bar"
'afoo,bare'.trim /[aeiou]/   # => "foo,bar"
3
Eva

Je voulais la même chose, mais pour les barres obliques dans le chemin de l'URL, qui peut être /test/test/test/ (de sorte qu'il ait les caractères de strip-tease au milieu) et a finalement proposé quelque chose comme ceci pour éviter les expressions rationnelles:

'/test/test/test/'.split('/').reject(|i| i.empty?).join('/')

Ce qui dans ce cas se traduit évidemment par:

 '"foo,bar"'.split('"').select{|i| i != ""}.join('"')

ou

'"foo,bar"'.split('"').reject{|i| i.empty?}.join('"')
2
marcinowski

Les regex peuvent être assez lourdes et conduire à des erreurs géniales. Si vous ne traitez pas de chaînes volumineuses et que les données sont assez uniformes, vous pouvez utiliser une approche plus simple.

Si vous savez que les chaînes ont des guillemets de départ et de début, vous pouvez épisser la chaîne entière:

string  = "'This has quotes!'"
trimmed = string[1..-2] 
puts trimmed # "This has quotes!"

Cela peut aussi être transformé en une simple fonction:

# In this case, 34 is \" and 39 is ', you can add other codes etc. 
def trim_chars(string, char_codes=[34, 39])
    if char_codes.include?(string[0]) && char_codes.include?(string[-1])
        string[1..-2]
    else
        string
    end
end
0
user427390