新しい文字列を作成せずにRubyで文字列をトリミングする標準的な方法は何ですか?


182

これは私が今持っているものです-それはそれがしている仕事には冗長すぎます。

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

トークンは、CSV行を分割して取得した配列であると想定します。今ストリップのような機能!むしゃむしゃ!等 文字列が変更されていない場合、すべてnilを返します

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

コピーを作成せずに余分な先頭または末尾のスペースが含まれている場合、Rubyはそれをトリムすると言う方法は何ですか?

やりたいなら醜くなる tokens[Title].chomp!.strip!


3
トークンから繰り返し物を読み取る場合は、トークンを前処理する方が理にかなっている可能性があります。つまり、「tokens.each {| t | t.strip!}」です。その後、「@ title = tokens [Title] ||」」を実行するだけです
glenn mcdonald

回答:


272

あなたが望むのは:

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

#strip!この方法は、返されnil、それが取り除かれた場合、それは何を削除しなかった場合、変数そのもの。

Ruby標準によれば、感嘆符のサフィックスが付いたメソッドは、変数を適切に変更します。

お役に立てれば。

更新:これはirb、次のデモからの出力です。

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

1
えーと、まだ@title = tokens [Title] .stripだと思います!見た目がすっきりしている-変更されていない文字列ではなくnilを返すのは残念です。誰かがより良いans ..を投稿しない限り、あなたは受け入れられたビットを得ています。
岐阜

7
まあ、@ title = tokens [Title] .stripでうまくいきますが、代わりにコピーがあります。tokens[Title]変数をそのままにしておけば問題ありません。
イゴール

9
Ruby 1.9にはタップがあり、それはまさにあなたが望むものを実行します:@ title.tap {| x | x.strip!}
timkay

2
@timkayそれは可能でしょう@title.tap &:strip!か?それは何よりもきれいに見えます。
Jon Egeland 2013

16
nilそれが何かを剥がさない限り、なぜそれは世界に戻るのですか?それは間違いなくたくさんの人々を混乱させました(それは意味がないので)。
ジョシュM.

53

ところで、Rubyはすでに「!」なしのストリップのみをサポートしています。

比較:

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

また、strip複製なしでは不可能です。string.cのソースを参照してください:

static VALUE
rb_str_strip(VALUE str)
{
    str = rb_str_dup(str);
    rb_str_strip_bang(str);
    return str;
}

ルビー1.9.3p0(2011-10-30)[i386-mingw32]

アップデート1:私が今見るように-1999年に作成されました(SVNのrev#372を参照):

Update2: strip!1.9.x、2.x、およびトランクバージョンの両方で、重複は作成されません。


1
「重複なしにストリップすることは不可能です」-もちろんそれは可能です、それstrip!が目的です。
Karoly Horvath、2015年

@KarolyHorvath Cで書かれたソースコードは表示されませんか?Plsは注意深く読んだ。私がここで複製について書いたもの。
gaRex

1
もちろん見ます。しかし、それはのソースコードですstrip。私は何かを誤解していますか?他にどのようにして「重複せずに除去することは不可能」と解釈できますか?
Karoly Horvath、2015年

@KarolyHorvathの内部複製は常に作成されます。それは文字列 `str = rb_str_dup(str);`についてです
gaRex

1
また、複製が必要ない場合は、strip!別名を使用しますrb_str_strip_bang
Karoly Horvath、2015年

9

ストリップは後続のキャリッジリターンも削除するため、ストリップとチョンプの両方を行う必要はありません。デフォルトのレコードセパレーターを変更していない限り、チョッピングは行われません。

オリーの答えはすでにRubyでこれを行うための標準的な方法を持っていますが、これをたくさん自分でやっていると思ったら、いつでもそのためのメソッドを定義できます:

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

与える:

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

また@title、トークンがnilの場合、ifステートメントは割り当てられないため、以前の値が保持されることに注意してください。@title常に割り当てられることを希望する場合、または気にしない場合は、チェックをメソッドに移動して、重複をさらに減らすことができます。

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

別の方法として、冒険したい場合は、String自体にメソッドを定義できます。

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

次のいずれかを与える:

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

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

9

Ruby on Railsを使用している場合、スキッシュがあります

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

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

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

Rubyだけを使用している場合は、ストリップを使用したい

ここには、落とし穴があります..あなたの場合、あなたは強打なしでストリップを使いたいです!

ストリップしながら!アクションがなかった場合は確かにnilを返しますが、それでも変数が更新されるので削除してください!インラインでは使用できません。インラインでストリップを使用したい場合は、強打なしのバージョンを使用できます!

ストリップ!複数行アプローチを使用

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

単線アプローチを取り除く ...あなたの答え

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

4

あなたの例は賢明なアプローチだと思いますが、次のように少し単純化することもできます。

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

別の方法としては、次の2行で記述できます。

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

3

このようなものが必要になった後で別の方法を使用したい場合:

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

このようにして、ストリップした後でも何かを行うことができます:)



1

ruby 1.9またはactivesupportのいずれかを使用している場合は、簡単に行うことができます

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

私の意見では、これはRubyで最も強力な関数構成体である:try:tapメソッドを利用しているので、本当にクールです。

機能がすべてシンボルとして渡される、よりかわいいフォーム:

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

-1
@title = tokens[Title].strip! || tokens[Title]

私はトピックを理解していない可能性がありますが、これはあなたが必要とすることをしませんか?

" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.