Rubyで文字列を扱う場合、Stringクラスを使用します。この章では特に指定しない限り、Stringクラスのメソッドを解説しています。

文字列を結合する

Stringクラスのインスタンス自体(メソッドのレシーバ)へ文字列を追加する場合、String#«メソッドまたはString#concatメソッドを使用します。

 s = "Hello"
 
 s << " Ruby" #=> "Hello Ruby"
 s.concat(" World!") #=> "Hello Ruby World!"

インスタンスは更新せずに複数の文字列を結合する場合は、String#+メソッドを使用します。

下の例ではsの値は変化せず、sの値’Hello’とリテラルで指定した’ World’の値を結合した’Hello World’がs1の値になります。

 s = "Hello"
 
 s1 = s + " World" #=> "Hello World"

繰り返し文字列を生成する

String#*メソッドを使うと文字列を指定回数分繰り返した文字列を返却します。

下の例ではsの値’Hey ‘を3回繰り返した’Hey Hey Hey ‘がs1の値になります。

 s = "Hey "
 
 s1 = s * 3 #=> "Hey Hey Hey "

大文字・小文字に揃える

文字列を大文字または小文字に揃えるにはString#upcaseメソッド、String#downcaseメソッドを使います。

下の例ではs1にはsを全て大文字にした’I LOVE RUBY’が、s2には全て小文字にした’i love ruby’が設定されます。

 s = "I love Ruby"
 
 s1 = s.upcase #=> "I LOVE RUBY"
 s2 = s.downcase #=> "i love ruby"

String#upcase、String#downcaseにはそれぞれ破壊的メソッドString#upcase!、String#downcase!が用意されています。

大文字と小文字の入れ替え

大文字と小文字を入れ替えるにはString#swapcaseメソッドを使います。破壊的メソッドString#swapcase!も用意されています。

 s = "i lOVE rUBY"
 p s.swapcase #=> "I Love Ruby"
 s.swapcase! #=> "I Love Ruby" s.swapcaseではsは変更されない

コマンドの実行結果を文字列に設定する

コマンドの実行結果を文字列にするには、バッククオート(`)でコマンドを括り以下のように指定します。

 s = `date` #=> "Sun May 13 23:47:47 JST 2001"

複数行の文字列を作成する

複数行の文字列を作成するにはヒアドキュメントを使用すると便利です。ヒアドキュメントの終端文字列と«の間にはスペースやタブを置くことはできません。

 s = <<EOS
 This is test.
 
 Ruby, the Object Oriented Script Language.
 EOS

この例ではThis is test.以下EOS直前までの3行がsへ設定されます。

ヒアドキュメントの終端文字列をインデントする

スクリプト中にヒアドキュメントを埋め込む場合、他の部分と合わせてヒアドキュメントの終端を示す文字列もインデントとしたいことがあります。そのような時は«-を使用し以下のようにします。

     s= <<-EOS
 This is test.
 
 Ruby, the Object Oriented Script Language.
     EOS

複数行のコマンドの実行結果を文字列に設定する

ヒアドキュメントの中に複数行に渡るコマンドを記述し、その実行結果をまとめて文字列へ設定するには以下のようにします。

 s= <<`EOS`
 date
 echo "-----------------------------"
 ps
 EOS

このスクリプトでのsの設定例を以下に示します。

 Sun May 13 23:06:12 JST 2001
 -----------------------------
   PID TTY          TIME CMD
  2681 pts/1    00:00:00 bash
  2878 pts/1    00:00:00 ruby
  2879 pts/1    00:00:00 ps

部分文字列を取り出す

文字列の一部分を取り出すにはString#s[n..m], String#s[n,len],またはString#sliceメソッドを使います。

s[n..m]とするとsのn文字目からm文字目の文字列を返却します。s[n, len]とするとsのn文字目からlen文字の文字列を返却します。文字列の最初の文字を0番目として指定します。

String#sliceの場合s.slice(n..m)とするとsのn文字目からm文字目の文字列を返却し、s.slice(n, len)とするとsのn文字目からlen文字の文字列を返却します。

また、s.slice(n)とするとn文字目の文字コードを返却します。String#sliceには破壊的メソッドString#slice!が用意されています。

 s = "Apple Banana Orange"
 
 p s[0..4] #=> "Apple"
 p s[6, 6] #=> "Banana"
 
 p s.slice(0,3) #=> "App"
 p s.slice(6) #=> 66
 p s.slice(13..18) #=> "Orange"

部分文字列を置き換える

文字列のどの部分を置き換えるかをs[n..m], s[n,len]のように左辺に記述し、置き換えたい文字列を右辺に記述し=で結びます。

 s = "Apple Banana Orange"
 
 s[0..4] = "Vine" #=> s = "Vine Banana Orane"
 s[5, 6] = "Lemon" #=> s = "Vine Lemon Orange"

上の例のようにm置き換える文字列と置き換えられる文字列の長さは異なっていてもかまいません。

文字列中の式を評価し値を展開する

文字列中の式を評価し値を展開するには、#{…}という記述を使います。

 value = 123
 
 puts "value is #{value}" #=> "value is 123"

変数だけではなくメソッドやサブルーチンを記述することもできます。

 def sub1(str)
   "Hello, #{str}."
 end
 
 puts "Say  #{sub1("Tomoya")}" #=> "Say Hello, Tomoya."

文字列を1文字ずつ処理する

文字列を1文字ずつ処理するにはString#each_byteメソッドを使用します。

 sum = 0
 
 "Ruby".each_byte {|c| sum = sum + c}
 p sum

上記の例は”Ruby”という文字列を構成する文字R,u,b,yの文字コードの合計をsumに設定し、値を表示します。文字コードはそれぞれR(82)、u(117)、b(98)、y(121)ですので、sumの値として418が出力されます。

文字列を1行ずつ処理する

文字列を1行ずつ処理するにはString#each_lineメソッドを使用します。

 linenum = 1
 
 s = <<EOS
 This is test.
 
 Ruby, the Object Oriented Script Language.
 EOS
 
 s.each_line {|line| 
   print "#{linenum}: #{line}"
   linenum = linenum + 1
 }

上記の例はヒアドキュメントで設定された3行の文字列の各行に、行番号を付与して出力します。結果は以下のようになります。

 1: This is test.
 2: 
 3: Ruby, the Object Oriented Script Language.

文字列の先頭と末尾の空白文字を削除する

文字列の先頭と末尾の空白文字(\r \n \t \f \v 半角スペース)を削除するにはString#stripメソッドを使います。String#stripには破壊的メソッドString#strip!も用意されています。

 s = "   Hello, Ruby!   "
 
 s.strip #=> "Hello, Ruby!"
 s.strip! #=> "Hello, Ruby!"

文字列を整数に変換する (to_i)

文字列を数値に変換するにはString#to_iメソッドを使います。

 i  = 1
 s = "999"
 
 i = i + s.to_i #=> 1000

文字列を浮動小数点に変換する (to_f)

文字列を浮動小数点に変換するにはString#to_fメソッドを使います。

 p "10".to_f #=> 10.0

8進文字列を整数に変換する (oct)

8進文字列を整数に変換するにはString#octメソッドを使います。

 p "010".oct #=> 8

16進文字列を整数に変換する (hex)

16進文字列を整数に変換するにはString#hexメソッドを使います。

 p "0xff".hex #=> 255
 p "10".hex #=> 16

ASCII文字をコード値に(コード値をASCII文字に)変換する

ord メソッドはアスキー文字列の最初の文字のアスキーコード値を返します.(Ruby 1.9.x以降)

 s = "ABC"
 p s.ord #=> 65 : "A" のアスキーコード値

Ruby 1.8.7 以前にはこのメソッドはないので注意してください.

文字列を[]で1文字だけ参照するとそのASCII文字のコード値が返されます。(Ruby 1.8.xまで)

 s = "ABC"
 p s[0] #=> 65

[]については.Ruby 1.9.x 以降は次のように仕様が変わっていますので注意してください.

 s = "ABC"
 p s[0] #=>  "A" : 最初の文字を返す.
 s = "あいうえお"
 p s[0] #=> "あ"

Integer#chrメソッド、組込み関数のsprintf、format、String#%メソッドを使うとコード値からASCII文字に変換することができます。

 p 82.chr #=> "R"
 p sprintf("%c", 82) #=> "R"
 p format("%c", 82) #=> "R"
 p "%c" % 82 #=> "R"

文字列を中央寄せ・左詰・右詰する

文字列をセンタリングするにはString#center、左詰するにはString#ljust、右詰するにはString#rjustメソッドを使用します。

引数で指定された長さの文字列を生成し、そのなかで指定された整形を行った文字列が返却されます。

 s = "Ruby"
 
 p s.center(10) #=> "   Ruby   "
 p s.ljust(10)  #=> "Ruby      "
 p s.rjust(10)  #=> "      Ruby"

“次”の文字列を取得する

String#succメソッドは文字列の「次」の文字列を返却します。

 p "9".succ #>= "10"
 p "a".succ #>= "b"
 p "AAA".succ #>= "AAB"
 p "A99".succ #>= "B00"
 p "A099".succ #>= "A100"

プログラム中でシーケンシャルな識別子を払い出す場合などに便利でしょう。破壊的メソッドString#succ!も用意されています。

String#next、String#next!が同様の動きをするメソッドとして用意されています。

文字列を暗号化する

文字列を暗号化するにはString#cryptメソッドを使います。

 secretword = "hogehoge"
 
 SALT_CHARSET = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 salt = "" << SALT_CHARSET[rand 64] << SALT_CHARSET[rand 64]
 passwd = secretword.crypt(salt)

上記の例ではSALT_CHARSETからランダムに選んだ2文字を乱数の種にして、”hogehoge”という文字列を暗号化し、passwdに設定しています。

仮にpasswdの値が”KBxoECYM2ydlM”だったとすると、以下のスクリプトは引数に指定された文字列が暗号化前の文字列と同じ”hogehoge”であれば”right”、それ以外では”wrong”を出力します。

 passwd = "KBxoECYM2ydlM"
 
 userinput = ARGV.shift
 
 if userinput.crypt(passwd) == passwd
   puts "right"
 else
   puts "wrong"
 end

文字列中で指定したパターンにマッチする部分を置換する

文字列中で指定したパターンにマッチする部分を置換するにはString#sub、String#gsubメソッドを使用します。

String#subメソッドは文字列中で最初にマッチした部分だけを置換しますが、String#gsubメソッドはマッチする全ての部分を置換します。パターンには正規表現も指定できます。

 s = "Apple Banana Apple Orange"
 
 p s.sub("Apple", "Pine") #=> "Pine Banana Apple Orange"
 p s.gsub("Apple", "Pine") #=> "Pine Banana Pine Orange"

String#sub、String#gsubメソッドにはそれぞれ破壊的メソッドString#sub!、String#gsub!が用意されています。

文字列中に含まれている任意文字列の位置を求める

文字列中に含まれている任意文字列の最初の位置を求めるにはString#indexメソッド、最後の位置を求めるにはString#rindexを使います。

第2引数が与えられた場合、String#indexメソッドの場合はそこから後方に、String#rindexメソッドの場合は前方に検索を行います。見つからなければ nil を返します。

 s = "Apple Banana Apple Orange"
 
 p s.index("Apple") #=> 0
 p s.index("Banana") #=> 6
 p s.index("Apple", 6) #=> 13
 
 p s.rindex("Apple") #=> 13
 p s.rindex("Apple", 6) #>= 0

文字列の末端の改行を削除する

文字列の末端の改行を削除するにはString#chompメソッドを使用します。String#chompメソッドは文字列の末端がグローバル変数$/と一致した場合、それを削除した文字列を返却します。

$/のデフォルト値は”\n”ですので、通常このメソッドにより末端の改行を削除することができます。String#chompメソッドには破壊的メソッドのString#chomp!も用意されています。

 s = "Hello, Ruby!\n"
 
 p s.chomp #=> "Hello, Ruby!"
 s.chomp! #=> "Hello, Ruby!"

カンマ区切りの文字列を扱う

カンマ区切りなど特定のセパレータで区切られた文字列を扱う場合、String#splitメソッドを使うと便利です。

String#splitメソッドは引数として与えた正規表現に合致する部分をセパレータと認識し、各フィールドを配列にして返すメソッドです。

 "001,TAKEUCHI Hitoshi,Yokohama".split(/\s*,\s*/) #=> ["001", "TAKEUCHI Hitoshi", "Yokohama"]

任意のパターンにマッチするものを全て抜き出す

String#scanメソッドは文字列中で任意のパターンにマッチするものを全て抜き出した配列を返却します。

 p "hoge:045-111-2222 boke:045-222-2222".scan(/(\S+):([\d\-]+)/)
 
 #=> [["hoge", "045-111-2222"], ["boke", "045-222-2222"]]

漢字コードを変換する

漢字コードを変換するには添付モジュールのkconvを使用します。

kconvにはJISに変換するKconv::tojis、EUCに変換するKconv::toeuc、シフトJISに変換するKconv::tosjisメソッドがあります。

 require "kconv"
 
 s = "漢字です"
 
 p Kconv.tojis(s)
 p Kconv.toeuc(s)
 p Kconv.tosjis(s)

kconvをrequireするとStringクラスにこれらのメソッドが追加されます。

 require "kconv"
 
 s = "漢字です"
 
 p s.tojis
 p s.toeuc
 p s.tosjis

kconvをrequireすれば、Stringクラスにtojis、toeuc、tosjisメソッドが追加されます。

マルチバイト文字の数を数える

utf-8 の場合

 "日本語".split(//u).length
 
 => 3

euc-jp の場合

 "日本語".split(//e).length

shift-jis の場合

 "日本語".split(//s).length

マルチバイト文字列の最後の1文字を削除する

utf-8 の場合

 puts "日本語".split(//u)[0..-2].join
 
 日本
 => nil

printf整形

 m = "%s %.1f" % [Time.now.strftime("%H:%m"), 3.19]
 => "18:12 3.2"