>> 連載の目次は こちら!
1. 文字列リテラルの表現
基本的な書き方
name = 'miro'
puts "My name is #{name}.\nI am #{10-1} years old."
str = String.new("これはあまりやらないだろう");
puts %Q{"ダブルクォーテーション" を "いっぱい" 使いたい}
puts %q{'シングルクォーテーション' を 'いっぱい' 使いたい}
- ダブルクォーテーションだと式やエスケープシーケンスを展開してくれる
- クォーテーション類を多用するなどでエスケープしたくないときは%Qや%q記法もあり
- わざわざnewすることはあまりないかな
ヒアドキュメント
str = <<"EOS"
改行の記号とか入れるの
面倒だしみづらいし。
EOS
puts str
puts(<<"EOS")
メソッドにヒアドキュメント
を渡す方法は独特だー
EOS
puts (<<-EOS)
終了の識別子も
インデントしたいときあるよねー
EOS
- 識別子はEOSじゃなくてもよい
- 識別子をダブクォーで囲むと式とかエスケープ文字を展開してくれる
- 「<<-識別子」だと、終了の識別子をインデントできる
2. 文字列の結合
プラス記号で結合。掛け算で繰り返し。
puts "abc" + "def"
str2, str3 = "aaa", "bbb"
puts str2 + str3
puts "Hey!" * 3 # Hey!Hey!Hey!
puts month.to_s + '月' # 数値はto_sしてから結合
配列から結合
arr = ["apple", "orange", "lemon"].join() # そのままくっつけて結合
arr = ["apple", "orange", "lemon"].join(","); # 指定文字区切りで結合
破壊的な結合
str = "abc"
puts str << "xyz"
puts str
str = "abc"
puts str.concat("xyz")
puts str
- 「<<」も concat もStringのメソッドで機能は同じ
- 自分自身を変更する(破壊的)と同時に、式は変更後の文字列を返す
- 前述の「+」記号のように破壊的でない結合の場合、結合後の文字列が別オブジェクトとして作られるので、ループで大量処理するときとかは破壊的な結合の使用を検討する。
sprintf的なあれ
puts "between %d and %d" % [5, 10]
puts "rate: %.4f%%" % (10.0 / 3)
- 「%」は、Stringのメソッド
- Kernelモジュールにsprintfメソッドもあるが、こっちのほうが楽
3. 文字列の比較
str1 == str2
str1 != str2
でよい。
※オブジェクトの比較について
equal? メソッドだとオブジェクトが同一かを判定する。
== 演算子は、Object クラスにおいては equal? メソッドの別名だが、たいてい値そのものを比較するようにオーバーライドされていて、Stringも同様。
なので、str1 == str2 は文字列の値を比較している。
4. 数値から文字列への変換
month.to_s + '月'
・to_s メソッドで変換する
・他に t_str メソッドというのもあり、違いは以下。
to_sは(どのオブジェクトにもデフォルトで定義されている)文字列
化のフォーマットを変えるために再定義します。to_strはそのクラス/オブジェクトが文字列として振る舞うことが
できるようにするために定義します。
5. Stringクラスのよく使いそうなメソッド
※多くのメソッドは、「!」をつけると破壊的(自分自身を変更)になる。
文字数を取得
puts "ダダーンン半角やら英字xyzまじってるゾ!".length
puts "ダダーンン半角やら英字xyzまじってるゾ!".size
※関係ないけど、半角カナって濁点が1文字にカウントされるんだね。PHP(mb_strlen)でも試したけど同じだった。
大文字・小文字の変換
str = "komoji".upcase # 大文字化。
str = "OOMOJI".downcase # 小文字化。
str = "mojimoji".capitalize # 先頭大文字であと小文字化。
トリム、削除
target = " target "
str = target.strip # 先頭と末尾をトリム。
str = target.lstrip # 先頭をトリム。
str = target.rstrip # 末尾をトリム。
# ↑これらは、空白と 「¥t」 「¥r」 「¥n」 「¥f」 「¥v」 がトリムされる
str = "最後の,カンマ,要らない,".chop() # 文字列の末尾の文字を除去
str = "wa-i\n".chomp() # 文字列の末尾の改行を除去(引数で改行文字は指定できる)
str = "very good".delete("very ") # 文字列から特定の文字列を除去
検索系
pos = "どこにポケモンがいるでしょう".index("ポケモン") # 文字列のなかの文字列のindexを返す(先頭から検索)
pos = "どこにポケモンがいるでしょう".rindex("ポケモン") # 文字列のなかの文字列のindexを返す(末尾から検索)
# ↑これらは、第2引数で開始位置を指定できる
flag = "ここにはポケモンがいるのか".include?("ポケモン") # 文字列のなかに、ある文字列が含まれているか
切り出し系
substring的なあれ。配列みたいにインデックスでアクセスできるから楽。
puts "まぐろサーモンいくら"[3, 4] # 文字列の一部を取得(開始indexと文字数を指定する方法)
puts "トロえんがわたまご"[2..5] # 文字列の一部を取得(開始indexと終了indexを指定する方法)
ある文字列で始まっているか、終わっているか
str = "猫はとっても人間が好き"
p str.start_with?('猫')
p str.start_with?('猫', '犬') # 複数候補でマッチングできる
p str.end_with?('好き')
p str.end_with?('好き', '嫌い') # 複数候補でマッチングできる
置換、挿入系
これも配列みたいにインデックスでアクセスできるから楽。
str = "彼は強い".insert(2, "とても") # 文字列の指定の位置に文字列を挿入
str[5, 2] = "背が高い" # 文字列の指定の部分を置換(開始indexと文字数を指定する方法)
str[5..11] = "太っている" # 文字列の指定の部分を置換(開始indexと終了indexを指定する方法)
バラして配列化
arr = "abc".chars # 1文字ずつばらして配列化
arr = "ミスド\nスタバ\nタリーズ".lines # 1行ずつばらして配列化(改行が各要素に含まれる)
arr = "北海道,東京,大阪,福岡".split(",") # 指定の区切り文字でばらして配列化
ループ処理系
# 1文字ずつ取り出してループ処理したい
"横を縦にする".each_char do |char|
puts char
end
# 1行ずつ取り出してループ処理したい(改行が各要素に含まれる)
"わーい\n改行\nしちゃうよ".each_line do |line|
print line
end
6. 正規表現
パターンの生成
ptn1 = /abc[0-9]{2}xyz/
ptn2 = Regexp.new('^XX[a-z]{3}[0-9]{2}xyz$')
シンプルにマッチングだけしたい
m = "XXabc54xyz" =~ ptn1 # マッチしていることを判定
m = "XXabc54xyz" !~ ptn1 # マッチしていないことを判定
マッチング結果を取り出したい
ptn = /(\d{4})\/(\d{2})\/(\d{2})/
# または ptn = Regexp.new('(\d{4})\/(\d{2})\/(\d{2})')
mData = "2099/12/31".match(ptn)
puts "%s-%s-%s" % [$1, $2, $3]
puts "%s (%s-%s-%s)" % [mData[0], mData[1], mData[2], mData[3]]
- Stringクラスの match メソッドを使う
- 結果は MatchData クラスのオブジェクトで返される
- マッチ結果は、
$1
〜$n
の特殊変数か、MatchDataオブジェクトにインデックスでアクセスして取得する