[Ruby入門] 04. 文字列を扱う（リテラルとStringクラス。あと正規表現）

&gt;&gt; 連載の目次は [こちら！](http://qiita.com/prgseek/items/237d02be844534063f1d)

## 1. 文字列リテラルの表現

### 基本的な書き方
```ruby
name = 'miro'
puts "My name is #{name}.\nI am #{10-1} years old."
str = String.new("これはあまりやらないだろう");
puts %Q{"ダブルクォーテーション" を "いっぱい" 使いたい}
puts %q{'シングルクォーテーション' を 'いっぱい' 使いたい}
```
+ ダブルクォーテーションだと式やエスケープシーケンスを展開してくれる
+ クォーテーション類を多用するなどでエスケープしたくないときは%Qや%q記法もあり
+ わざわざnewすることはあまりないかな

### ヒアドキュメント
```ruby
str = <<"EOS"
改行の記号とか入れるの
面倒だしみづらいし。
EOS
puts str

puts(<<"EOS")
メソッドにヒアドキュメント
を渡す方法は独特だー
EOS

  puts (<<-EOS)
終了の識別子も
インデントしたいときあるよねー
  EOS
```

+ 識別子はEOSじゃなくてもよい
+ 識別子をダブクォーで囲むと式とかエスケープ文字を展開してくれる
+ 「<<-識別子」だと、終了の識別子をインデントできる

## 2. 文字列の結合

### プラス記号で結合。掛け算で繰り返し。
```ruby
puts "abc" + "def"
str2, str3 = "aaa", "bbb"
puts str2 + str3
puts "Hey!" * 3            # Hey!Hey!Hey!
puts month.to_s + '月'     # 数値はto_sしてから結合 
```

### 配列から結合
```ruby
arr = ["apple", "orange", "lemon"].join()     # そのままくっつけて結合
arr = ["apple", "orange", "lemon"].join(","); # 指定文字区切りで結合
```

### 破壊的な結合
```ruby
str = "abc"
puts str << "xyz"
puts str

str = "abc"
puts str.concat("xyz")
puts str
```
+ 「<<」も concat もStringのメソッドで機能は同じ
+ 自分自身を変更する(破壊的)と同時に、式は変更後の文字列を返す
+ 前述の「+」記号のように破壊的でない結合の場合、結合後の文字列が別オブジェクトとして作られるので、ループで大量処理するときとかは破壊的な結合の使用を検討する。

### sprintf的なあれ
```ruby
puts "between %d and %d" % [5, 10]
puts "rate: %.4f%%" % (10.0 / 3)
```
+ 「%」は、Stringのメソッド
+ Kernelモジュールにsprintfメソッドもあるが、こっちのほうが楽

## 3. 文字列の比較
```ruby
str1 == str2
str1 != str2
```
でよい。

※オブジェクトの比較について
equal? メソッドだとオブジェクトが同一かを判定する。
== 演算子は、Object クラスにおいては equal? メソッドの別名だが、たいてい値そのものを比較するようにオーバーライドされていて、Stringも同様。
なので、str1 == str2 は文字列の値を比較している。


## 4. 数値から文字列への変換
```ruby
month.to_s + '月'
```
・to_s メソッドで変換する
・他に t_str メソッドというのもあり、違いは以下。 

> to_sは(どのオブジェクトにもデフォルトで定義されている)文字列
> 化のフォーマットを変えるために再定義します。
> 
> to_strはそのクラス/オブジェクトが文字列として振る舞うことが
> できるようにするために定義します。


## 5. Stringクラスのよく使いそうなメソッド

※多くのメソッドは、「!」をつけると破壊的（自分自身を変更）になる。

### 文字数を取得
```ruby
puts "ダﾀﾞーンﾝ半角やら英字xyzまじってるｿﾞ！".length
puts "ダﾀﾞーンﾝ半角やら英字xyzまじってるｿﾞ！".size
```
※関係ないけど、半角カナって濁点が１文字にカウントされるんだね。PHP(mb_strlen)でも試したけど同じだった。

### 大文字・小文字の変換
```ruby
str = "komoji".upcase       # 大文字化。
str = "OOMOJI".downcase     # 小文字化。
str = "mojimoji".capitalize # 先頭大文字であと小文字化。
```

### トリム、削除
```ruby
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 ")   # 文字列から特定の文字列を除去
```

### 検索系
```ruby
pos = "どこにポケモンがいるでしょう".index("ポケモン")   # 文字列のなかの文字列のindexを返す（先頭から検索）
pos = "どこにポケモンがいるでしょう".rindex("ポケモン")  # 文字列のなかの文字列のindexを返す（末尾から検索）
# ↑これらは、第２引数で開始位置を指定できる

flag = "ここにはポケモンがいるのか".include?("ポケモン") # 文字列のなかに、ある文字列が含まれているか
```

### 切り出し系
substring的なあれ。配列みたいにインデックスでアクセスできるから楽。

```ruby
puts "まぐろサーモンいくら"[3, 4]  # 文字列の一部を取得（開始indexと文字数を指定する方法）
puts "トロえんがわたまご"[2..5]   # 文字列の一部を取得（開始indexと終了indexを指定する方法）
```

### ある文字列で始まっているか、終わっているか
```ruby
str = "猫はとっても人間が好き"
p str.start_with?('猫')
p str.start_with?('猫', '犬')   # 複数候補でマッチングできる
p str.end_with?('好き')
p str.end_with?('好き', '嫌い')  # 複数候補でマッチングできる
```

### 置換、挿入系
これも配列みたいにインデックスでアクセスできるから楽。

```ruby
str = "彼は強い".insert(2, "とても") # 文字列の指定の位置に文字列を挿入
str[5, 2] = "背が高い"             # 文字列の指定の部分を置換（開始indexと文字数を指定する方法）
str[5..11] = "太っている"           # 文字列の指定の部分を置換（開始indexと終了indexを指定する方法）
```

### バラして配列化
```ruby
arr = "abc".chars                       # １文字ずつばらして配列化
arr = "ミスド\nスタバ\nタリーズ".lines        # １行ずつばらして配列化（改行が各要素に含まれる）
arr = "北海道,東京,大阪,福岡".split(",")   # 指定の区切り文字でばらして配列化
```

### ループ処理系
```ruby
# １文字ずつ取り出してループ処理したい
"横を縦にする".each_char do |char|
  puts char
end

# １行ずつ取り出してループ処理したい（改行が各要素に含まれる）
"わーい\n改行\nしちゃうよ".each_line do |line|
  print line
end
```

## 6. 正規表現

### パターンの生成
```ruby
ptn1 = /abc[0-9]{2}xyz/
ptn2 = Regexp.new('^XX[a-z]{3}[0-9]{2}xyz$')
```

### シンプルにマッチングだけしたい
```ruby
m = "XXabc54xyz" =~ ptn1  # マッチしていることを判定
m = "XXabc54xyz" !~ ptn1  # マッチしていないことを判定
```

### マッチング結果を取り出したい
```ruby
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オブジェクトにインデックスでアクセスして取得する