Ruby 1.8.7 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Stringクラス

class String

クラスの継承リスト: String < Enumerable < Comparable < Object < Kernel

要約

文字列のクラスです。 NUL 文字を含む任意のバイト列を扱うことができます。 文字列の長さにはメモリ容量以外の制限はありません。

文字列は通常、文字列リテラルを使って生成します。 以下に文字列リテラルの例をいくつか示します。

'str\\ing'   # シングルクオート文字列 (エスケープシーケンスがほぼ無効)
"string\n"   # ダブルクオート文字列 (エスケープシーケンスがすべて有効)
%q(str\\ing) # 「%q」文字列 (エスケープシーケンスがほぼ無効、デリミタが変えられる)
%Q(string\n) # 「%Q」文字列 (エスケープシーケンスがすべて有効、デリミタが変えられる)

# ヒアドキュメント
<<End
この行はヒアドキュメント
End

# ダブルクオートヒアドキュメント (クオートなしの場合と同じ)
<<"End"
この行はヒアドキュメント
End

# シングルクオートヒアドキュメント (一切のエスケープシーケンスが無効)
<<'End'
この行はヒアドキュメント
End

# 終端記号がインデントされたヒアドキュメント
# シングルクオート、ダブルクオートとの併用も可能
<<-End
この行はヒアドキュメント (終端記号をインデントできる)
   End

破壊的な変更

Ruby の String クラスは mutable です。 つまり、オブジェクト自体を破壊的に変更できます。

「破壊的な変更」とは、あるオブジェクトの内容自体を変化させることです。 例えば文字列のすべての文字を破壊的に大文字へ変更する String#upcase! メソッドの使用例を以下に示します。

a = "string"
b = a
a.upcase!
p a   # => "STRING"
p b   # => "STRING"

この例では、a に対してメソッドを呼んだにも関わらず b も変更されています。 これは、変数 a と b が一つの文字列オブジェクトを指していて、 upcase! メソッドでそのオブジェクト自体が変更されたからです。

upcase! の非破壊版である String#upcase を使った例を以下に示します。 こちらでは a の変更が b に波及しません。

a = "string"
b = a
a = a.upcase
p a   # => "STRING"
p b   # => "string"

一般には、破壊的「ではない」メソッドを 中心に使っていくほうがバグが出にくくなります。

String クラスのメソッドには破壊的なメソッドも非破壊的なメソッドもあります。 破壊的なメソッドの例としては concat, sub!, upcase! などが挙げられます。 非破壊的なメソッドの例としては index, sub, upcase などが挙げられます。

同じ動作で破壊的なメソッドと非破壊的なメソッドの両方が定義されているときは、 破壊的なバージョンには名前の最後に「!」が付いています。 例えば upcase メソッドは非破壊的で、upcase! メソッドは破壊的です。

ただし、この命名ルールを 「破壊的なメソッドにはすべて『!』が付いている」と解釈しないでください。 例えば concat には「!」が付いていませんが、破壊的です。あくまでも、 「『!』が付いているメソッドと付いていないメソッドの両方があるときは、 『!』が付いているほうが破壊的」というだけです。 「『!』が付いているならば破壊的」は常に成立しますが、逆は必ずしも成立しません。

マルチバイト文字列の処理

String クラスは自身を文字の列ではなくバイト列として扱います。 例えば str[1] は str の内容やエンコーディングに関わらず 2 バイトめの数値を返します。

マルチバイト文字列を正しく処理するためには、 原則としてインデックスよりも正規表現を使うメソッド、 例えば String#subString#gsub を中心に用いるべきです。 Ruby の正規表現エンジンはマルチバイト文字列に対応しているので、 正規表現を使って位置を指定すればマルチバイト文字を正しく処理できます。 なお、正規表現を正しく動作させるためには、組み込み変数 $KCODE を文字列のエンコーディングにあわせて設定する必要があります。

また、jcode ライブラリを利用すると String クラスのすべてのメソッドが文字単位で動作するようになります。 しかし jcode ライブラリはプロセス全体に影響するため、 中程度以上の規模プログラムで用いることは推奨できません。

目次

特異メソッド
new
インスタンスメソッド
% * + << concat <=> == =~ [] slice []= bytes each_byte bytesize capitalize capitalize! casecmp center chars each_char chomp chomp! chop chop chop! chop! count crypt delete delete delete! delete! downcase downcase! dump each each_line lines each_char empty? end_with? eql? gsub gsub! hash hex include? index insert inspect intern to_sym length size ljust lstrip lstrip! match next succ next! succ! oct partition replace reverse reverse! rindex rjust rpartition rstrip rstrip! scan slice! split squeeze squeeze squeeze! squeeze! start_with? strip strip! sub sub! succ succ! sum swapcase swapcase! to_f to_i to_s to_str tr tr tr! tr! tr_s tr_s tr_s! tr_s! unpack upcase upcase! upto

特異メソッド

new(string = "") -> String[permalink][rdoc]

string と同じ内容の新しい文字列を作成して返します。 引数を省略した場合は空文字列を生成して返します。

[PARAM] string:
文字列
[RETURN]
引数 string と同じ内容の文字列オブジェクト

インスタンスメソッド

self % args -> String[permalink][rdoc]

printf と同じ規則に従って args をフォーマットします。

args が配列であれば Kernel.#sprintf(self, *args) と同じです。 それ以外の場合は Kernel.#sprintf(self, args) と同じです。

[PARAM] args:
フォーマットする値、もしくはその配列
[RETURN]
フォーマットされた文字列

例:

p "i = %d" % 10       # => "i = 10"
p "i = %x" % 10       # => "i = a"
p "i = %o" % 10       # => "i = 12"

p "i = %#d" % 10      # => "i = 10"
p "i = %#x" % 10      # => "i = 0xa"
p "i = %#o" % 10      # => "i = 012"

p "%d" % 10           # => "10"
p "%d,%o" % [10, 10]  # => "10,12"

sprintf フォーマット

Ruby の sprintf フォーマットは基本的に C 言語の sprintf(3) のものと同じです。ただし、short や long などの C 特有の型に対する修飾子が ないこと、2進数の指示子(%b, %B)が存在すること、sprintf のすべての方言をサ ポートしていないこと(%': 3桁区切り)などの違いがあります。

Ruby には整数の大きさに上限がないので、%b, %B, %o, %x, %X に負の数を与えると (左側に無限に1が続くとみなせるので) ..f のような表示をします。絶対値に符号を付けた形式 で出力するためには %+x、% x のように指定します。

以下は sprintf フォーマットの書式です。[] で囲まれた部分は省略可 能であることを示しています。

%[nth$][フラグ][幅][.精度]指示子

`%' 自身を出力するには `%%' とします。

以下それぞれの要素に関して説明します。

フラグ

フラグには #, +, ' '(スペース), -, 0 の5種類があります。

#

2進、8進、16進の指示子(b, B, o, x, X) ではそれぞれプレフィック スとして "0b", "0B", "0", "0x", "0X" を付加します。 C 言語とは異なり引数が 0 の場合にもプレフィックスが付加されます。

  p sprintf("%#b", 10) #=> "0b1010"
  p sprintf("%#B", 10) #=> "0B1010"
  p sprintf("%#b", 0)  #=> "0b0"
  p sprintf("%#o", 10) #=> "012"
  p sprintf("%#x", 10) #=> "0xa"
  p sprintf("%#X", 10) #=> "0XA"

浮動小数点数 (f, e, E, g, G) に対しては必ず出力に"."をつけます。

  p sprintf("%.0f", 10) #=> "10"
  p sprintf("%#.0f", 10) #=> "10."
  p sprintf("%.0e", 10) #=> "1e+01"
  p sprintf("%#.0e", 10) #=> "1.e+01"

また g, G では上記に加えて末尾の余分な0が残ります。

  p sprintf("%.05g", 10) #=> "10"
  p sprintf("%#.05g", 10) #=> "10.000"
+

出力文字列を符号付きにします。特に正の数では`+'が付加されます。 数値の指示子 (d, i, b, B, o, x, X, u, f, e, E, g, G) に対してだけ意味を持ちます。 また、特に b, B, o, x, X, u に対しては、負数に対して "-" を付加することを示します。

  p sprintf("%d", 1)   #=> "1"
  p sprintf("%+d", 1)  #=> "+1"

  p sprintf("%x", -1)  #=> "..f"  # ".." は無限に f が続くことを表している
  p sprintf("%+x", -1) #=> "-1"
' '(スペース)

`+' と同じですが正の符号 `+' の代わりに空白を用います。数値の指示子 (d, i, b, B, o, x, X, u, f, e, E, g, G) に対してだけ意味を持ちます。

  p sprintf("%d", 1)   #=> "1"
  p sprintf("%+d", 1)  #=> "+1"
  p sprintf("% d", 1)  #=> " 1"

  p sprintf("%x", -1)  #=> "..f"
  p sprintf("% x", 1)  #=> " 1"
  p sprintf("% x", -1) #=> "-1"
-

出力を左詰めにします幅の指定がなければ 意味がありません。

0

出力が右詰めの場合に余った部分に空白の代わりに "0" を詰めます。

数値の指示子の一部(d, i, b, B, o, x, X, u, f, g, G)に対し てだけ意味を持ちます(e, E には意味がない)

  p sprintf("%010d", 10)   #=> "0000000010"

`#' と一緒に指定した場合の出力は以下のようになります。

  p sprintf("%#010x", 10)  #=> "0x0000000a"
  p sprintf("%#010o", 10)  #=> "0000000012"
  p sprintf("%#010b", 10)  #=> "0b00001010"

これは、以下と同じです。

  p sprintf("%#10.8x", 10) #=> "0x0000000a"
  p sprintf("%#10.9o", 10) #=> "0000000012"
  p sprintf("%#10.8b", 10) #=> "0b00001010"

通常は、以下のようになります。

  p sprintf("%#10x", 10)   #=> "       0xa"
  p sprintf("%#10o", 10)   #=> "       012"
  p sprintf("%#10b", 10)   #=> "    0b1010"

0以外の数字で始まる数字列は幅指定になります。幅は生成文字列の長さを示 します。後述の精度の値によらずこの幅分だ けの文字列が生成されます。

幅の指定はフラグで付与される " ", "+", "-", "0b", "0B", "0", "0x", "0X" の長さも考慮されます。

p sprintf("%+5d", 11)  #=> "  +11"
p sprintf("%+-5d", 11) #=> "+11  "
p sprintf("%+05d", 11) #=> "+0011"

幅は「最低限必要な幅」の指定になります。結果の文字列が指定した幅を超 える場合は幅の指定は無効になります。

幅として `*' を指定すると幅の値を引数から得ることになります。

p sprintf("%#05x", 10)    #=> "0x00a"
p sprintf("%#0*x", 5, 10) #=> "0x00a"

精度

"." の後に続く数字列は精度を表します("." のみの場合 ".0" と同じです)。精度は 整数の指示子 (d, i, b, B, o, x, X, u) に対しては、数値列部分の長さを意味します。

p sprintf("%10.5d", 1)  #=> "     00001"
p sprintf("%#10.5x", 1) #=> "   0x00001"
p sprintf("%+10.5x", 1) #=> "    +00001"

浮動小数点数の指示子 (f) に対しては小数部の桁数を意味します。

p sprintf("%10.5f", 1)   #=> "   1.00000"
p sprintf("%10.5f", 10)  #=> "  10.00000"

浮動小数点数の指示子 (e, E, g, G) に対しては有効桁数を意味します。

p sprintf("%10.5e", 1)   #=> "1.00000e+00"
p sprintf("%10.5e", 10)  #=> "1.00000e+01"
p sprintf("%10.5g",  10)  #=> "        10"
p sprintf("%#10.5G", 10)  #=> "    10.000"

文字列の指示子(s, p) に対しては引数の文字列のうち指定した数を超える分を切り捨てます。 幅と精度を同じ値にすれば、どのような引数に対してもその 長さだけの出力を行うことになります。

p sprintf("%10.2s", "foo")  #=> "        fo"

p sprintf("%5.5s", "foo")     #=> "  foo"
p sprintf("%5.5s", "foobar")  #=> "fooba"

精度として `*' を指定すると精度の値を引数から得ることになります。

p sprintf("%.5s", "foobar")    #=> "fooba"
p sprintf("%.*s", 5, "foobar") #=> "fooba"

指示子

指示子は引数の型の解釈を示します。指示子を省略することはできません。 指示子には大きく分けて

があります

c

引数の数値(0〜255)を文字コードとみなして対応する文字を出力します。 引数が数値以外のオブジェクトの場合 to_int メソッドによる変換を試みます。

  p sprintf("%c", 97)  #=> "a"

フラグ `-' と幅 の指定だけが意味を持ちます。

s

文字列を出力します。

引数が String オブジェクトでなければ to_s メソッドにより文字列化 したものを引数として扱います。

p

Object#inspect の結果を出力します。

  p sprintf("%s", /e+/)  #=> "(?-mix:e+)"
  p sprintf("%p", /e+/)  #=> "/e+/"
d
i

引数の数値を10進表現の整数として出力します。

引数が整数でなければ関数 Kernel.#Integer と同じ規則で整数に 変換されます。

  p sprintf("%d", -1) #=> "-1"
  p sprintf("%d", 3.1) #=> "3"
  p sprintf("%d", '0b1010') #=> "10"
u

引数の数値を符号なし整数とみなして10進表現の整数として出力します。

  p sprintf("%u", '0b1010') #=> "10"
  p sprintf("%u", -1) #=> "..4294967295" (warning)
b
B
o
x
X

整数をそれぞれ2進、2進(大文字)、8進、16進、16進(大文字)表現の文字列で出力します。

`#' フラグを指定すれば "0b", "0B", "0", "0x", "0X" を先頭に付加します。

`+', ` ' フラグがない場合、負の数には ".." が先頭(`#' フラグがあれば "0x" などの後)に付加されます。これは最上位桁の文字が無限に続くことを 意味し、2の補数表現で負の数を表しています。

   p sprintf("%#b", 10)    #=> "0b1010"
   p sprintf("%#B", 10)    #=> "0B1010"
   p sprintf("%#o", 10)    #=> "012"
   p sprintf("%#x", 10)    #=> "0xa"
   p sprintf("%#X", 10)    #=> "0XA"

   # 負の数に対して ".." が付加されます
   p sprintf("%#b", -1)    #=> "0b..1"
   p sprintf("%#o", -1)    #=> "0..7"
   p sprintf("%#x", -1)    #=> "0x..f"

   p sprintf("%10x", -1)   #=> "       ..f"
   p sprintf("%-10x", -1)  #=> "..f       "

   # 「精度」を指定した場合、".." は付加されません
   p sprintf("%.10x", -1)  #=> "ffffffffff"
f
e
E
g
G

f は小数点表現(xxx.xxx)で数値を出力します。

e は指数表現(x.xxxe+xx)で数値を出力します。

g は 指数が -4 より小さいか精度以上の場合に e と同じ出力を、それ以 外では f と同じ出力を行います。ただし、小数部の末尾の0は取り除かれ ます。

大文字の指示子(E, G)は出力のアルファベットを大文字にします。

  p sprintf("%f", 1.0) #=> "1.000000"
  p sprintf("%e", 1.0) #=> "1.000000e+00"
  p sprintf("%g", 1.0) #=> "1"

  p sprintf("%f", 10.1) #=> "10.100000"
  p sprintf("%e", 10.1) #=> "1.010000e+01"
  p sprintf("%g", 10.1) #=> "10.1"

  p sprintf("%g", 10 ** 6)  #=> "1e+06"
  p sprintf("%g", 10 ** -5) #=> "1e-05"

精度の省略値は 6 です。

無限大、NaN(Not a Number) に対する出力は以下のとおりです。

  p sprintf("%f",  1.0/0)  #=> "inf"
  p sprintf("%f", -1.0/0)  #=> "-inf"
  p sprintf("%f",  0.0/0)  #=> "nan"

  p sprintf("%E",  1.0/0)  #=> "INF"
  p sprintf("%E", -1.0/0)  #=> "-INF"
  p sprintf("%E",  0.0/0)  #=> "NAN"

f, e, E, g, G に関しては sprintf(3) の結果を利用しています。従って出力結果は 実際にはシステムに依存することになります。

引数指定

利用頻度が低いので最後に説明します。

nth$

nth 番目の引数のフォーマットを行うことを示します。

  p sprintf("%d, %x, %o", 1, 2, 3) #=> "1, 2, 3"
  p sprintf("%3$d, %2$x, %1$o", 1, 2, 3) #=> "3, 2, 1"

  p sprintf("%1$d, %1$x, %1$o", 10) #=> "10, a, 12"

状況によってフォーマットを変えたいが引数の順序を変えたくない場合に使 用します。

  case ENV['LC_TIME']
  when /^ja_JP/
    fmt = "%1$d年%2$d月%3$d日"
  else
    fmt = "%2$02d/%03$2d/%1$02d"
  end

  p sprintf(fmt, 1, 4, 22) #=> "04/22/01"

"*" の後に指定することで幅や 精度を引数で指定することもできます。

  p sprintf("%5.2f", 1)              #=> " 1.00"
  p sprintf("%*.*f", 5, 2, 1)        #=> " 1.00"
  p sprintf("%1$*2$.*3$f", 1, 5, 2)  #=> " 1.00"
self * times -> String[permalink][rdoc]

文字列の内容を times 回だけ繰り返した新しい文字列を作成して返します。

[PARAM] times:
整数
[RETURN]
self を times 回繰り返した新しい文字列
[EXCEPTION] ArgumentError:
引数に負数を指定したときに発生します。

例:

p "str" * 3   # => "strstrstr"

str = "abc"
p str * 4   # => "abcabcabcabc"
p str * 0   # => ""
p str       # => "abc"  (変化なし)
self + other -> String[permalink][rdoc]

文字列と other を連結した新しい文字列を返します。

[PARAM] other:
文字列
[RETURN]
self と other を連結した文字列

例:

p "str" + "ing"   # => "string"

a = "abc"
b = "def"
p a + b   # => "abcdef"
p a       # => "abc"  (変化なし)
p b       # => "def"
self << other -> self[permalink][rdoc]
concat(other) -> self

self に文字列 other を破壊的に連結します。 other が 0 から 255 のまでの整数である場合は その 1 バイトを末尾に追加します (つまり、整数が示す ASCII コードの文字が追加されます)。

self を返します。

[PARAM] other:
文字列もしくは 0 から 255 までの範囲の整数

例:

str = "string"
str.concat "XXX"
p str    # => "stringXXX"

str << "YYY"
p str    # => "stringXXXYYY"

str << 65  # 文字AのASCIIコード
p str    # => "stringXXXYYYA"
self <=> other -> -1 | 0 | 1 | nil[permalink][rdoc]

self と other を ASCII コード順で比較して、 self が大きい時には 1、等しい時には 0、小さい時には -1 を返します。 このメソッドは Comparable モジュールのメソッドを実装するために使われます。

変数 $= の値が真であるときは アルファベットの大文字小文字を無視して比較します。 ただし $= 変数はいずれ廃止されることが決まっているので $= に頼るべきではありません。 代わりに String#casecmp を使ってください。

other が文字列でない場合、 other.to_str と other.<=> が定義されていれば 0 - (other <=> self) の結果を返します。 そうでなければ nil を返します。

[PARAM] other:
文字列
[RETURN]
比較結果の整数か nil

例:

p "aaa" <=> "xxx"   # => -1
p "aaa" <=> "aaa"   # => 0
p "xxx" <=> "aaa"   # => 1

p "string" <=> "stringAA"  # => -1
p "string" <=> "string"    # => 0
p "stringAA" <=> "string"  # => 1
self == other -> bool[permalink][rdoc]

other が文字列の場合、String#eql? と同様に文字列の内容を比較します。

変数 $= の値が真であるときは アルファベットの大文字小文字を無視して比較します。 ただし $= 変数はいずれ廃止されることが決まっているので $= に頼るべきではありません。

other が文字列でない場合、 other.to_str が定義されていれば other == self の結果を返します。(ただし、 other.to_str は実行されません。) そうでなければ false を返します。

[PARAM] other:
任意のオブジェクト
[RETURN]
true か false

例:

stringlike = Object.new

def stringlike.==(other)
  "string" == other
end

p "string".eql?(stringlike) #=> false
p "string" == stringlike    #=> false

def stringlike.to_str
  raise
end

p "string".eql?(stringlike) #=> false
p "string" == stringlike    #=> true

[SEE_ALSO] String#eql?

self =~ other -> Integer[permalink][rdoc]

正規表現 other とのマッチを行います。 マッチが成功すればマッチした位置のインデックスを、そうでなければ nil を返します。

other が正規表現でも文字列でもない場合は other =~ self を行います。

このメソッドが実行されると、組み込み変数 $~, $1, ... にマッチに関する情報が設定されます。

[PARAM] other:
正規表現もしくは =~ メソッドを持つオブジェクト
[EXCEPTION] TypeError:
other が文字列の場合に発生します。

例:

p "string" =~ /str/   # => 0
p "string" =~ /not/   # => nil
p "abcfoo" =~ /foo/   # => 3
self[nth] -> Integer | nil[permalink][rdoc]
slice(nth) -> Integer | nil

nth 番目のバイトを整数 (文字コード) で返します。 nth が負の場合は文字列の末尾から数えます。 つまり、 self.size + nth 番目のバイトを返します。

nth が範囲外を指す場合は nil を返します。

[PARAM] nth:
バイトインデックスを表す整数
[RETURN]
文字コードを表す整数

例:

p 'bar'[2]        # => 114
p 'bar'[2] == ?r  # => true
p 'bar'[-1]       # => 114

p 'bar'[3]        # => nil
p 'bar'[-4]       # => nil

このメソッドの逆に文字コードから文字列を得るには Integer#chr を使ってください。

self[nth, len] -> String | nil[permalink][rdoc]
slice(nth, len) -> String | nil

nth バイト番目から長さ len バイトの部分文字列を新しく作って返します。 nth が負の場合は文字列の末尾から数えます。

[PARAM] nth:
取得したい文字列の開始インデックスを整数で指定します。
[PARAM] len:
取得したい文字列の長さを正の整数で指定します。
[RETURN]
nth が範囲外を指す場合は nil を返します。

例:

str0 = "bar"
str0[2, 1]         #=> "r"
str0[2, 0]         #=> ""
str0[2, 100]       #=> "r"  (右側を超えても平気)
str0[2, 1] == ?r   #=> false  (左辺は長さ1の文字列、右辺は整数の文字コード)
str0[-1, 1]        #=> "r"
str0[-1, 2]        #=> "r" (あくまでも「右に向かって len バイト」)

str0[3, 1]         #=> ""
str0[4, 1]         #=> nil
str0[-4, 1]        #=> nil
str1 = str0[0, 2]    # (str0 の「一部」を str1 とする)
str1               #=> "ba"
str1[0] = "XYZ"
str1               #=> "XYZa" (str1 の内容が破壊的に変更された)
str0               #=> "bar" (str0 は無傷、 str1 は str0 と内容を共有していない)
self[substr] -> String | nil[permalink][rdoc]
slice(substr) -> String | nil

self が substr を含む場合、一致した文字列を新しく作って返します。 substr を含まなければ nil を返します。

[PARAM] substr:
取得したい文字列のパターン。文字列

例:

substr = "bar"
result = "foobar"[substr]
p result   # => "bar"
p substr.equal?(result)   # => false
self[regexp, nth = 0] -> String[permalink][rdoc]
slice(regexp, nth = 0) -> String

正規表現 regexp の nth 番目の括弧にマッチする最初の部分文字列を返します。 nth を省略したときや 0 の場合は正規表現がマッチした部分文字列全体を返します。 正規表現が self にマッチしなかった場合や nth に対応する括弧がないときは nil を返します。

このメソッドを実行すると、 マッチ結果に関する情報が組み込み変数 $~ に設定されます。

[PARAM] regexp:
取得したい文字列のパターンを示す正規表現
[PARAM] nth:
取得したい正規表現レジスタのインデックス。整数
p "foobar"[/bar/]  # => "bar"
p $~.begin(0)      # => 3

p "def getcnt(line)"[ /def\s+(\w+)/, 1 ]   # => "getcnt"
self[range] -> String[permalink][rdoc]
slice(range) -> String

rangeで指定したインデックスの範囲に含まれる部分文字列を返します。

[PARAM] range:
取得したい文字列の範囲を示す Range オブジェクト

rangeオブジェクトが終端を含む場合

インデックスと文字列の対応については以下の対照図も参照してください。

  0   1   2   3   4   5   (インデックス)
 -6  -5  -4  -3  -2  -1   (負のインデックス)
| a | b | c | d | e | f |
|<--------->|                'abcdef'[0..2]  # => 'abc'
                |<----->|    'abcdef'[4..5]  # => 'ef'
        |<--------->|        'abcdef'[2..4]  # => 'cde'

range.last が文字列の長さ以上のときは (文字列の長さ - 1) を指定したものとみなされます。

range.first が 0 より小さいか文字列の長さより大きいときは nil を 返します。ただし range.first および range.last のどちらか または両方が負の数のときは一度だけ文字列の長さを足して 再試行します。

例:

'abcd'[ 2 ..  1] # => ""
'abcd'[ 2 ..  2] # => "c"
'abcd'[ 2 ..  3] # => "cd"
'abcd'[ 2 ..  4] # => "cd"

'abcd'[ 2 .. -1] # => "cd"   # str[f..-1] は「f 文字目から
'abcd'[ 3 .. -1] # => "d"    # 文字列の最後まで」を表す慣用句

'abcd'[ 1 ..  2] # => "bc"
'abcd'[ 2 ..  2] # => "c"
'abcd'[ 3 ..  2] # => ""
'abcd'[ 4 ..  2] # => ""
'abcd'[ 5 ..  2] # => nil

'abcd'[-3 ..  2] # => "bc"
'abcd'[-4 ..  2] # => "abc"
'abcd'[-5 ..  2] # => nil

rangeオブジェクトが終端を含まない場合

文字列と「隙間」の関係については以下の模式図を参照してください。

 0   1   2   3   4   5   6  (隙間番号)
-6  -5  -4  -3  -2  -1      (負の隙間番号)
 | a | b | c | d | e | f |
 |<--------->|                'abcdef'[0...3]  # => 'abc'
                 |<----->|    'abcdef'[4...6]  # => 'ef'
         |<--------->|        'abcdef'[2...5]  # => 'cde'

range.last が文字列の長さよりも大きいときは文字列の長さを 指定したものとみなされます。

range.first が 0 より小さいか文字列の長さより大きいときは nil を返します。 ただし range.first と range.last のどちらかまたは両方が負の数 であるときは一度だけ文字列の長さを足して再試行します。

例:

'abcd'[ 2 ... 3] # => "c"
'abcd'[ 2 ... 4] # => "cd"
'abcd'[ 2 ... 5] # => "cd"

'abcd'[ 1 ... 2] # => "b"
'abcd'[ 2 ... 2] # => ""
'abcd'[ 3 ... 2] # => ""
'abcd'[ 4 ... 2] # => ""
'abcd'[ 5 ... 2] # => nil

'abcd'[-3 ... 2] # => "b"
'abcd'[-4 ... 2] # => "ab"
'abcd'[-5 ... 2] # => nil
self[nth] = val[permalink][rdoc]

nth 番目のバイトを文字列 val で置き換えます。

val が 0 から 255 の範囲の整数である場合、 文字コードとみなしてその文字で置き換えます。

[PARAM] nth:
置き換えたいバイトのインデックス
[PARAM] val:
指定バイトと置き換える文字列もしくはバイト
[RETURN]
val を返します。

例:

buf = "string"
buf[1] = "!!"
p buf   # => "s!!ring"
self[nth, len] = val[permalink][rdoc]

nth バイト番目から長さ len バイトの部分文字列を文字列 val で置き換えます。

len が0 の場合は、単にnthの位置から文字列の追加が行われます。 nth が負の場合は文字列の末尾から数えます。

[PARAM] nth:
置き換えたい部分文字列の開始インデックス
[PARAM] len:
置き換えたい部分文字列の長さ
[PARAM] val:
指定範囲の部分文字列と置き換える文字列
[RETURN]
val を返します。

例:

buf = "string"
buf[1, 4] = "!!"
p buf   # => "s!!g"

buf = "string"
buf[1, 0] = "!!"
p buf   # => "s!!tring"
self[substr] = val[permalink][rdoc]

文字列中の substr に一致する最初の部分文字列を文字列 val で置き換えます。

[PARAM] substr:
置き換えたい部分文字列のパターンを示す文字列
[PARAM] val:
指定範囲の部分文字列と置き換える文字列
[RETURN]
val を返します。
[EXCEPTION] IndexError:
self が部分文字列 substr を含まない場合に発生します。

例:

buf = "string"
buf["trin"] = "!!"
p buf   # => "s!!g"

buf = "string"
buf["nosuchstring"] = "!!"   # IndexError
self[regexp, nth] = val[permalink][rdoc]

正規表現 regexp の nth 番目の括弧にマッチする 最初の部分文字列を文字列 val で置き換えます。

nth が 0 の場合は、マッチした部分文字列全体を val で置き換えます。

[PARAM] regexp:
置き換えたい部分文字列のパターンを示す正規表現
[PARAM] nth:
置き換えたい部分文字列のパターンを示す正規表現レジスタの番号
[PARAM] val:
指定範囲の部分文字列と置き換えたい文字列
[RETURN]
val を返します。
[EXCEPTION] IndexError:
正規表現がマッチしなかった場合に発生します。

例:

buf = "def exec(cmd)"
buf[/def\s+(\w+)/, 1] = "preprocess"
p buf    # => "def preprocess(cmd)"
self[regexp] = val[permalink][rdoc]

正規表現 regexp にマッチした部分文字列全体を val で置き換えます。

[PARAM] regexp:
置き換えたい部分文字列のパターンを示す正規表現
[PARAM] val:
置き換えたい文字列
[RETURN]
val を返します。
[EXCEPTION] IndexError:
正規表現がマッチしなかった場合に発生します。

例:

buf = "string"
buf[/tr../] = "!!"
p buf   # => "s!!g"
self[range] = val[permalink][rdoc]

rangeで指定したインデックスの範囲に含まれる部分文字列を文字列 val で置き換えます。

[PARAM] range:
置き換えたい範囲を示す Range オブジェクト
[RETURN]
val を返します。
each_byte {|byte| ... } -> self[permalink][rdoc]
bytes {|byte| ... } -> self
each_byte -> Enumerable::Enumerator
bytes -> Enumerable::Enumerator

文字列の各バイトに対して繰り返します。

例:

"str".each_byte do |byte|
  p byte
end
    # => 115
    # => 116
    # => 114
bytesize -> Integer[permalink][rdoc]

文字列のバイト長を整数で返します。

例:

#coding:UTF-8
# 実行結果は文字コードによって異なります。
p "いろは".size     #=> 6
p "いろは".bytesize #=> 9

[SEE_ALSO] String#size

capitalize -> String[permalink][rdoc]

文字列先頭の文字を大文字に、残りを小文字に変更した文字列を返します。 ただし、アルファベット以外の文字は位置に関わらず変更しません。

例:

p "foobar--".capitalize   # => "Foobar--"
p "fooBAR--".capitalize   # => "Foobar--"
p "FOOBAR--".capitalize   # => "Foobar--"

$KCODE が適切に設定されていない場合は、 マルチバイト文字の一部をあやまって変換してしまう場合があります。 この問題は以下のように Shift JIS エンコーディングを使う場合に発生します。

$KCODE = 'NONE'
# 文字列は Shift JIS エンコーディングで記述されている
puts "帰".capitalize   # => 蟻

また、$KCODE を設定しても、 マルチバイト文字のいわゆる全角アルファベットは処理しません。

[SEE_ALSO] String#capitalize!, String#upcase, String#downcase, String#swapcase

capitalize! -> self | nil[permalink][rdoc]

文字列先頭の文字を大文字に、残りを小文字に変更します。 ただし、アルファベット以外の文字は位置に関わらず変更しません。

[RETURN]
capitalize! は self を変更して返しますが、 変更が起こらなかった場合は nil を返します。

例:

str = "foobar"
str.capitalize!
p str   # => "Foobar"

str = "fooBAR"
str.capitalize!
p str   # => "Foobar"

$KCODE が適切に設定されていない場合は、 マルチバイト文字の一部をあやまって変換してしまう場合があります。 この問題は以下のように Shift JIS エンコーディングを使う場合に発生します。

$KCODE = 'NONE'
# 文字列は Shift JIS エンコーディングで記述されている
str = "帰"
str.capitalize!
puts str   # => 蟻

また、$KCODE を設定しても、 マルチバイト文字のいわゆる全角アルファベットは処理しません。

[SEE_ALSO] String#capitalize, String#upcase!, String#downcase!, String#swapcase!

casecmp(other) -> Integer | nil[permalink][rdoc]

String#<=> と同様に文字列の順序を比較しますが、 アルファベットの大文字小文字の違いを無視します。

このメソッドの動作は組み込み変数 $= には影響されません。

[PARAM] other:
self と比較する文字列

例:

p 'a' <=> 'A'       # => 1
p 'a'.casecmp('A')  # => 0

[SEE_ALSO] String#<=>

center(width, padding = ' ') -> String[permalink][rdoc]

長さ width の文字列に self を中央寄せした文字列を返します。 self の長さが width より長い時には元の文字列の複製を返します。 また、第 2 引数 padding を指定したときは 空白文字の代わりに padding を詰めます。

[PARAM] width:
返り値の文字列の最小の長さ
[PARAM] padding:
長さが width になるまで self の両側に詰める文字

例:

p "foo".center(10)       # => "   foo    "
p "foo".center(9)        # => "   foo   "
p "foo".center(8)        # => "  foo   "
p "foo".center(7)        # => "  foo  "
p "foo".center(3)        # => "foo"
p "foo".center(2)        # => "foo"
p "foo".center(1)        # => "foo"
p "foo".center(10, "*")  # => "***foo****"

[SEE_ALSO] String#ljust, String#rjust

each_char {|cstr| block } -> self[permalink][rdoc]
chars {|cstr| block } -> self
each_char -> Enumerable::Enumerator
chars -> Enumerable::Enumerator

文字列の各文字に対して繰り返します。 $KCODE が適切に設定されていれば、マルチバイト文字も正しく扱われます。

たとえば、

"hello世界".each_char {|c| print c, ' ' }

は次のように出力されます。

h e l l o 世 界
chomp(rs = $/) -> String[permalink][rdoc]

self の末尾から rs で指定する改行コードを取り除いた文字列を生成して返します。 ただし、rs が "\n" ($/ のデフォルト値) のときは、 実行環境によらず "\r", "\r\n", "\n" のすべてを改行コードとみなして取り除きます。

rs に nil を指定した場合、このメソッドは何もしません。

rs に空文字列 ("") を指定した場合は「パラグラフモード」になり、 末尾の連続する改行コードをすべて取り除きます。

例:

p "foo\n".chomp             # => "foo"
p "foo\n".chomp("\n")       # => "foo"
p "foo\r\n".chomp("\r\n")   # => "foo"

$/ = "\n"   # デフォルト値と同じ
p "foo\r".chomp    # => "foo"
p "foo\r\n".chomp  # => "foo"
p "foo\n".chomp    # => "foo"
p "foo\n\r".chomp  # => "foo\n"
chomp!(rs = $/) -> self | nil[permalink][rdoc]

self の末尾から rs で指定する改行コードを取り除きます。 ただし rs が "\n" ($/ のデフォルト値) のときは、 システムによらず "\r", "\r\n", "\n" のすべてを改行コードとみなして取り除きます。

rs に nil を指定した場合、このメソッドは何もしません。

rs に空文字列 ("") を指定した場合は「パラグラフモード」になり、 末尾の連続する改行コードをすべて取り除きます。

[RETURN]
chomp! は通常 self を返しますが、取り除く改行がなかった場合は nil を返します。

例:

buf = "string\n"
buf.chomp!
p buf   # => "string"

$/ = "\n"   # デフォルトと同じ
p "foo\r".chomp!    # => "foo"
p "foo\r\n".chomp!  # => "foo"
p "foo\n".chomp!    # => "foo"
p "foo\n\r".chomp!  # => "foo\n"
chop -> String[permalink][rdoc]

文字列の最後の文字を取り除いた新しい文字列を生成して返します。 ただし、文字列の終端が "\r\n" であればその 2 文字を取り除きます。

例:

p "string\n".chop    # => "string"
p "string\r\n".chop  # => "string"
p "string".chop      # => "strin"
p "strin".chop       # => "stri"
p "".chop            # => ""
chop -> String[permalink][rdoc] [redefined by jcode]

String#chop の日本語対応版です。

例:

#!/usr/bin/env ruby

$KCODE = 'e'
zstr = 'ABCDEF'
hoge = 'hogehoge'

p zstr.chop       # => "ABCDE\243"
p hoge.chop       # => "hogehog"

require 'jcode'
p zstr.chop       # => "ABCDE"
p hoge.chop       # => "hogehog"
chop! -> self | nil[permalink][rdoc]

文字列の最後の文字を取り除きます。 ただし、終端が "\r\n" であればその 2 文字を取り除きます。

[RETURN]
chop! は self を変更して返しますが、取り除く文字がなかった場合は nil を返します。
chop! -> self | nil[permalink][rdoc] [redefined by jcode]

String#chop! の日本語対応版です。

count(*chars) -> Integer[permalink][rdoc]

chars で指定された文字が文字列 self にいくつあるか数えます。

検索する文字を示す引数 chars の形式は tr(1) と同じです。 つまり、「"a-c"」は文字 a から c を意味し、 「"^0-9"」のように文字列の先頭が「^」の場合は 指定文字以外を意味します。

文字「-」は文字列の両端にない場合にだけ範囲指定の意味になります。 同様に、「^」も文字列の先頭にあるときだけ否定の効果を発揮します。 また、「-」「^」「\」は バックスラッシュ (「\」) によりエスケープできます。

引数を複数指定した場合は、 すべての引数にマッチした文字だけを数えます。

[PARAM] chars:
出現回数を数える文字のパターン

例:

p 'abcdefg'.count('c')               # => 1
p '123456789'.count('2378')          # => 4
p '123456789'.count('2-8', '^4-6')   # => 4

# ファイルの行数を数える
n_lines = File.open("foo").read.count("\n")

# ファイルの末尾に改行コードがない場合にも対処する
buf = File.open("foo").read
n_lines = buf.count("\n")
n_lines += 1 if /[^\n]\z/ =~ buf
    # if /\n\z/ !~ buf だと空ファイルを 1 行として数えてしまうのでダメ
crypt(salt) -> String[permalink][rdoc]

self と salt から暗号化された文字列を生成して返します。 salt には英数字、ドット (「.」)、スラッシュ (「/」) から構成される、 2 バイト以上の文字列を指定します。

暗号化された文字列から暗号化前の文字列 (self) を求めることは一般に困難で、 self を知っている者のみが同じ暗号化された文字列を生成できます。 このことから self を知っているかどうかの認証に使うことが出来ます。

salt には、以下の様になるべくランダムな文字列を選ぶべきです。 他にも [ruby-list:29297] などがあります。

注意:

[PARAM] salt:
文字列を暗号化するための鍵となる文字列。 英数字・「.」・「/」のいずれかで構成される 2 バイト以上の文字列

例:

# パスワードの暗号化
salt = [rand(64),rand(64)].pack("C*").tr("\x00-\x3f","A-Za-z0-9./")
passwd.crypt(salt)

# UNIX のログイン認証
require 'etc'

def valid_login?(user, password)
  ent = Etc.getpwnam(user)
  password.crypt(ent.passwd) == ent.passwd
end

p valid_login?("taro", "password")   # => 真偽値が得られる
delete(*strs) -> String[permalink][rdoc]

self から strs に含まれる文字を取り除いた文字列を生成して返します。

str の形式は tr(1) と同じです。 つまり、`a-c' は a から c を意味し、"^0-9" のように 文字列の先頭が `^' の場合は指定文字以外を意味します。

「-」は文字列の両端にない場合にだけ範囲指定の意味になります。 「^」も文字列の先頭にあるときだけ効果を発揮します。 また、「-」「^」「\」はバックスラッシュ (「\」) によってエスケープできます。

なお、引数を複数指定した場合は、 すべての引数にマッチする文字だけが削除されます。

[PARAM] strs:
削除する文字列を示す文字列 (のリスト)

例:

p "123456789".delete("2378")         #=> "14569"
p "123456789".delete("2-8", "^4-6")  #=> "14569"
delete(str) -> String[permalink][rdoc] [redefined by jcode]

String#delete の日本語対応版です。 指定したパターンの文字列を取り除きます。

ただしこのメソッドは置き換え前の物とは異なり 複数の引数を取れません。

[PARAM] str:
取り除く文字のパターン。

例:

#!/usr/bin/env ruby

$KCODE = 'EUC'
zstr = 'ABCDEF'
hoge = 'hogehoge'

p zstr.delete("A")  # => "唾津\306"
p hoge.delete("e")   # => "hoghog"

require 'jcode'
p zstr.delete("A")  # => "BCDEF"
p hoge.delete("e")   # => "hoghog"
delete!(str) -> self|nil[permalink][rdoc] [redefined by jcode]

String#delete! の日本語対応版です。 指定したパターンの文字列を破壊的に取り除きます。

ただしこのメソッドは置き換え前の物とは異なり 複数の引数を取れません。

[PARAM] str:
取り除く文字のパターン。
delete!(*strs) -> self | nil[permalink][rdoc]

self から strs に含まれる文字を破壊的に取り除きます。

str の形式は tr(1) と同じです。 つまり、「a-c」は a から c を意味し、"^0-9" のように 文字列の先頭が「^」の場合は指定文字以外を意味します。

「-」は文字列の両端にない場合にだけ範囲指定の意味になります。 「^」も文字列先頭にあるときだけ否定の効果を発揮します。 また、「-」「^」「\」はバックスラッシュ (「\」) によってエスケープできます。

なお、引数を複数指定した場合は、 すべての引数にマッチする文字だけが削除されます。

[RETURN]
通常は self を返しますが、何も変更が起こらなかった場合は nil を返します。
[PARAM] strs:
削除する文字列を示す文字列 (のリスト)

例:

p "123456789".delete("2-8", "^4-6")  #=> "14569"
p "123456789".delete("2378")         #=> "14569"
downcase -> String[permalink][rdoc]

'A' から 'Z' までの アルファベット大文字をすべて小文字に置き換えた新しい文字列を生成して返します。 アルファベット大文字以外の文字はすべてそのまま保存されます。

このメソッドはマルチバイト文字列を認識しますが、 それはあくまでも「1 文字を 1 文字として認識する」だけであって、 いわゆる全角アルファベットの大文字小文字までは変換しません。

処理する文字列の文字コードが Shift JIS で、 しかも $KCODE が適切に設定されていない場合、 このメソッドはマルチバイト文字の一部も変換してしまう場合があります。 逆に、$KCODE を適切に設定しても マルチバイト文字のアルファベットは処理できません。

例:

p "STRing?".downcase   # => "string?"

# -*- encoding: shift_jis -*-
$KCODE = 'n'
puts "帰".downcase   # => 蟻

[SEE_ALSO] String#downcase!, String#upcase, String#swapcase, String#capitalize

downcase! -> self | nil[permalink][rdoc]

文字列中の 'A' から 'Z' までの アルファベット大文字をすべて破壊的に小文字に置き換えます。 アルファベット大文字以外の文字はすべてそのまま保存されます。

このメソッドはマルチバイト文字列を認識しますが、 それはあくまでも「1 文字を 1 文字として認識する」だけであって、 いわゆる全角アルファベットの大文字小文字までは変換しません。

処理する文字列の文字コードが Shift JIS で、 しかも $KCODE が適切に設定されていない場合、 このメソッドはマルチバイト文字の一部も変換してしまう場合があります。 逆に、$KCODE を適切に設定しても マルチバイト文字のアルファベットは処理できません。

[RETURN]
self を変更して返します。変更が無かった場合は nil を返します。

例:

str = "STRing?"
str.downcase!
p str   # => "string?"

# -*- encoding: shift_jis -*-
$KCODE = 'n'
str = "帰"
str.downcase!
puts str   # => 蟻

[SEE_ALSO] String#downcase, String#upcase!, String#swapcase!, String#capitalize!

dump -> String[permalink][rdoc]

文字列中の非表示文字をバックスラッシュ記法に置き換えた文字列を返します。 str == eval(str.dump) となることが保証されています。

例:

# p だとさらにバックスラッシュが増えて見にくいので puts している
puts "abc\r\n\f\x00\b10\\\"".dump   # => "abc\r\n\f\000\01010\\\""
each(rs = $/) {|line| ... } -> self[permalink][rdoc]
each_line(rs = $/) {|line| ... } -> self
lines(rs = $/) {|line| ... } -> self
each(rs = $/) -> Enumerable::Enumerator
each_line(rs = $/) -> Enumerable::Enumerator
lines(rs = $/) -> Enumerable::Enumerator

文字列中の各行に対して繰り返します。 行の区切りは rs に指定した文字列で、 そのデフォルト値は変数 $/ の値です。 各 line には区切りの文字列も含みます。

rs に nil を指定すると行区切りなしとみなします。 rs に空文字列 "" を指定すると「パラグラフモード」になり、 改行コードが 2 つ以上連続するところで文字列を分割します (つまり空行で分割します)。

[PARAM] rs:
行末を示す文字列

例:

"aa\nbb\ncc\n".each_line do |line|
  p line
end
    # => "aa\n"
    # => "bb\n"
    # => "cc\n"

p "aa\nbb\ncc\n".lines.to_a   # => ["aa\n", "bb\n", "cc\n"]
p "aa\n".lines.to_a           # => ["aa\n"]
p "".lines.to_a               # => []

s = "aa\nbb\ncc\n"
p s.lines("\n").to_a #=> ["aa\n", "bb\n", "cc\n"]
p s.lines("bb").to_a #=> ["aa\nbb", "\ncc\n"]
each_char -> [String][permalink][rdoc] [redefined by jcode]
each_char {|char| ... } -> String [redefined by jcode]

文字列中の各文字に対してブロックを呼びだします。 ブロックを指定せずに呼び出された時には、各文字の配列を返します。

例:

#!/usr/bin/env ruby

$KCODE = 'EUC'

require 'jcode'

zstr = 'ABCDEF'
zstr.each_char do |x|
  print "+#{x}+"
end                     # => +A++B++C++D++E++F+
empty? -> bool[permalink][rdoc]

文字列が空 (つまり長さ 0) の時、真を返します。

end_with?(*strs) -> bool[permalink][rdoc]

self の末尾が strs のいずれかであるとき true を返します。

[PARAM] strs:
パターンを表す文字列 (のリスト)

例:

"string".end_with?("ing")          # => true
"string".end_with?("str")          # => false
"string".end_with?("str", "ing")   # => true

[SEE_ALSO] String#start_with?

eql?(other) -> bool[permalink][rdoc]

文字列の内容が文字列 other の内容と等しいときに true を返します。 等しくなければ false を返します。

このメソッドは文字列の内容を比較します。 同一のオブジェクトかどうかを比較するわけではありません。 つまり、"string".eql?(str) という式を実行した場合には、 str が "string" という内容の文字列でありさえすれば常に true を返します。 同一のオブジェクトであるかどうかを判定したいときは Object#equal? を使ってください。

アルファベットの大文字小文字を無視して比較したい場合は、String#upcase, String#downcase で大文字小文字を揃えてから比較してください。

Hash クラス内での比較に使われます。

このメソッドの動作は組み込み変数 $= には影響されません。

[PARAM] other:
任意のオブジェクト
[RETURN]
true か false

例:

p "string".eql?("string")  # => true
p "string".eql?("STRING")  # => false
p "string".eql?("")        # => false
p "".eql?("string")        # => false

p "string".eql?("str" + "ing")   # => true   (内容が同じなら true)
p "string".eql?("stringX".chop)  # => true   (内容が同じなら true)

p "string".upcase.eql?("String".upcase)     # => true
p "string".downcase.eql?("String".downcase) # => true

[SEE_ALSO] Hash, String#<=>, String#casecmp, String#==

gsub(pattern, replace) -> String[permalink][rdoc]

文字列中で pattern にマッチする部分全てを 文字列 replace で置き換えた文字列を生成して返します。

置換文字列 replace 中の \& と \0 はマッチした部分文字列に、 \1 ... \9 は n 番目の括弧の内容に置き換えられます。 置換文字列内では \`、\'、\+ も使えます。 これらは $`$'$+ に対応します。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[PARAM] replace:
pattern で指定した文字列と置き換える文字列

例:

p 'abcdefg'.gsub(/def/, '!!')          # => "abc!!g"
p 'abcabc'.gsub(/b/, '<<\&>>')         # => "a<<b>>ca<<b>>c"
p 'xxbbxbb'.gsub(/x+(b+)/, 'X<<\1>>')  # => "X<<bb>>X<<bb>>"
p '2.5'.gsub('.', ',') # => "2,5"

注意:

第 2 引数 replace に $1 を埋め込んでも意図した結果にはなりません。 この文字列が評価される時点ではまだ正規表現マッチが行われておらず、 $1 がセットされていないからです。

また、gsub では「\」が部分文字列との置き換えという特別な意味を持つため、 replace に「\」自身を入れたいときは 「\」を二重にエスケープしなければなりません。

# ひとつめの括弧の内容に置き換えるときによくある間違い
p 'xbbb-xbbb'.gsub(/x(b+)/, "#{$1}")   # => "-"        # NG
p 'xbbb-xbbb'.gsub(/x(b+)/, "\1")      # => "1-1"      # NG
p 'xbbb-xbbb'.gsub(/x(b+)/, "\\1")     # => "bbb-bbb"  # OK
p 'xbbb-xbbb'.gsub(/x(b+)/, '\1')      # => "bbb-bbb"  # OK
p 'xbbb-xbbb'.gsub(/x(b+)/, '\\1')     # => "bbb-bbb"  # OK

# バックスラッシュを倍にするときによくある間違い
puts '\n'.gsub(/\\/, "\\\\")      # => \n   # NG
puts '\n'.gsub(/\\/, '\\\\')      # => \n   # NG
puts '\n'.gsub(/\\/, "\\\\\\\\")  # => \\n  # OK
puts '\n'.gsub(/\\/, '\\\\\\\\')  # => \\n  # OK

このような間違いを確実に防止し、コードの可読性を上げるには、 \& や \1 よりも下記のようにブロック付き形式の gsub を使うべきです。

p 'xbbb-xbbb'.gsub(/x(b+)/) { $1 }   # => "bbb-bbb"  # OK

puts '\n'.gsub(/\\/) { '\\\\' }      # => \\n        # OK

[SEE_ALSO] String#sub

gsub(pattern) {|matched| .... } -> String[permalink][rdoc]
gsub(pattern) -> Enumerable::Enumerator

文字列中で pattern にマッチした部分を順番にブロックに渡し、 その実行結果で置き換えた文字列を生成して返します。 ブロックなしの場合と違い、ブロックの中からは 組み込み変数 $1, $2, $3, ... を問題なく参照できます。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[RETURN]
新しい文字列

例:

p 'abcabc'.gsub(/[bc]/) {|s| s.upcase }  #=> "aBCaBC"
p 'abcabc'.gsub(/[bc]/) { $&.upcase }    #=> "aBCaBC"

[SEE_ALSO] String#sub

gsub!(pattern, replace) -> self | nil[permalink][rdoc]

文字列中で pattern にマッチする部分全てを文字列 replace に破壊的に置き換えます。

置換文字列 replace 中の \& と \0 はマッチした部分文字列に、 \1 ... \9 は n 番目の括弧の内容に置き換えられます。 置換文字列内では \`、\'、\+ も使えます。 これらは $`$'$+ に対応します。

gsub! は通常 self を変更して返しますが、 置換が起こらなかった場合は nil を返します。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[PARAM] replace:
pattern で指定した文字列と置き換える文字列
[RETURN]
置換した場合は self、置換しなかった場合は nil

例:

buf = "String-String"
buf.gsub!(/in./, "!!")
p buf   # => "Str!!-Str!!"

buf = "String.String"
buf.gsub!(/in./, '<<\&>>')
p buf   # => "Str<<ing>>-Str<<ing>>"

注意:

引数 replace の中で $1 を使うことはできません。 replace は gsub メソッドの呼び出しより先に評価されるので、 まだ gsub の正規表現マッチが行われておらず、 $1 がセットされていないからです。

また、gsub では「\」が部分文字列との置き換えという特別な意味を持つため、 replace に「\」自身を入れたいときは 「\」を二重にエスケープしなければなりません。

例:

# ひとつめの括弧にマッチした部分に置き換えるときによくやる間違い
'abbbcd'.gsub!(/a(b+)/, "#{$1}")       # NG
'abbbcd'.gsub!(/a(b+)/, "\1")          # NG
'abbbcd'.gsub!(/a(b+)/, "\\1")         # OK
'abbbcd'.gsub!(/a(b+)/, '\\1')         # OK
'abbbcd'.gsub!(/a(b+)/, '\1')          # OK
'abbbcd'.gsub!(/a(b+)/) { $1 }         # OK   これがもっとも安全

[SEE_ALSO] String#sub

gsub!(pattern) {|matched| .... } -> self | nil[permalink][rdoc]
gsub!(pattern) -> Enumerable::Enumerator

文字列中で pattern にマッチする部分全てを順番にブロックに渡し、 その評価結果に置き換えます。

また、ブロックなしの場合と違い、ブロックの中からは 組み込み変数 $1, $2, $3, ... を問題なく参照できます。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[RETURN]
置換した場合は self、置換しなかった場合は nil

例:

str = 'abcabc'
str.gsub!(/b/) {|s| s.upcase }
p str    #=> "aBcaBc"

str = 'abcabc'
str.gsub!(/b/) { $&.upcase }
p str    #=> "aBcaBc"

[SEE_ALSO] String#sub

hash -> Integer[permalink][rdoc]

self のハッシュ値を返します。 eql? で等しい文字列は、常にハッシュ値も等しくなります。

[SEE_ALSO] Hash

hex -> Integer[permalink][rdoc]

文字列に 16 進数で数値が表現されていると解釈して整数に変換します。 接頭辞 "0x", "0X" とアンダースコアは無視されます。 文字列が [_0-9a-fA-F] 以外の文字を含むときはその文字以降を無視します。

self が空文字列のときは 0 を返します。

例:

p "10".hex    # => 16
p "ff".hex    # => 255
p "0x10".hex  # => 16
p "-0x10".hex # => -16

p "xyz".hex   # => 0
p "10z".hex   # => 16
p "1_0".hex   # => 16

p "".hex      # => 0

[SEE_ALSO] String#oct, String#to_i, String#to_f, Kernel.#Integer, Kernel.#Float

このメソッドの逆に数値を文字列に変換するには Kernel.#sprintf, String#%, Integer#to_s などを使ってください。

include?(substr) -> bool[permalink][rdoc]

文字列中に部分文字列 substr が含まれていれば真を返します。

substr が 0 から 255 の範囲の Fixnum の場合、 文字コードとみなして、その文字が含まれていれば真を返します。

[PARAM] substr:
検索する文字列もしくは文字コードを表す整数
index(pattern, pos = 0) -> Integer[permalink][rdoc]

文字列のインデックス pos から右に向かって pattern を検索し、 最初に見つかった部分文字列の左端のインデックスを返します。 見つからなければ nil を返します。

引数 pattern は探索する部分文字列、 正規表現、文字コードを示す 0 から 255 の整数のいずれかで指定します。

pos が負の場合、文字列の末尾から数えた位置から探索します。

[PARAM] pattern:
探索する部分文字列、正規表現、文字コードを示す 0 から 255 の整数のいずれか
[PARAM] pos:
探索を開始するインデックス

例:

p "astrochemistry".index("str")         # => 1
p "regexpindex".index(/e.*x/, 2)        # => 3
p "character".index(?c)                 # => 0

p "foobarfoobar".index("bar", 6)        # => 9
p "foobarfoobar".index("bar", -6)       # => 9

[SEE_ALSO] String#rindex

insert(pos, other) -> self[permalink][rdoc]

pos 番目の文字の直前に文字列 other を挿入します。 self[pos, 0] = other と同じ操作です。

[PARAM] pos:
文字列を挿入するインデックス
[PARAM] other:
挿入する文字列

例:

str = "foobaz"
str.insert(3, "bar")
p str   # => "foobarbaz"

[SEE_ALSO] String#[]=

inspect -> String[permalink][rdoc]

文字列オブジェクトの内容を、出力したときに人間が読みやすいような適当な形式に変換します。 変換された文字列は印字可能な文字のみによって構成されます

現在の実装では、Ruby のリテラル形式を使って、 文字列中の不可視文字をエスケープシーケンスに変換します。

$KCODE が設定されている場合は、 そのエンコーディング内の適正なマルチバイト文字をそのまま出力します。 それ以外の不可視文字はエスケープシーケンスを使って出力されます。

このメソッドは主にデバッグのために用意されています。 永続化などの目的で文字列をダンプしたいときは、 String#dump を使うべきです。

例:

# p ではないことに注意
puts "string".inspect    # => "string"
puts "\t\r\n".inspect    # => "\t\r\n"

[SEE_ALSO] String#dump

intern -> Symbol[permalink][rdoc]
to_sym -> Symbol

文字列に対応するシンボル値 Symbol を返します。

なお、このメソッドの逆にシンボルに対応する文字列を得るには Symbol#to_s または Symbol#id2name を使います。

ナルキャラクタ ("\0") を含む文字列、もしくは空の文字列をinternすると、 例外 ArgumentError が発生します。

[EXCEPTION] ArgumentError:
self が ナルキャラクタ ("\0") を含む文字列、もしくは空の文字列の場合発生します。

例:

p "foo".intern                 # => :foo
p "foo".intern.to_s == "foo"   # => true
length -> Integer[permalink][rdoc]
size -> Integer

文字列のバイト数を返します。

ljust(width, padding = ' ') -> String[permalink][rdoc]

長さ width の文字列に self を左詰めした文字列を返します。 self の長さが width より長い時には元の文字列の複製を返します。 また、第 2 引数 padding を指定したときは 空白文字の代わりに padding を詰めます。

[PARAM] width:
返り値の文字列の最小の長さ
[PARAM] padding:
長さが width になるまで self の右側に詰める文字

例:

p "foo".ljust(10)        # => "foo       "
p "foo".ljust(9)         # => "foo      "
p "foo".ljust(8)         # => "foo     "
p "foo".ljust(2)         # => "foo"
p "foo".ljust(1)         # => "foo"
p "foo".ljust(10, "*")   # => "foo*******"

[SEE_ALSO] String#center, String#rjust

lstrip -> String[permalink][rdoc]

文字列の先頭にある空白文字を全て取り除いた新しい文字列を返します。 空白文字の定義は " \t\r\n\f\v" です。

例:

p "  abc\n".lstrip     #=> "abc\n"
p "\t abc\n".lstrip    #=> "abc\n"
p "abc\n".lstrip       #=> "abc\n"

[SEE_ALSO] String#strip, String#rstrip

lstrip! -> self | nil[permalink][rdoc]

文字列の先頭にある空白文字を全て破壊的に取り除きます。 空白文字の定義は " \t\r\n\f\v" です。

lstrip! は self を変更して返します。 ただし取り除く空白がなかったときは nil を返します。

例:

str = "  abc"
p str.lstrip!   # => "abc"
p str           # => "abc"

str = "abc"
p str.lstrip!   # => nil
p str           # => "abc"
match(regexp) -> MatchData | nil[permalink][rdoc]

regexp.match(self) と同じです。 regexp が文字列の場合は、正規表現にコンパイルします。 詳しくは Regexp#match を参照してください。

succ -> String[permalink][rdoc]
next -> String

self の「次の」文字列を返します。

「次の」文字列は、対象の文字列の右端から アルファベットなら アルファベット順(aの次はb, zの次はa, 大文字も同様)に、 数字なら 10 進数(9 の次は 0)とみなして計算されます。

p "aa".succ        # => "ab"
p "88".succ.succ   # => "90"

"99" → "100", "AZZ" → "BAA" のような繰り上げも行われます。 このとき負符号などは考慮されません。

p "99".succ   # => "100"
p "ZZ".succ   # => "AAA"
p "a9".succ   # => "b0"
p "-9".succ   # => "-10"

self にアルファベットや数字とそれ以外の文字が混在している場合、 アルファベットと数字だけが「次の」文字になり、残りは保存されます。

p "1.9.9".succ # => # "2.0.0"

逆に self がアルファベットや数字をまったく含まない場合は、 単純に文字コードを 1 増やします。

p ".".succ     # => "/"

さらに、self が空文字列の場合は "" を返します。 このメソッドはマルチバイト文字を意識せず、 単に文字列をバイト列として扱います。

なお、succ と逆の動作をするメソッドはありません。 また、succ という名前の由来は successor です。

例:

p "aa".succ   # => "ab"

# 繰り上がり
p "99".succ   # => "100"
p "a9".succ   # => "b0"
p "Az".succ   # => "Ba"
p "zz".succ   # => "aaa"
p "-9".succ   # => "-10"
p "9".succ    # => "10"
p "09".succ   # => "10"

# アルファベット・数字とそれ以外の混在
p "1.9.9".succ # => # "2.0.0"

# アルファベット・数字以外のみ
p ".".succ     # => "/"
p "\0".succ    # => "\001"
p "\377".succ  # => "\001\000"

このメソッドは文字列の Range の内部で使用されます。

succ! -> String[permalink][rdoc]
next! -> String

self を「次の」文字列に置き換えます。 「次の」文字列は、アルファベットなら 16 進数、 数字なら 10 進数とみなして計算されます。 「次の」文字列の計算では "99" → "100" のように繰り上げも行われます。 このとき負符号などは考慮されません。

self にアルファベットや数字とそれ以外の文字が混在している場合、 アルファベットと数字だけが「次の」文字になり、残りは保存されます。 逆に self がアルファベットや数字をまったく含まない場合は、 単純に文字コードを 1 増やします。

さらに、self が空文字列の場合は "" を返します。

このメソッドはマルチバイト文字を意識せず、 単に文字列をバイト列として扱います。

なお、succ! と逆の動作をするメソッドはありません。

例:

p "aa".succ   # => "ab"

# 繰り上がり
p "99".succ   # => "100"
p "a9".succ   # => "b0"
p "Az".succ   # => "Ba"
p "zz".succ   # => "aaa"
p "-9".succ   # => "-10"
p "9".succ    # => "10"
p "09".succ   # => "10"

# アルファベット・数字とそれ以外の混在
p "1.9.9".succ # => # "2.0.0"

# アルファベット・数字以外のみ
p ".".succ     # => "/"
p "\0".succ    # => "\001"
p "\377".succ  # => "\001\000"

[SEE_ALSO] String#succ

oct -> Integer[permalink][rdoc]

文字列を 8 進文字列であると解釈して、整数に変換します。

例:

p "10".oct  # => 8
p "010".oct # => 8
p "8".oct   # => 0

oct は文字列の接頭辞 ("0", "0b", "0B", "0x", "0X") に応じて 8 進以外の変換も行います。

例:

p "0b10".oct  # => 2
p "10".oct    # => 8
p "010".oct   # => 8
p "0x10".oct  # => 16

整数とみなせない文字があればそこまでを変換対象とします。 変換対象が空文字列であれば 0 を返します。

符号や _ が含まれる場合も変換対象になります。

例:

p "-010".oct     # => -8
p "-0x10".oct    # => 0
p "-0b10".oct    # => 0

p "1_0_1x".oct   # => 65

[SEE_ALSO] String#hex, String#to_i, String#to_f, Kernel.#Integer, Kernel.#Float

逆に、数値を文字列に変換するにはKernel.#sprintf, String#%, Integer#to_s を使用します。

partition(sep) -> [String, String, String][permalink][rdoc]

セパレータ sep が最初に登場する部分で self を 3 つに分割し、 [最初のセパレータより前の部分, セパレータ, それ以降の部分] の 3 要素の配列を返します。

self がセパレータを含まないときは、 返り値の第 2 要素と第 3 要素が空文字列になります。

[PARAM] sep:
セパレータを表す文字列か正規表現を指定します。

例:

p "axaxa".partition("x")   # => ["a", "x", "axa"]
p "aaaaa".partition("x")   # => ["aaaaa", "", ""]
p "aaaaa".partition("")    # => ["aaaaa", "", ""]

[SEE_ALSO] String#rpartition, String#split

replace(other) -> String[permalink][rdoc]

self の内容を other の内容で置き換えます。

例:

str = "foo"
str.replace "bar"
p str   # => "bar"
reverse -> String[permalink][rdoc]

文字列をバイト単位で左右逆転した文字列を返します。

例:

p "foobar".reverse   # => "raboof"
p "".reverse         # => ""
reverse! -> self[permalink][rdoc]

文字列をバイト単位で左右逆転します。

例:

str = "foobar"
str.reverse!
p str   # => "raboof"
rindex(pattern, pos = self.size) -> Integer | nil[permalink][rdoc]

文字列のインデックス pos から左に向かって pattern を探索します。 最初に見つかった部分文字列の左端のインデックスを返します。 見つからなければ nil を返します。

引数 pattern は探索する部分文字列、 正規表現、文字コードを示す 0 から 255 の整数のいずれかで指定します。

pos が負の場合は、文字列の末尾から数えた位置から探索します。

rindex と String#index とでは、探索方向だけが逆になります。 完全に左右が反転した動作をするわけではありません。 探索はその開始位置を右から左にずらしながら行いますが、 部分文字列の照合はどちらのメソッドも左から右に向かって行います。 以下の例を参照してください。

# String#index の場合
p "stringstring".index("ing", 1)    # => 3
  # ing            # ここから探索を始める
  #  ing
  #   ing          # 右にずらしていってここで見つかる

# String#rindex の場合
p "stringstring".rindex("ing", -1)  # => 9
  #           ing    # インデックス -1 のバイトから探索を始める
  #          ing
  #         ing      # 左にずらしていってここで見つかる
[PARAM] pattern:
探索する部分文字列、正規表現、文字コードを示す 0 から 255 の整数のいずれか
[PARAM] pos:
探索を始めるインデックス

例:

p "astrochemistry".rindex("str")        # => 10
p "character".rindex(?c)                # => 5
p "regexprindex".rindex(/e.*x/, 2)      # => 1

p "foobarfoobar".rindex("bar", 6)       # => 3
p "foobarfoobar".rindex("bar", -6)      # => 3

[SEE_ALSO] String#index

rjust(width, padding = ' ') -> String[permalink][rdoc]

長さ width の文字列に self を右詰めした文字列を返します。 self の長さが width より長い時には元の文字列の複製を返します。 また、第 2 引数 padding を指定したときは 空白文字の代わりに padding を詰めます。

[PARAM] width:
返り値の文字列の最小の長さ
[PARAM] padding:
長さが width になるまで self の左側に詰める文字

例:

p "foo".rjust(10)        # => "       foo"
p "foo".rjust(9)         # => "      foo"
p "foo".rjust(8)         # => "     foo"
p "foo".rjust(2)         # => "foo"
p "foo".rjust(1)         # => "foo"
p "foo".rjust(10, "*")   # => "*******foo"

[SEE_ALSO] String#center, String#ljust

rpartition(sep) -> [String, String, String][permalink][rdoc]

セパレータ sep が最後に登場する部分で self を 3 つに分割し、 [最後のセパレータより前の部分, セパレータ, それ以降の部分] の 3 要素の配列を返します。

self がセパレータを含まないときは、 返り値の第 1 要素と第 2 要素が空文字列になります。

[PARAM] sep:
セパレータを表す文字列か正規表現を指定します。

例:

p "axaxa".rpartition("x")   # => ["axa", "x", "a"]
p "aaaaa".rpartition("x")   # => ["", "", "aaaaa"]

[SEE_ALSO] String#partition, String#split

rstrip -> String[permalink][rdoc]

文字列の末尾にある空白文字を全て取り除いた新しい文字列を返します。 空白文字の定義は " \t\r\n\f\v\0" です。

例:

p "  abc\n".rstrip          #=> "  abc"
p "  abc \t\r\n\0".rstrip   #=> "  abc"
p "  abc".rstrip            #=> "  abc"
p "  abc\0 ".rstrip         #=> "  abc\0"

str = "abc\n"
p str.rstrip    #=> "abc"
p str           #=> "abc\n"  (元の文字列は変化しない)

[SEE_ALSO] String#lstrip,String#strip

rstrip! -> self | nil[permalink][rdoc]

文字列の末尾にある空白文字を全て破壊的に取り除きます。 空白文字の定義は " \t\r\n\f\v\0" です。

例:

str = "  abc\n"
p str.rstrip!   # => "  abc"
p str           # => "  abc"

str = "  abc \r\n\t\v\0"
p str.rstrip!   # => "  abc"
p str           # => "  abc"

[SEE_ALSO] String#rstrip, String#lstrip

scan(pattern) -> [String] | [[String]][permalink][rdoc]

self に対して pattern を繰り返しマッチし、 マッチした部分文字列の配列を返します。

pattern が正規表現で括弧を含む場合は、 括弧で括られたパターンにマッチした部分文字列の配列の配列を返します。

[PARAM] pattern:
探索する部分文字列または正規表現

例:

p "foobar".scan(/../)               # => ["fo", "ob", "ar"]
p "foobar".scan("o")                # => ["o", "o"]
p "foobarbazfoobarbaz".scan(/ba./)  # => ["bar", "baz", "bar", "baz"]

p "foobar".scan(/(.)/)
    # => [["f"], ["o"], ["o"], ["b"], ["a"], ["r"]]

p "foobarbazfoobarbaz".scan(/(ba)(.)/)
    # => [["ba", "r"], ["ba", "z"], ["ba", "r"], ["ba", "z"]]
scan(pattern) {|s| ... } -> self[permalink][rdoc]

pattern がマッチした部分文字列をブロックに渡して実行します。 pattern が正規表現で括弧を含む場合は、 括弧で括られたパターンにマッチした文字列の配列を渡します。

[PARAM] pattern:
探索する部分文字列または正規表現

例:

"foobarbazfoobarbaz".scan(/ba./) {|s| p s }
    # => "bar"
    #    "baz"
    #    "baz"
    #    "baz"

"foobarbazfoobarbaz".scan("ba") {|s| p s }
    # => "ba"
    #    "ba"
    #    "ba"
    #    "ba"

"foobarbazfoobarbaz".scan(/(ba)(.)/) {|s| p s }
    # => ["ba", "r"]
    #    ["ba", "z"]
    #    ["ba", "r"]
    #    ["ba", "z"]
slice!(nth) -> Integer[permalink][rdoc]
slice!(pos, len) -> String
slice!(substr) -> String
slice!(regexp, nth = 0) -> String
slice!(first..last) -> String
slice!(first...last) -> String
slice!(regexp, nth = 0) -> String

指定した範囲 (String#[] 参照) を 文字列から取り除いたうえで取り除いた部分文字列を返します。

引数が範囲外を指す場合は nil を返します。

split(sep = $;, limit = 0) -> [String] | [[String]][permalink][rdoc]

第 1 引数 sep で指定されたセパレータによって文字列を limit 個まで分割し、 結果を文字列の配列で返します。

第 1 引数 sep は以下のいずれかです。

正規表現

正規表現にマッチする部分で分割する。 特に、括弧によるグルーピングがあればそのグループにマッチした 文字列も結果の配列に含まれる (後述)。

文字列

その文字列自体にマッチする部分で分割する。

1 バイトの空白文字 ' ' か nil

先頭と末尾の空白を除いたうえで、空白文字列で分割する。

空文字列 '' あるいは空文字列にマッチする正規表現

文字列を 1 文字ずつに分割する。マルチバイト文字を認識する。

sep が正規表現で、かつその正規表現に括弧が含まれている場合には、 各括弧のパターンにマッチした文字列も配列に含まれます。 括弧が複数ある場合は、マッチしたものだけが配列に含まれます。

第 2 引数 limit は以下のいずれかです。

limit > 0

最大 limit 個の文字列に分割する

limit == 0

分割個数制限はなしで、配列末尾の空文字列を取り除く

limit < 0

分割個数の制限はなし

[PARAM] sep:
文字列を分割するときのセパレータのパターン
[PARAM] limit:
分割する最大個数

例:

p "   a \t  b \n  c".split(/\s+/) # => ["", "a", "b", "c"]

p "   a \t  b \n  c".split(nil)   # => ["a", "b", "c"]
p "   a \t  b \n  c".split(' ')   # => ["a", "b", "c"]   # split(nil) と同じ
p "   a \t  b \n  c".split        # => ["a", "b", "c"]   # split(nil) と同じ

# 括弧を含む正規表現
p '1-10,20'.split(/([-,])/)   # => ["1", "-", "10", ",", "20"]

# 正規表現が空文字列にマッチする場合は 1 文字に分割
p 'hi there'.split(/\s*/).join(':')  # => "h:i:t:h:e:r:e"

# 文字列全体を 1 文字ずつに分割する例
p 'hi there'.split(//).join(':')     # => "h:i: :t:h:e:r:e"

# $KCODE を設定すればマルチバイト文字列を認識
$KCODE = "EUC"
p '文字列'.split(//).join(':')       # => "文:字:列"

# limit == 0 だと制限なく分割、配列末尾の空文字列は取り除かれる
p "a,b,c,,,".split(/,/, 0)   # => ["a", "b", "c"]

# limit 省略時は 0 と同じ (最もよく使われるパターン)
p "a,b,c,,,".split(/,/)      # => ["a", "b", "c"]

# 正の limit 使用例
p "a,b,c,d,e".split(/,/, 1)  # => ["a,b,c,d,e"]
p "a,b,c,d,e".split(/,/, 2)  # => ["a", "b,c,d,e"]
p "a,b,c,d,e".split(/,/, 3)  # => ["a", "b", "c,d,e"]
p "a,b,c,d,e".split(/,/, 4)  # => ["a", "b", "c", "d,e"]
p "a,b,c,d,e".split(/,/, 5)  # => ["a", "b", "c", "d", "e"]
p "a,b,c,d,e".split(/,/, 6)  # => ["a", "b", "c", "d", "e"]
p "a,b,c,d,e".split(/,/, 7)  # => ["a", "b", "c", "d", "e"]

# limit が負の数の場合は制限なく分割
p "a,b,c,,,".split(/,/, -1)    # => ["a", "b", "c", "", "", ""]

[SEE_ALSO] String#partition, String#rpartition

squeeze(*chars) -> String[permalink][rdoc]

chars に含まれる文字が複数並んでいたら 1 文字にまとめます。

chars の形式は tr(1) と同じです。つまり、 `a-c' は a から c を意味し、"^0-9" のように 文字列の先頭が `^' の場合は指定文字以外を意味します。

`-' は文字列の両端にない場合にだけ範囲指定の意味になります。 同様に、`^' もその効果は文字列の先頭にあるときだけです。また、 `-', `^', `\' はバックスラッシュ(`\')によ りエスケープすることができます。

引数を 1 つも指定しない場合は、すべての連続した文字を 1 文字にまとめます。

引数を複数指定した場合は、すべての引数にマッチする文字を 1 文字にまとめます。

[PARAM] chars:
1文字にまとめる文字。

例:

p "112233445566778899".squeeze          # =>"123456789"
p "112233445566778899".squeeze("2-8")   # =>"11234567899"

# 以下の 2 つは同じ意味
p "112233445566778899".squeeze("2378")          # =>"11234455667899"
p "112233445566778899".squeeze("2-8", "^4-6")   # =>"11234455667899"
squeeze(str = nil) -> String[permalink][rdoc] [redefined by jcode]

String#squeeze の日本語対応版です。 指定した文字を1文字にまとめた文字列を返します。

ただしこのメソッドは置き換え前の物とは異なり、 2つ以上の引数を取ることはできません。

[PARAM] str:
1文字にまとめる文字のパターン。

例:

#!/usr/bin/env ruby

$KCODE = 'EUC'
zstr = 'AABBCC'
hoge = 'hhoge'

p zstr.squeeze   # => "AABBCC"
p hoge.squeeze   # => "hoge"

require 'jcode'
p zstr.squeeze   # => "ABC"
p hoge.squeeze   # => "hoge"
squeeze!(str = nil) -> self | nil[permalink][rdoc] [redefined by jcode]

String#squeeze! の日本語対応版です。 指定した文字を1文字にまとめた文字列に自身を置き換えます。

ただしこのメソッドは置き換え前の物とは異なり、 2つ以上の引数を取ることはできません。

[PARAM] str:
1文字にまとめる文字のパターン。
squeeze!(*chars) -> self | nil[permalink][rdoc]

chars に含まれる文字が複数並んでいたら 1 文字にまとめます。

chars の形式は tr(1) と同じです。つまり、 `a-c' は a から c を意味し、"^0-9" のように 文字列の先頭が `^' の場合は指定文字以外を意味します。

`-' は文字列の両端にない場合にだけ範囲指定の意味になります。 同様に、`^' もその効果は文字列の先頭にあるときだけです。また、 `-', `^', `\' はバックスラッシュ(`\')によ りエスケープすることができます。

引数を 1 つも指定しない場合は、すべての連続した文字を 1 文字にまとめます。

引数を複数指定した場合は、すべての引数にマッチする文字を 1 文字にまとめます。

1 文字もまとめられなかった場合は nil を返します。

[PARAM] chars:
1文字にまとめる文字。

例:

str = "112233445566778899"
str.squeeze!
p str    # =>"123456789"

str = "112233445566778899"
str.squeeze!("2-8")
p str    # =>"11234567899"

str = "123456789"
str.squeeze! # => nil
p str        # =>"123456789"
start_with?(*strs) -> bool[permalink][rdoc]

self の先頭が strs のいずれかであるとき true を返します。

[PARAM] strs:
パターンを表す文字列 (のリスト)

例:

"string".start_with?("str")          # => true
"string".start_with?("ing")          # => false
"string".start_with?("ing", "str")   # => true

[SEE_ALSO] String#end_with?

strip -> String[permalink][rdoc]

文字列先頭と末尾の空白文字を全て取り除いた文字列を生成して返します。 空白文字の定義は " \t\r\n\f\v" です。 また、文字列右側からは "\0" も取り除きますが、 左側の "\0" は取り除きません。

例:

p "  abc  \r\n".strip    #=> "abc"
p "abc\n".strip          #=> "abc"
p "  abc".strip          #=> "abc"
p "abc".strip            #=> "abc"
p "  \0  abc  \0".strip  # => "\000  abc"   # 右側のみ "\0" も取り除く

str = "\tabc\n"
p str.strip              #=> "abc"
p str                    #=> "\tabc\n" (元の文字列は変化しない)

[SEE_ALSO] String#lstrip, String#rstrip

strip! -> self | nil[permalink][rdoc]

先頭と末尾の空白文字を全て破壊的に取り除きます。 空白文字の定義は " \t\r\n\f\v" です。 また、文字列右側からは "\0" も取り除きますが、 左側の "\0" は取り除きません。

strip! は、内容を変更した self を返します。 ただし取り除く空白がなかったときは nil を返します。

例:

str = "  abc\r\n"
p str.strip!     #=> "abc"
p str            #=> "abc"

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

str = "  \0  abc  \0"
str.strip!
p str            # => "\000  abc"   # 右側の "\0" のみ取り除かれる

[SEE_ALSO] String#strip, String#lstrip

sub(pattern, replace) -> String[permalink][rdoc]

文字列中で pattern にマッチした最初の部分を 文字列 replace で置き換えた文字列を生成して返します。

置換文字列 replace 中の \& と \0 はマッチした部分文字列に、 \1 ... \9 は n 番目の括弧の内容に置き換えられます。 置換文字列内では \`、\'、\+ も使えます。 これらは $`$'$+ に対応します。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[PARAM] replace:
pattern で指定した文字列と置き換える文字列

例:

p 'abcdefg'.sub(/def/, '!!')          # => "abc!!g"
p 'abcabc'.sub(/b/, '<<\&>>')         # => "a<<b>>cabc"
p 'xxbbxbb'.sub(/x+(b+)/, 'X<<\1>>')  # => "X<<bb>>xbb"

注意:

第 2 引数 replace に $1 を埋め込んでも意図した結果にはなりません。 この文字列が評価される時点ではまだ正規表現マッチが行われておらず、 $1 がセットされていないからです。

また、sub では「\」が部分文字列との置き換えという特別な意味を持つため、 replace に「\」自身を入れたいときは 「\」を二重にエスケープしなければなりません。

# ひとつめの括弧の内容に置き換えるときによくある間違い
p 'xbbb-xbbb'.sub(/x(b+)/, "#{$1}")   # => "-xbbb"     # NG
p 'xbbb-xbbb'.sub(/x(b+)/, "\1")      # => "1-xbbb"    # NG
p 'xbbb-xbbb'.sub(/x(b+)/, "\\1")     # => "bbb-xbbb"  # OK
p 'xbbb-xbbb'.sub(/x(b+)/, '\1')      # => "bbb-xbbb"  # OK
p 'xbbb-xbbb'.sub(/x(b+)/, '\\1')     # => "bbb-xbbb"  # OK

# バックスラッシュを倍にするときによくある間違い
puts '\n'.sub(/\\/, "\\\\")      # => \n   # NG
puts '\n'.sub(/\\/, '\\\\')      # => \n   # NG
puts '\n'.sub(/\\/, "\\\\\\\\")  # => \\n  # OK
puts '\n'.sub(/\\/, '\\\\\\\\')  # => \\n  # OK

このような間違いを確実に防止し、コードの可読性を上げるには、 \& や \1 よりも下記のようにブロック付き形式の sub を使うべきです。

p 'xbbb-xbbb'.sub(/x(b+)/) { $1 }   # => "bbb-xbbb"  # OK

puts '\n'.sub(/\\/) { '\\\\' }      # => \\n        # OK

[SEE_ALSO] String#gsub

sub(pattern) {|matched| .... } -> String[permalink][rdoc]

文字列中で pattern にマッチした最初の部分をブロックに渡し、 その評価結果で置き換えた新しい文字列を返します。 ブロックなしの sub と違い、ブロックの中からは 組み込み変数 $1, $2, $3, ... を問題なく参照できます。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする

例:

p 'abcabc'.sub(/b/) {|s| s.upcase }  #=> "aBcabc"
p 'abcabc'.sub(/b/) { $&.upcase }    #=> "aBcabc"

[SEE_ALSO] String#gsub

sub!(pattern, replace) -> self | nil[permalink][rdoc]

文字列中で pattern にマッチした最初の部分を文字列 replace へ破壊的に置き換えます。

置換文字列 replace 中の \& と \0 はマッチした部分文字列に、 \1 ... \9 は n 番目の括弧の内容に置き換えられます。 置換文字列内では \`、\'、\+ も使えます。 これらは $`$'$+ に対応します。

sub! は通常 self を変更して返しますが、 置換が起こらなかった場合は nil を返します。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[PARAM] replace:
pattern で指定した文字列と置き換える文字列
[RETURN]
置換した場合は self、置換しなかった場合は nil

例:

buf = "String-String"
buf.sub!(/in./, "!!")
p buf   # => "Str!!-String"

buf = "String.String"
buf.sub!(/in./, '<<\&>>')
p buf   # => "Str<<ing>>-String"

注意:

引数 replace の中で $1 を使うことはできません。 replace は sub メソッドの呼び出しより先に評価されるので、 まだ sub の正規表現マッチが行われておらず、 $1 がセットされていないからです。

また、sub では「\」が部分文字列との置き換えという特別な意味を持つため、 replace に「\」自身を入れたいときは 「\」を二重にエスケープしなければなりません。

例:

# ひとつめの括弧にマッチした部分に置き換えるときによくやる間違い
'abbbcd'.sub!(/a(b+)/, "#{$1}")       # NG
'abbbcd'.sub!(/a(b+)/, "\1")          # NG
'abbbcd'.sub!(/a(b+)/, "\\1")         # OK
'abbbcd'.sub!(/a(b+)/, '\\1')         # OK
'abbbcd'.sub!(/a(b+)/, '\1')          # OK
'abbbcd'.sub!(/a(b+)/) { $1 }         # OK   これがもっとも安全

[SEE_ALSO] String#gsub

sub!(pattern) {|matched| .... } -> self | nil[permalink][rdoc]

文字列中で pattern にマッチした最初の部分をブロックに渡し、 その評価結果へ破壊的に置き換えます。

また、ブロックなしの sub と違い、ブロックの中からは 組み込み変数 $1, $2, $3, ... を問題なく参照できます。

[PARAM] pattern:
置き換える文字列のパターンを表す文字列か正規表現。 文字列を指定した場合は全く同じ文字列にだけマッチする
[RETURN]
置換した場合は self、置換しなかった場合は nil

例:

str = 'abcabc'
str.sub!(/b/) {|s| s.upcase }
p str    #=> "aBcabc"

str = 'abcabc'
str.sub!(/b/) { $&.upcase }
p str    #=> "aBcabc"

[SEE_ALSO] String#gsub

succ -> String[permalink][rdoc] [redefined by jcode]

String#succ の日本語対応版です。 「次の」文字列を返します。

以下のような次の文字列を返します。

"あaあ".succ => "あaぃ"
"rb".succ => "rc"
"_紅玉".succ => "_紅桐"

従来の String#succ は、 多バイト文字と半角文字が混在している文字列を 意図通りに処理することができません。 例えば上記のコードは、それぞれ "あbあ"、"sb"、"_紘玉"(最後のは SJIS 環境の場合の例で、 EUC-JP の場合はこうはなりません)を返します。

なお、"99" の次は "100" になるのに対し、 "99" の次は "100" にはならないことに注意。 "Az" や "zz" も同様です。つまり多バイト文字では 従来の String#succ のようなアルファベットや数字に 関する繰り上げを行わないということです。

succ! -> self | nil[permalink][rdoc] [redefined by jcode]

String#succ! の日本語対応版です。 自身を「次の」文字列に置き換えます。

sum(bits = 16) -> Integer[permalink][rdoc]

文字列の bits ビットのチェックサムを計算します。

以下と同じです。

def sum(bits)
  sum = 0
  each_byte {|c| sum += c }
  return 0 if sum == 0
  sum & ((1 << bits) - 1)
end

例えば以下のコードで UNIX System V の sum(1) コマンドと同じ値が得られます。

例:

sum = 0
ARGF.each_line do |line|
  sum += line.sum
end
sum %= 65536
[PARAM] bits:
チェックサムのビット数
swapcase -> String[permalink][rdoc]

'A' から 'Z' までのアルファベット大文字を小文字に、 'a' から 'z' までのアルファベット小文字を大文字に変更した文字列を返します。

このメソッドはマルチバイト文字列を認識しますが、 それはあくまでも「1 文字を 1 文字として認識する」だけであって、 いわゆる全角アルファベットの大文字小文字までは変換しません。

そのため、文字列が Shift JIS エンコーディングで、 かつ $KCODE が適切に設定されていない場合、 マルチバイト文字の一部も変換してしまう場合があります。 逆に、$KCODE を設定しても マルチバイト文字のアルファベットは処理しません。

例:

p "ABCxyz".swapcase   # => "abcXYZ"
p "Access".swapcase   # => "aCCESS"

# -*- Coding: shift_jis -*-
$KCODE = 'n'
puts "蟻".swapcase   # => 帰

[SEE_ALSO] String#swapcase!, String#upcase, String#downcase, String#capitalize

swapcase! -> self | nil[permalink][rdoc]

'A' から 'Z' までのアルファベット大文字を小文字に、 'a' から 'z' までのアルファベット小文字を大文字に、破壊的に変更します。

swapcase! は self を変更して返しますが、 置換が起こらなかった場合は nil を返します。

このメソッドはマルチバイト文字を認識しません。 そのため、文字列が Shift JIS エンコーディングで、 かつ $KCODE が適切に設定されていない場合、 マルチバイト文字の一部も変換してしまう場合があります。 逆に、$KCODE を設定しても マルチバイト文字のアルファベットは処理しません。

例:

str = "ABCxyz"
str.swapcase!
p str   # => "abcXYZ"

# -*- Coding: shift_jis -*-
$KCODE ='n'
puts "蟻".swapcase   # => 帰

[SEE_ALSO] String#swapcase, String#upcase!, String#downcase!, String#capitalize!

to_f -> Float[permalink][rdoc]

文字列を 10 進数表現と解釈して、浮動小数点数 Float に変換します。

浮動小数点数とみなせなくなるところまでを変換対象とします。 変換対象が空文字列であれば 0.0 を返します。

例:

p "10".to_f    # => 10.0
p "10e2".to_f  # => 1000.0
p "1e-2".to_f  # => 0.01
p ".1".to_f    # => 0.1

p "nan".to_f   # => 0.0
p "INF".to_f   # => 0.0
p "-Inf".to_f  # => -0.0
p(("10" * 1000).to_f)   # => Infinity (with warning)

p "".to_f      # => 0.0
p "1_0_0".to_f # => 100.0
p " \n10".to_f # => 10.0       # 先頭の空白は無視される
p "0xa.a".to_f # => 0.0

なお、このメソッドの逆に、数値を文字列に変換するには Kernel.#sprintf,String#%,Integer#to_s を使用します。

[SEE_ALSO] String#hex, String#oct, String#to_i, Kernel.#Integer, Kernel.#Float

to_i(base = 10) -> Integer[permalink][rdoc]

文字列を 10 進数表現された整数であると解釈して、整数に変換します。

p " 10".to_i    # => 10
p "+10".to_i    # => 10
p "-10".to_i    # => -10

p "010".to_i    # => 10
p "-010".to_i   # => -10

整数とみなせない文字があればそこまでを変換対象とします。 変換対象が空文字列であれば 0 を返します。

p "0x11".to_i   # => 0
p "".to_i       # => 0

基数を指定することでデフォルトの 10 進以外に 2 〜 36 進数表現へ変換できます。 それぞれ Ruby の整数リテラルで使用可能なプリフィクスは無視されます。 また、base に 0 を指定するとプリフィクスから基数を判断します。 認識できるプリフィクスは、 0b (2 進数)、0 (8 進数)、0o (8 進数)、0d (10 進数)、0x (16 進数) です。

0, 2 〜 36 以外の引数を指定した場合は 例外 ArgumentError が発生します。

p "01".to_i(2)    # => 1
p "0b1".to_i(2)   # => 1

p "07".to_i(8)    # => 7
p "0o7".to_i(8)   # => 7

p "1f".to_i(16)   # => 31
p "0x1f".to_i(16) # => 31

p "0b10".to_i(0)  # => 2
p "0o10".to_i(0)  # => 8
p "010".to_i(0)   # => 8
p "0d10".to_i(0)  # => 10
p "0x10".to_i(0)  # => 16
[PARAM] base:
進数を指定する整数。0 か、2〜36 の整数。
[RETURN]
整数

このメソッドの逆に数値を文字列に変換するには、 Kernel.#sprintf, String#%, Integer#to_s を使用します。

String#hex, String#oct, String#to_f, Kernel.#Integer, Kernel.#Float も参照してください。

to_s -> String[permalink][rdoc]
to_str -> String

self を返します。

例:

p "str".to_s     # => "str"
p "str".to_str   # => "str"

このメソッドは、文字列を他のクラスのインスタンスと混ぜて処理したいときに有効です。 例えば返り値が文字列か nil であるメソッド some_method があるとき、 to_s メソッドを使うと以下のように統一的に処理できます。

# some_method(5).downcase だと返り値が nil のときに
# エラーになるので to_s をはさむ
p some_method(5).to_s.downcase
tr(pattern, replace) -> String[permalink][rdoc]

pattern 文字列に含まれる文字を検索し、 それを replace 文字列の対応する文字に置き換えます。

pattern の形式は tr(1) と同じです。つまり、 `a-c' は a から c を意味し、"^0-9" のように 文字列の先頭が `^' の場合は指定文字以外が置換の対象になります。

replace に対しても `-' による範囲指定が可能です。 例えば String#upcase は tr を使って "foo".tr('a-z', 'A-Z') と書けます。

`-' は文字列の両端にない場合にだけ範囲指定の意味になります。 `^' も文字列の先頭にあるときにだけ否定の効果を発揮します。 また、`-', `^', `\' はバックスラッシュ (`\') によりエスケープできます。

replace の範囲が pattern の範囲よりも小さい場合は、 replace の最後の文字が無限に続くものとして扱われます。

[PARAM] pattern:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字

例:

p "foo".tr("f", "X")      # => "Xoo"
p "foo".tr('a-z', 'A-Z')  # => "FOO"
p "FOO".tr('A-Z', 'a-z')  # => "foo"

[SEE_ALSO] String#tr_s

tr(search, replace) -> String[permalink][rdoc] [redefined by jcode]

String#tr の日本語対応版です。 search に含まれる文字を検索し、 replace の対応する文字に 置き換えた文字列を返します。

[PARAM] search:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字

例:

#!/usr/bin/env ruby

$KCODE = 'EUC'
zstr = 'AABBCC'
hoge = 'hhoge'

p zstr.tr('A-Z','A-Z')    # => "A疏疏汰汰蛋\303"
p hoge.tr('a-z','A-Z')    # => "旙旙\332"

require 'jcode'
p zstr.tr('A-Z','A-Z')    # => "AABBCC"
p hoge.tr('a-z','A-Z')    # => "HHOGE"

[SEE_ALSO] String#tr_s

tr!(search, replace) -> self | nil[permalink][rdoc] [redefined by jcode]

String#tr! の日本語対応版です。 search に含まれる文字を検索し、 replace の対応する文字に 破壊的に置き換えます。

[PARAM] search:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字
tr!(pattern, replace) -> self | nil[permalink][rdoc]

pattern 文字列に含まれる文字を検索し、 それを replace 文字列の対応する文字に破壊的に置き換えます。

pattern の形式は tr(1) と同じです。 つまり、`a-c' は a から c を意味し、 "^0-9" のように文字列の先頭が `^' の場合は 指定文字以外が置換の対象になります。

replace に対しても `-' による範囲指定が可能です。 例えば、String#upcase を tr で書くと、

p "foo".tr('a-z', 'A-Z')
=> "FOO"

となります。

`-' は文字列の両端にない場合にだけ範囲指定の意味になります。 `^' も文字列の先頭にあるときにだけ否定の効果を発揮します。 また、`-', `^', `\' はバックスラッシュ (`\') によりエスケープできます。

replace の範囲が pattern の範囲よりも小さい場合は、 replace の最後の文字が無限に続くものと扱われます。

tr! は self を変更して返しますが、 置換が起こらなかった場合は nil を返します。

[PARAM] pattern:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字

[SEE_ALSO] String#tr, String#tr_s

tr_s(pattern, replace) -> String[permalink][rdoc]

文字列の中に pattern 文字列に含まれる文字が存在したら、 replace 文字列の対応する文字に置き換えます。さらに、 置換した部分内に同一の文字の並びがあったらそれを 1 文字に圧縮します。

pattern の形式は tr(1) と同じです。 つまり「a-c」は a から c を意味し、 "^0-9" のように文字列の先頭が「^」の場合は指定した文字以外が置換の対象になります。

replace でも「-」を使って範囲を指定できます。

「-」は文字列の両端にない場合にだけ範囲指定の意味になります。 同様に、「^」もその効果は文字列の先頭にあるときだけです。 また、「-」、「^」、「\」はバックスラッシュ (「\」) でエスケープできます。

replace の範囲が pattern の範囲よりも小さい場合、 replace の最後の文字が無限に続くものとして扱われます。

[PARAM] pattern:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字

例:

p "gooooogle".tr_s("o", "X")       # => "gXgle"
p "gooooogle".tr_s("a-z", "A-Z")   # => "GOGLE"

注意: 一般に、tr_s を tr と squeeze で置き換えることはできません。 tr と squeeze の組みあわせでは tr の置換後の文字列全体を squeeze しますが、 tr_s は置換された部分だけを squeeze します。 以下のコードを参照してください。

p "foo".tr_s("o", "f")              # => "ff"
p "foo".tr("o", "f").squeeze("f")   # => "f"

[SEE_ALSO] String#tr

tr_s(search, replace) -> String[permalink][rdoc] [redefined by jcode]

String#tr_s の日本語対応版です。 文字列の中に search 文字列に含まれる文字が存在したら、 replace 文字列の対応する文字に置き換え、 置換した部分内に同一の文字の並びがあったらそれを 1 文字に圧縮した文字列を返します。

[PARAM] search:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字

例:

$KCODE = 'EUC'

p "foo".tr_s("o", "f")        # => "ff"
p "foo".tr_s("o", "f")   # => TODO: fill result

require 'jcode'
p "foo".tr_s("o", "f")        # => "ff"
p "foo".tr_s("o", "f")   # => "ff"
tr_s!(pattern, replace) -> self | nil[permalink][rdoc]

文字列の中に pattern 文字列に含まれる文字が存在したら、 replace 文字列の対応する文字に置き換えます。さらに、 置換した部分内に同一の文字の並びがあったらそれを 1 文字に圧縮します。

pattern の形式は tr(1) と同じです。 つまり「a-c」は a から c を意味し、 "^0-9" のように文字列の先頭が「^」の場合は指定した文字以外が置換の対象になります。

replace でも「-」を使って範囲を指定できます。

p "gooooogle".tr_s("a-z", "A-Z")   # => "GOGLE"

「-」は文字列の両端にない場合にだけ範囲指定の意味になります。 同様に、「^」もその効果は文字列の先頭にあるときだけです。 また、「-」、「^」、「\」はバックスラッシュ (「\」) でエスケープできます。

replace の範囲が search の範囲よりも小さい場合、 replace の最後の文字が無限に続くものとして扱われます。

tr_s は置換後の文字列を生成して返します。 tr_s! は self を変更して返しますが、 置換が起こらなかった場合は nil を返します。

注意: 一般に、tr_s! を tr! と squeeze! で置き換えることはできません。 tr! と squeeze! の組みあわせでは tr! の置換後の文字列全体を squeeze! しますが、 tr_s! は置換された部分だけを squeeze! します。 以下のコードを参照してください。

str = "foo"
str.tr_s!("o", "f")
p str   # => "ff"

str = "foo"
str.tr!("o", "f")
str.squeeze!("f")
p str   # => "f"
[PARAM] pattern:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字

[SEE_ALSO] String#tr, String#tr_s

tr_s!(search, replace) -> self | nil[permalink][rdoc] [redefined by jcode]

String#tr_s! の日本語対応版です。 文字列の中に search 文字列に含まれる文字が存在したら、 replace 文字列の対応する文字に置き換えます。さらに、 置換した部分内に同一の文字の並びがあったらそれを 1 文字に圧縮します。

[PARAM] search:
置き換える文字のパターン
[PARAM] replace:
pattern で指定した文字を置き換える文字
unpack(template) -> Array[permalink][rdoc]

Array#pack で生成された文字列を テンプレート文字列 template にしたがってアンパックし、 それらの要素を含む配列を返します。

[PARAM] template:
pack テンプレート文字列
[RETURN]
オブジェクトの配列

以下にあげるものは、Array#packString#unpack のテンプレート文字の一覧です。テンプレート文字は後に「長さ」を表す数字 を続けることができます。「長さ」の代わりに`*'とすることで「残り全て」 を表すこともできます。

長さの意味はテンプレート文字により異なりますが大抵、

"iiii"

のように連続するテンプレート文字は

"i4"

と書き換えることができます。

テンプレート文字列中の空白類は無視されます。 また、`#' から改行あるいはテンプレート文字列の最後まではコメントとみな され無視されます。

整数のテンプレート文字のシステム依存性

各テンプレート文字の説明の中で、 short や long はシステムによらずそれぞれ 2, 4バイトサ イズの数値(32ビットマシンで一般的なshort, longのサイズ)を意味していま す。s, S, l, L に対しては直後に _ または ! を "s_" あるいは "s!" のように 続けることでシステム依存の short, long のサイズにすることもできます。

i, I (int)のサイズは常にシステム依存であり、n, N, v, V のサイズは常にシステム依存ではない(!をつけられない)ことに注意してください。

つまり、IO#ioctl などで C の構造体を渡すときのように、 システム依存のサイズとエンディアンに合わせる必要があるときには s!, S!, i!, I!, l!, L!, q!, Q! を用います。 また、ネットワークプロトコルやファイルフォーマットのように、 システムに依存しないデータを扱うときには n, N, v, V を用います。

まとめると以下のようになります。

エンディアン非依存、整数サイズ非依存 (ネットワークプロトコルなどに適切)
  n: big endian unsigned 16bit
  N: big endian unsigned 32bit
  v: little endian unsigned 16bit
  V: little endian unsigned 32bit
エンディアン依存、整数サイズ依存 (C の構造体などに適切)
  s!: signed short
  S!: unsigned short
  i!: signed int
  I!: unsigned int
  l!: signed long
  L!: unsigned long
  q!: signed long long
  Q!: unsigned long long
エンディアン依存、整数サイズ非依存 (C99 の stdint.h にある厳密な幅を持つ整数型に適切)
  s: int16_t
  S: uint16_t
  l: int32_t
  L: uint32_t

各テンプレート文字の説明

説明中、Array#packString#unpack で違いのあるものは `/' で区切って 「Array#pack の説明 / String#unpack の説明」としています。

a

ASCII文字列(null文字を詰める/後続するnull文字やスペースを残す)

    ["abc"].pack("a")    # => "a"
    ["abc"].pack("a*")   # => "abc"
    ["abc"].pack("a4")   # => "abc\0"

    "abc\0".unpack("a4") # => ["abc\0"]
    "abc ".unpack("a4")  # => ["abc "]
A

ASCII文字列(スペースを詰める/後続するnull文字やスペースを削除)

    ["abc"].pack("A")    # => "a"
    ["abc"].pack("A*")   # => "abc"
    ["abc"].pack("A4")   # => "abc "

    "abc ".unpack("A4")  # => ["abc"]
    "abc\0".unpack("A4") # => ["abc"]
Z

null終端文字列(長さが`*'の場合も含め、null文字を詰める/後続するnull文字を削除)

    ["abc"].pack("Z")  # => "a"
    ["abc"].pack("Z*") # => "abc\0"
    ["abc"].pack("Z4") # => "abc\0"

    "abc\0".unpack("Z4") # => ["abc"]
    "abc ".unpack("Z4")  # => ["abc "]
b

ビットストリング(各バイトごとに下位ビットから上位ビット)

    "\377\000".unpack("b*") # => ["1111111100000000"]
    "\001\002".unpack("b*") # => ["1000000001000000"]
    "\001\002".unpack("b3") # => ["100"]


    ["1000000001000000"].pack("b*") # => "\001\002"
B

ビットストリング(各バイトごとに上位ビットから下位ビット)

    "\377\000".unpack("B*")  # => ["1111111100000000"]
    "\001\002".unpack("B*")  # => ["0000000100000010"]
    "\001\002".unpack("B9")  # => ["000000010"]
    "\001\002".unpack("B15") # => ["000000010000001"]

    ["0000000100000010"].pack("B*")  # => "\001\002"
    ["0000000100000010"].pack("B0")  # => ""
    ["0000000100000010"].pack("B1")  # => "\000"
    ["0000000100000010"].pack("B7")  # => "\000"
    ["0000000100000010"].pack("B8")  # => "\001"
    ["0000000100000010"].pack("B9")  # => "\001\000"
    ["0000000100000010"].pack("B14") # => "\001\000"
    ["0000000100000010"].pack("B15") # => "\001\002"
    ["0000000100000010"].pack("B16") # => "\001\002"
h

16進文字列(下位ニブルが先)

    "\x01\xfe".unpack("h*") # => ["10ef"]
    "\x01\xfe".unpack("h3") # => ["10e"]

    ["10ef"].pack("h*") # => "\001\376"
H

16進文字列(上位ニブルが先)

    "\x01\xfe".unpack("H*") # => ["01fe"]
    "\x01\xfe".unpack("H3") # => ["01f"]
    "~".unpack("H2")        # => ["7e"]

    ["01fe"].pack("H*") # => "\001\376"
    ["7e"].pack("H2")   # => "~"
c

char (8bit 符号つき整数)

    "\001\376".unpack("c*") # => [1, -2]

    [1, -2].pack("c*")  # => "\001\376"
    [1, 254].pack("c*") # => "\001\376"
C

unsigned char (8bit 符号なし整数)

    "\001\376".unpack("C*") # => [1, 254]

    [1, -2].pack("C*")  # => "\001\376"
    [1, 254].pack("C*") # => "\001\376"
s

short (16bit 符号つき整数, エンディアンに依存) (s! は 16bit でなく、short のサイズに依存)

リトルエンディアン:

    "\001\002\376\375".unpack("s*") # => [513, -514]

    [513, 65022].pack("s*") # => "\001\002\376\375"
    [513, -514].pack("s*")  # => "\001\002\376\375"

ビッグエンディアン:

    "\001\002\376\375".unpack("s*") # => [258, -259]

    [258, 65277].pack("s*") # => "\001\002\376\375"
    [258, -259].pack("s*")  # => "\001\002\376\375"
S

unsigned short (16bit 符号なし整数, エンディアンに依存) (S! は 16bit でなく、short のサイズに依存)

リトルエンディアン:

    "\001\002\376\375".unpack("S*") # => [513, 65022]

    [513, 65022].pack("s*") # => "\001\002\376\375"
    [513, -514].pack("s*")  # => "\001\002\376\375"

ビッグエンディアン:

    "\001\002\376\375".unpack("S*") # => [258, 65277]

    [258, 65277].pack("S*") # => "\001\002\376\375"
    [258, -259].pack("S*")  # => "\001\002\376\375"
i

int (符号つき整数, エンディアンと int のサイズに依存)

リトルエンディアン, 32bit int:

    "\001\002\003\004\377\376\375\374".unpack("i*") # => [67305985, -50462977]

    [67305985, 4244504319].pack("i*") # => RangeError
    [67305985, -50462977].pack("i*")  # => "\001\002\003\004\377\376\375\374"

ビッグエンディアン, 32bit int:

    "\001\002\003\004\377\376\375\374".unpack("i*") # => [16909060, -66052]

    [16909060, 4294901244].pack("i*") # => RangeError
    [16909060, -66052].pack("i*")     # => "\001\002\003\004\377\376\375\374"
I

unsigned int (符号なし整数, エンディアンと int のサイズに依存)

リトルエンディアン, 32bit int:

    "\001\002\003\004\377\376\375\374".unpack("I*") # => [67305985, 4244504319]

    [67305985, 4244504319].pack("I*") # => "\001\002\003\004\377\376\375\374"
    [67305985, -50462977].pack("I*")  # => "\001\002\003\004\377\376\375\374"

ビッグエンディアン, 32bit int:

    "\001\002\003\004\377\376\375\374".unpack("I*") # => [16909060, 4294901244]

    [16909060, 4294901244].pack("I*") # => "\001\002\003\004\377\376\375\374"
    [16909060, -66052].pack("I*")     # => "\001\002\003\004\377\376\375\374"
l

long (32bit 符号つき整数, エンディアンに依存) (l! は 32bit でなく、long のサイズに依存)

リトルエンディアン, 32bit long:

    "\001\002\003\004\377\376\375\374".unpack("l*") # => [67305985, -50462977]

    [67305985, 4244504319].pack("l*") # => RangeError
    [67305985, -50462977].pack("l*")  # => "\001\002\003\004\377\376\375\374"
L

unsigned long (32bit 符号なし整数, エンディアンに依存) (L! は 32bit でなく、long のサイズに依存)

リトルエンディアン, 32bit long:

    "\001\002\003\004\377\376\375\374".unpack("L*") # => [67305985, 4244504319]

    [67305985, 4244504319].pack("L*") # => "\001\002\003\004\377\376\375\374"
    [67305985, -50462977].pack("L*")  # => "\001\002\003\004\377\376\375\374"
q

long long (符号付き整数, エンディアンと long long のサイズに依存) (C で long long が扱えない場合には 64bit)

リトルエンディアン, 64bit long long:

    "\001\002\003\004\005\006\007\010\377\376\375\374\373\372\371\370".unpack("q*")
    # => [578437695752307201, -506097522914230529]

    [578437695752307201, -506097522914230529].pack("q*")
    # => "\001\002\003\004\005\006\a\010\377\376\375\374\373\372\371\370"
    [578437695752307201, 17940646550795321087].pack("q*")
    # => "\001\002\003\004\005\006\a\010\377\376\375\374\373\372\371\370"
Q

unsigned long long (符号なし整数, エンディアンと long long のサイズに依存) (C で long long が扱えない場合には 64bit)

リトルエンディアン, 64bit long long:

    "\001\002\003\004\005\006\007\010\377\376\375\374\373\372\371\370".unpack("Q*")
    # => [578437695752307201, 17940646550795321087]

    [578437695752307201, 17940646550795321087].pack("Q*")
    # => "\001\002\003\004\005\006\a\010\377\376\375\374\373\372\371\370"
    [578437695752307201, -506097522914230529].pack("Q*")
    # => "\001\002\003\004\005\006\a\010\377\376\375\374\373\372\371\370"
m

base64された文字列。60 オクテットごと(と最後)に改行コードが付加されます。

Base64は、3オクテット(8bits * 3 = 24bits)のバイナリコードをASCII文字の うちの65文字 ([A-Za-z0-9+/]の64文字とpaddingのための'=')だけを使用して 4オクテット(6bits * 4 = 24bits)の印字可能文字列に変換するエンコーディ ング法です。[RFC2045] で定義されています。

    [""].pack("m")             # => ""
    ["\0"].pack("m")           # => "AA==\n"
    ["\0\0"].pack("m")         # => "AAA=\n"
    ["\0\0\0"].pack("m")       # => "AAAA\n"
    ["\377"].pack("m")         # => "/w==\n"
    ["\377\377"].pack("m")     # => "//8=\n"
    ["\377\377\377"].pack("m") # => "////\n"

    ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"].pack("m")
    # => "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n"
    ["abcdefghijklmnopqrstuvwxyz"].pack("m3")
    # => "YWJj\nZGVm\nZ2hp\namts\nbW5v\ncHFy\nc3R1\ndnd4\neXo=\n"

    "".unpack("m")       # => [""]
    "AA==\n".unpack("m") # => ["\000"]
    "AA==".unpack("m")   # => ["\000"]

    "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m")
    # => ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
    "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m")
    # => ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
M

quoted-printable encoding された文字列

    ["a b c\td \ne"].pack("M") # => "a b c\td =\n\ne=\n"

    "a b c\td =\n\ne=\n".unpack("M") # => ["a b c\td \ne"]
n

ネットワークバイトオーダー(ビッグエンディアン)のunsigned short (16bit 符号なし整数)

    [0,1,-1,32767,-32768,65535].pack("n*")
    # => "\000\000\000\001\377\377\177\377\200\000\377\377"

    "\000\000\000\001\377\377\177\377\200\000\377\377".unpack("n*")
    # => [0, 1, 65535, 32767, 32768, 65535]
N

ネットワークバイトオーダー(ビッグエンディアン)のunsigned long (32bit 符号なし整数)

    [0,1,-1].pack("N*") # => "\000\000\000\000\000\000\000\001\377\377\377\377"

    "\000\000\000\000\000\000\000\001\377\377\377\377".unpack("N*") # => [0, 1, 4294967295]
v

"VAX"バイトオーダー(リトルエンディアン)のunsigned short (16bit 符号なし整数)

    [0,1,-1,32767,-32768,65535].pack("v*")
    # => "\000\000\001\000\377\377\377\177\000\200\377\377"

    "\000\000\001\000\377\377\377\177\000\200\377\377".unpack("v*")
    # => [0, 1, 65535, 32767, 32768, 65535]
V

"VAX"バイトオーダー(リトルエンディアン)のunsigned long (32bit 符号なし整数)

    [0,1,-1].pack("V*") # => "\000\000\000\000\001\000\000\000\377\377\377\377"

    "\000\000\000\000\001\000\000\000\377\377\377\377".unpack("V*") # => [0, 1, 4294967295]
f

単精度浮動小数点数(機種依存)

IA-32 (x86) (IEEE754 単精度 リトルエンディアン):

    [1.0].pack("f")      # => "\000\000\200?"
    [0.0/0.0].pack("f")  # => "\000\000\300\377"      # NaN
    [1.0/0.0].pack("f")  # => "\000\000\200\177"      # +Inf
    [-1.0/0.0].pack("f") # => "\000\000\200\377"      # -Inf

SPARC (IEEE754 単精度 ビッグエンディアン):

    [1.0].pack("f")      # => "?\200\000\000"
    [0.0/0.0].pack("f")  # => "\177\377\377\377"      # NaN
    [1.0/0.0].pack("f")  # => "\177\200\000\000"      # +Inf
    [-1.0/0.0].pack("f") # => "\377\200\000\000"      # -Inf

VAX (NetBSD 3.0) (非IEEE754):

    [1.0].pack("f") # => "\200@\000\000"
d

倍精度浮動小数点数(機種依存)

IA-32 (IEEE754 倍精度 リトルエンディアン):

    [1.0].pack("d")      # => "\000\000\000\000\000\000\360?"
    [0.0/0.0].pack("d")  # => "\000\000\000\000\000\000\370\377"      # NaN
    [1.0/0.0].pack("d")  # => "\000\000\000\000\000\000\360\177"      # +Inf
    [-1.0/0.0].pack("d") # => "\000\000\000\000\000\000\360\377"      # -Inf

SPARC (IEEE754 倍精度 ビッグエンディアン):

    [1.0].pack("d")      # => "?\360\000\000\000\000\000\000"
    [0.0/0.0].pack("d")  # => "\177\377\377\377\377\377\377\377"      # NaN
    [1.0/0.0].pack("d")  # => "\177\360\000\000\000\000\000\000"      # +Inf
    [-1.0/0.0].pack("d") # => "\377\360\000\000\000\000\000\000"      # -Inf

VAX (NetBSD 3.0) (非IEEE754):

    [1.0].pack("d") # => "\200@\000\000\000\000\000\000"
e

リトルエンディアンの単精度浮動小数点数(機種依存)

IA-32 (IEEE754):

    [1.0].pack("e") # => "\000\000\200?"

SPARC (IEEE754):

    [1.0].pack("e") # => "\000\000\200?"
E

リトルエンディアンの倍精度浮動小数点数(機種依存)

IA-32 (IEEE754):

    [1.0].pack("E") # => "\000\000\000\000\000\000\360?"

SPARC (IEEE754):

    [1.0].pack("E") # => "\000\000\000\000\000\000\360?"
g

ビッグエンディアンの単精度浮動小数点数(機種依存)

IA-32 (IEEE754):

    [1.0].pack("g") # => "?\200\000\000"

SPARC (IEEE754):

    [1.0].pack("g") # => "?\200\000\000"

IEEE754準拠な環境の場合、以下のようにして符号、指数部、仮数部を取り出せます。

    s = [v].pack("g").unpack("B*")[0][0,1]      # 符号
    e = [v].pack("g").unpack("B*")[0][1,8]      # 指数部
    f = [v].pack("g").unpack("B*")[0][9,23]     # 仮数部

そして、s, e, f の意味は以下の通りです。

    sgn = s == "0" ? +1.0 : -1.0
    exp = Integer("0b" + e)
    fra = Integer("0b" + f)
    if exp == 0
      if fra == 0
        sgn * 0                     # ±0 (positive/negative zero)
      else
        sgn * fra * 2**(-126-23)    # 非正規化数 (denormalized number)
      end
    elsif exp == 255
      if fra == 0
        sgn * Inf                   # ±∞ (positive/negative infinity)
      else
        NaN                         # 非数 (not a number)
      end
    else
      fra += 1 << 23                # ゲタ
      sgn * fra * 2**(exp-127-23)   # 正規化数 (normalized number)
    end
G

ビッグエンディアンの倍精度浮動小数点数(機種依存)

IA-32:

    [1.0].pack("G") # => "?\360\000\000\000\000\000\000"

SPARC:

    [1.0].pack("G") # => "?\360\000\000\000\000\000\000"

IEEE754準拠な環境の場合、以下のようにして符号、指数部、仮数部を取り出せます。

    s = [v].pack("G").unpack("B*")[0][0,1]    # 符号
    e = [v].pack("G").unpack("B*")[0][1,11]   # 指数部
    f = [v].pack("G").unpack("B*")[0][12,52]  # 仮数部

そして、s, e, f の意味は以下の通りです。

    sgn = s == "0" ? +1.0 : -1.0
    exp = Integer("0b" + e)
    fra = Integer("0b" + f)
    if exp == 0
      if fra == 0
        sgn * 0                     # ±0 (positive/negative zero)
      else
        sgn * fra * 2**(-1022-52)   # 非正規化数 (denormalized number)
      end
    elsif exp == 2047
      if fra == 0
        sgn * Inf                   # ±∞ (positive/negative infinity)
      else
        NaN                         # 非数 (not a number)
      end
    else
      fra += 1 << 52                # ゲタ
      sgn * fra * 2**(exp-1023-52)  # 正規化数 (normalized number)
    end
p

ナル終端の文字列へのポインタ

    [""].pack("p")             # => "\310\037\034\010"
    ["a", "b", "c"].pack("p3") # => " =\030\010\340^\030\010\360^\030\010"
    [nil].pack("p")            # => "\000\000\000\000"
P

構造体(固定長文字列)へのポインタ

    [nil].pack("P")    # => "\000\000\000\000"
    ["abc"].pack("P3") # => "x*\024\010"

    ["abc"].pack("P4") # => ArgumentError: too short buffer for P(3 for 4)
    [""].pack("P")     # => ArgumentError: too short buffer for P(0 for 1)
u

uuencodeされた文字列

    [""].pack("u")           # => ""
    ["a"].pack("u")          # => "!80``\n"
    ["abc"].pack("u")        # => "#86)C\n"
    ["abcd"].pack("u")       # => "$86)C9```\n"
    ["a"*45].pack("u")       # => "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n"
    ["a"*46].pack("u")       # => "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n"
    ["abcdefghi"].pack("u6") # => "&86)C9&5F\n#9VAI\n"
U

UTF-8

    [0].pack("U")                               # => "\000"
    [1].pack("U")                               # => "\001"
    [0x7f].pack("U")                            # => "\177"
    [0x80].pack("U")                            # => "\302\200"
    [0x7fffffff].pack("U")                      # => "\375\277\277\277\277\277"
    [0x80000000].pack("U")                      # => RangeError
    [0,256,65536].pack("U3")                    # => "\000\304\200\360\220\200\200"

    "\000\304\200\360\220\200\200".unpack("U3") # => [0, 256, 65536]
    "\000\304\200\360\220\200\200".unpack("U")  # => [0]
    "\000\304\200\360\220\200\200".unpack("U*") # => [0, 256, 65536]
w

BER圧縮整数

1バイトあたり7ビットを使用して必要最小限のバイト数で任意サイズの 0以上の整数を表す数値表現。各バイトの最上位ビットはデータの最後 を除いて必ず1が立っている(つまり最上位ビットはどこまでデータがあ るかを示している)。

ISO/IEC 8825-1:1995 : Information technology−ASN.1 encoding rules : Specification of Basic Encoding Rules(BER) に定められる整数の符号化方法。

    [0].pack("w")             # => "\000"
    [1].pack("w")             # => "\001"
    [127].pack("w")           # => "\177"
    [128].pack("w")           # => "\201\000"
    [0x3fff].pack("w")        # => "\377\177"
    [0x4000].pack("w")        # => "\201\200\000"
    [0x3fffffff].pack("w")    # => "\203\377\377\377\177"
    [0x40000000].pack("w")    # => "\204\200\200\200\000"
    [0xffffffff].pack("w")    # => "\217\377\377\377\177"
    [0x100000000].pack("w")   # => "\220\200\200\200\000"

    "\0".unpack("w")          # => [0]
    "\0\201\0\1".unpack("w*") # => [0, 128, 1]

なお、BER圧縮整数でエンコードした結果は大小関係を保存しない。 たとえば、[0x3fff].pack("w") > [0x4000].pack("w") である。

x

ナルバイト/1バイト読み飛ばす

    [?a, ?b].pack("CxC")    # => "a\000b"
    [?a, ?b].pack("Cx3C")   # => "a\000\000\000b"

    "a\000b".unpack("CxC")  # => [97, 98]
    "a\377b".unpack("CxC")  # => [97, 98]
    "a\377b".unpack("Cx3C") # => ArgumentError: x outside of string
X

1バイト後退

    [?a, ?b, ?c].pack("CCXC") # => "ac"

    "abcdef".unpack("x*XC") # => [102]
@

絶対位置への移動

    [?a, ?b].pack("C @3 C") # => "a\000\000b"

    "a\000\000b".unpack("C @3 C") # => [97, 98]

使用例

以下、pack/unpack の使用例の一部です。

pack を使用しなくても同じことができる場合はその例も載せています。 pack は暗号になりやすい面があることを考慮し、pack を使いたくない人 に別解を示すためです。

数値(文字コード)の配列を文字列に変換する例
    [82, 117, 98, 121].pack("cccc")  # => "Ruby"
    [82, 117, 98, 121].pack("c4")    # => "Ruby"
    [82, 117, 98, 121].pack("c*")    # => "Ruby"

    s = ""
    [82, 117, 98, 121].each {|c| s << c}
    s    # => "Ruby"

    [82, 117, 98, 121].collect {|c| sprintf "%c", c}.join   # => "Ruby"

    [82, 117, 98, 121].inject("") {|s, c| s << c}    # => "Ruby"
文字列を数値(文字コード)の配列に変換する例
    "Ruby".unpack('C*')    # => [82, 117, 98, 121]

    a = []
    "Ruby".each_byte {|c| a << c}
    a    # => [82, 117, 98, 121]
"x" でナルバイトを埋めることができる
    [82, 117, 98, 121].pack("ccxxcc")    # => "Ru\000\000by"
"x" で文字を読み飛ばす事が出来る
    "Ru\0\0by".unpack('ccxxcc')    # => [82, 117, 98, 121]
Hexダンプを数値の配列に変換する例
    "61 62 63 64 65 66".delete(' ').to_a.pack('H*').unpack('C*')
    # => [97, 98, 99, 100, 101, 102]

    "61 62 63 64 65 66".split.collect {|c| c.hex}
    # => [97, 98, 99, 100, 101, 102]
バイナリと16進数のpackでは長さ指定は生成されるバイト数ではなく、ビットやニブルの個数を表す
    [0b01010010, 0b01110101, 0b01100010, 0b01111001].pack("C4")
    # => "Ruby"
    ["01010010011101010110001001111001"].pack("B32") # 8 bits * 4
    # => "Ruby"

    [0x52, 0x75, 0x62, 0x79].pack("C4")
    # => "Ruby"
    ["52756279"].pack("H8")  # 2 nybbles * 4
    # => "Ruby"
テンプレート文字'a'の長さ指定は1つの文字列だけに適用される
    ["RUBY", "u", "b", "y"].pack("a4")
    # => "RUBY"

    ["RUBY", "u", "b", "y"].pack("aaaa")
    # => "Ruby"

    ["RUBY", "u", "b", "y"].pack("a*aaa")
    # => "RUBYuby"
テンプレート文字"a"は、長さが足りない分をヌル文字で補う
    ["Ruby"].pack("a8")
    # => "Ruby\000\000\000\000"
リトルエンディアンとビッグエンディアン
    [1,2].pack("s2")
    # => "\000\001\000\002" # ビッグエンディアンのシステムでの出力
    # => "\001\000\002\000" # リトルエンディアンのシステムでの出力

    [1,2].pack("n2")
    # => "\000\001\000\002" # システムによらずビッグエンディアン

    [1,2].pack("v2")
    # => "\001\000\002\000" # システムによらずリトルエンディアン
ネットワークバイトオーダの signed long
      s = "\xff\xff\xff\xfe"
      n = s.unpack("N")[0]
      if n[31] == 1
        n = -((n ^ 0xffff_ffff) + 1)
      end
      n # => -2
ネットワークバイトオーダの signed long(その2)
      s = "\xff\xff\xff\xfe"
      n = s.unpack("N").pack("l").unpack("l")[0]
      n # => -2
IPアドレス
      require 'socket'
      Socket.gethostbyname("localhost")[3].unpack("C4").join(".")
      # => "127.0.0.1"

      "127.0.0.1".split(".").collect {|c| c.to_i}.pack("C4")
      # => "\177\000\000\001"
sockaddr_in 構造体
      require 'socket'
      [Socket::AF_INET,
       Socket.getservbyname('echo'),
       127, 0, 0, 1].pack("s n C4 x8")
      # => "\002\000\000\a\177\000\000\001\000\000\000\000\000\000\000\000"

pack/unpack を使う代わりに Socket.pack_sockaddr_in, Socket.unpack_sockaddr_in メソッドがあります。

'\0'終端文字列のアドレス

テンプレート文字 "p" や "P" は、C 言語レベルのインタフェースのた めにあります(例えば IO#ioctl)。

    ["foo"].pack("p")    # => "8\266\021\010"

結果の文字列はゴミに見えますが、実際は文字列"foo\0"を指すアドレ ス(のバイナリ表現)です。以下のようにすれば見慣れた表記で見ること が出来ます

    printf "%#010x\n", "8\266\021\010".unpack("L")[0] # => 0x0811b638

アドレスが指す先のオブジェクト(この例で "foo\0") は、pack の結 果が GC されるまではGCされないことが保証されています。

unpack("p"), unpack("P") は、pack の結果からしか unpack できません。

    ["foo"].pack("p").unpack("p") # => ["foo"]
    "8\266\021\010".unpack("p")
    # => -:1:in `unpack': no associated pointer (ArgumentError)
    #         from -:1

"p" や "P" は、nil を特別に扱い NULL ポインタとして解釈します。(以下は、32bitマシンで一般的な結果)

      [nil].pack("p")        # => "\000\000\000\000"
      "\0\0\0\0".unpack("p") # => [nil]
構造体のアドレス

例えば、

      struct {
        int   a;
        short b;
        long  c;
      } v = {1,2,3};

を表す文字列は

      v = [1,2,3].pack("i!s!l!")

です。(byte alignment の問題から実際は適当な padding が必要に なるかもしれません)

この構造体を指すアドレスは

      [v].pack("P")  # => "\300\265\021\010"

で得られます。

UTF-8からUCS-2への変換 (サロゲートを処理していないので UTF-16 とはいえない)

Little endian:

    ("Comments").unpack("U*").pack("v*") # => "C\000o\000m\000m\000e\000n\000t\000s\000"

Big endian:

    ("Comments").unpack("U*").pack("n*") # => "\000C\000o\000m\000m\000e\000n\000t\000s"
upcase -> String[permalink][rdoc]

'a' から 'z' までのアルファベット小文字を大文字に変換した文字列を作成して返します。

このメソッドはマルチバイト文字列を認識しますが、 それはあくまでも「1 文字を 1 文字として認識する」だけであって、 いわゆる全角アルファベットの大文字小文字までは変換しません。

また、マルチバイト文字列に対応するためには $KCODE を設定する必要があります。 文字列が Shift JIS エンコーディングで $KCODE が適切に設定されていないときは 以下のようにマルチバイト文字の一部も変換してしまいます。

#coding:Shift_JIS
$KCODE = "SJIS"
puts "蟻".upcase   # => 蟻   ($KCODE が適切なので正しく無視された)

$KCODE = "NONE"
puts "蟻".upcase   # => 帰   ($KCODE が不適切なので誤って処理された)

例:

p "stRIng? STring.".upcase   # => "STRING? STRING."

[SEE_ALSO] String#upcase!, String#downcase, String#swapcase, String#capitalize

upcase! -> self | nil[permalink][rdoc]

ASCII 文字列の範囲内で 'a' から 'z' までの アルファベット小文字を全て大文字にします。 このメソッドは self を破壊的に変更して返しますが、 置換が起こらなかった場合は nil を返します。

このメソッドはマルチバイト文字列を認識しますが、 それはあくまでも「1 文字を 1 文字として認識する」だけであって、 いわゆる全角アルファベットの大文字小文字までは変換しません。

また、マルチバイト文字列に対応するためには $KCODE を設定する必要があります。 文字列が Shift JIS エンコーディングで $KCODE が適切に設定されていないときは 以下のようにマルチバイト文字の一部も変換してしまいます。

#coding:Shift_JIS
$KCODE = "SJIS"
str = "蟻"
str.upcase!
puts str   # => 蟻   ($KCODE が適切なので正しく無視された)

$KCODE = "NONE"
str = "蟻"
str.upcase!
puts str   # => 帰   ($KCODE が不適切なので誤って処理された)

例:

buf = "stRIng? STring."
buf.upcase!
p buf   # => "STRING? STRING."

[SEE_ALSO] String#upcase, String#downcase!, String#swapcase!, String#capitalize!

upto(max, exclusive = false) {|s| ... } -> self[permalink][rdoc]

self から始めて max まで 「次の文字列」を順番にブロックに与えて繰り返します。 「次」の定義については String#succ を参照してください。

たとえば以下のコードは a, b, c, ... z, aa, ... az, ..., za を 出力します。

("a" .. "za").each do |str|
  puts str
end
'a'.upto('za') do |str|
  puts str
end
[PARAM] max:
繰り返しをやめる文字列
[PARAM] exclusive:
max を含むかどうか。false の場合は max を含む。