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
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('"')
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/, '')
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.
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.
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"
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('"')
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