it-swarm.com.de

Was ist die kanonische Methode, um einen String in Ruby zu schneiden, ohne einen neuen String zu erstellen?

Dies ist, was ich jetzt habe - was für die Arbeit, die es tut, zu wortreich aussieht.

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

Angenommen, Token sind ein Array, das durch Aufteilen einer CSV-Zeile erhalten wird. jetzt funktioniert das wie strip! chomp! et. Alle geben null zurück, wenn die Zeichenfolge nicht geändert wurde

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

Wie kann man Ruby trimmen sagen, wenn es zusätzliche führende oder nachfolgende Leerzeichen enthält, ohne Kopien zu erstellen?

Wird hässlicher, wenn ich tokens[Title].chomp!.strip! Machen will

175
Gishu

Ich denke, was Sie wollen, ist:

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

Das #strip! Die Methode gibt nil zurück, wenn nichts entfernt wurde, und die Variable selbst, wenn nichts entfernt wurde.

Gemäß den Ruby Standards wird die Variable durch eine mit einem Ausrufezeichen versehene Methode geändert.

Hoffe das hilft.

Update: Dies wird von irb ausgegeben, um zu demonstrieren:

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

Übrigens unterstützt jetzt Ruby nur Strip ohne "!".

Vergleichen Sie:

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

Es ist auch unmöglich, strip ohne Duplikate zu erstellen. Siehe Quellen in 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 (30.10.2011) [i386-mingw32]

Update 1: Wie ich jetzt sehe - es wurde im Jahr 1999 erstellt (siehe rev # 372 in SVN):

Update2: strip! erstellt keine Duplikate - sowohl in 1.9.x-, 2.x- als auch in Trunk-Versionen.

50
gaRex

Strip und Chomp müssen nicht gleichzeitig ausgeführt werden, da durch Strip auch nachgestellte Zeilenumbrüche entfernt werden - es sei denn, Sie haben das Standardtrennzeichen für Datensätze geändert.

Ollys Antwort hat bereits die kanonische Methode, dies in Ruby zu tun. Wenn Sie jedoch feststellen, dass Sie dies häufig tun, können Sie immer eine Methode dafür definieren:

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

Geben:

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

Denken Sie auch daran, dass die if-Anweisung @title wird nicht zugewiesen, wenn das Token null ist, was dazu führt, dass es seinen vorherigen Wert beibehält. Wenn Sie wollen oder nichts dagegen haben @title immer zugewiesen, können Sie den Scheck in die Methode verschieben und die Duplizierung weiter reduzieren:

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

Alternativ können Sie, wenn Sie sich abenteuerlustig fühlen, eine Methode für String selbst definieren:

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

Geben eines von:

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

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

Wenn Sie Ruby on Rails) verwenden, gibt es ein squish

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

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

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

Wenn Sie nur Ruby verwenden, möchten Sie strip verwenden

Hierin liegt die gotcha .. in Ihrem Fall möchten Sie Streifen ohne den Knall verwenden!

während streifen! Gibt auf jeden Fall nil zurück, wenn es keine Aktion gibt, aktualisiert es die Variable trotzdem, also strip! kann nicht inline verwendet werden. Wenn Sie Streifen inline verwenden möchten, können Sie die Version ohne den Knall verwenden!

Streifen! mit Multi-Line-Ansatz

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

Streifen Einzeiliger Ansatz ... IHRE ANTWORT

> tokens["Title"] = " abc "
 => " abc "
> @title = tokens["Title"].strip if tokens["Title"].present?
 => "abc"
7
gateblues

Wenn Sie eine andere Methode verwenden möchten, nachdem Sie so etwas benötigen:

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

Auf diese Weise kannst du dich ausziehen und danach noch etwas tun :)

Ich denke, Ihr Beispiel ist ein vernünftiger Ansatz, obwohl Sie ihn leicht vereinfachen könnten, indem Sie:

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

Alternativ können Sie es auf zwei Zeilen setzen:

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

Auf meine Art:

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

Wenn Sie entweder Ruby 1.9 oder activesupport haben, können Sie dies einfach tun

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

Das ist wirklich cool, da es das :try und der :tap Methode, die meiner Meinung nach die mächtigsten funktionellen Konstrukte in Ruby sind.

Eine noch niedlichere Form, Passing, fungiert als Symbol:

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