web-dev-qa-db-ger.com

Wie man führende und nachgestellte Zitate in Ruby vom String entfernt

Ich möchte in Ruby führende und nachgestellte Zitate von einer Zeichenfolge entfernen. Das Anführungszeichen tritt 0 oder 1 Mal auf. Beispielsweise sollten alle der folgenden Elemente in foo, bar konvertiert werden:

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

Sie können auch die chomp-Funktion verwenden, die jedoch leider nur am Ende des Strings funktioniert. Angenommen, es gibt einen umgekehrten Chomp, könnten Sie:

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

Die Implementierung von rchomp ist unkompliziert:

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

Beachten Sie, dass Sie dies auch inline tun können, mit der etwas weniger effizienten Version:

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

EDIT: Seit Ruby 2.5 ist rchomp(x) unter dem Namen delete_prefix und chomp(x) als delete_suffix verfügbar, was bedeutet, dass Sie es verwenden können

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

Ich kann mit gsub nach dem führenden oder nachgestellten Zitat suchen und es durch einen leeren String ersetzen:

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

Wie in den folgenden Kommentaren vorgeschlagen, ist eine bessere Lösung:

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

Wie üblich holt sich jeder zuerst Regex aus der Toolbox. :-)

Als Alternative empfehle ich einen Blick auf .tr('"', '') (AKA "translate"), der in diesem Fall die Anführungszeichen wirklich streicht.

23
the Tin Man

Ein anderer Ansatz wäre 

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 

Es ist ohne RegExps und start_with?/End_with? sind gut lesbar.

9
Yo Ludke

Es frustriert mich, dass Strip nur auf Leerzeichen wirkt. Ich muss alle Arten von Charakteren entfernen! Hier ist eine String-Erweiterung, die das korrigiert:

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

Ausgabe

'"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

Ich wollte dasselbe aber für Schrägstriche im URL-Pfad, der /test/test/test/ sein kann (so, dass er die Stripping-Zeichen in der Mitte hat) und schließlich mit etwas wie dem folgenden kam, um Regexs zu vermeiden:

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

Was in diesem Fall offensichtlich übersetzt wird in:

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

oder

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

Regexs können ziemlich schwer sein und zu funky Fehlern führen. Wenn Sie nicht mit massiven Strings zu tun haben und die Daten ziemlich einheitlich sind, können Sie einen einfacheren Ansatz verwenden.

Wenn Sie wissen, dass die Zeichenfolgen Anfangs- und führende Anführungszeichen haben, können Sie die gesamte Zeichenfolge zusammenfügen:

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

Dies kann auch in eine einfache Funktion umgewandelt werden:

# 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