class String

[edit]

dynamic include: JSON::Generator::GeneratorMethods::String (by json)

dynamic extend: JSON::Generator::GeneratorMethods::String::Extend (by json)

要約

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

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

文字列リテラルの例

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

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

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

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

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

# 中身がインデントされたヒアドキュメント
# シングルクオート、ダブルクオートとの併用も可能
<<~End
  この行のインデントは無視される
End

破壊的な変更

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

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

例:String#upcase!

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

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

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

例:String#upcase

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

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

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

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

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

多言語化と文字列のエンコーディング

String オブジェクトは自身のエンコーディング情報を持ちます。インスタンスメソッドはエンコーディングに従い、1バイトではなく1文字を単位として動作します。エンコーディングの変換にはメソッド String#encode を使います。

例:エンコーディングの変換

p "いろは".size      #=> 3 
p "漢字"[0]          #=> "漢"
p "山本山".reverse   #=> "山本山" (回文なので分からないですね)
p "ループ".reverse   #=> "プール"

s = "ruビー"
s[0..1] = "" 
p s                  #=> "ルビー"

e = "言語".encode("EUC-JP")
u = "言語".encode("UTF-8")
p e.encoding                   #=> Encoding::EUC_JP
p u.encoding                   #=> Encoding::UTF_8

より詳しく知りたい場合は、多言語化 を参照してください。

文字列同士の比較・結合

文字列同士の比較・結合などでは両者のエンコーディングを意識する必要があります。例えば String#==String#eql? は両者のエンコーディングが等しくバイト列表現が等しい場合にのみ true を返します。このときエンコーディングが UTF-8 であっても正規化せずに比較します。文字列の結合も同様です。異なるエンコーディング同士の文字列を結合する時は明示的にエンコーディングを変換する必要があります。

例:文字列の結合

s = "いろは"
a = s.encode("EUC-JP")
b = s.encode("UTF-8")
p a == b                            #=> false

s = "".encode("EUC-JP")
p s + "\u{4f53}".encode("EUC-JP")   #=> "合体"
p s + "\u{4f53}"                    #=> Encoding::CompatibilityError

String#eql? はハッシュのキーの比較に使われますので、ハッシュのキーに非 ASCII 文字列を使う場合には注意が必要です。

動作例:  (注)一行目にmagic commentが必要です。

# encoding: UTF-8
h = {}
s = "いろは"
s.force_encoding("EUC-JP")
h[s] = 1
s.force_encoding("ASCII-8BIT")
p h[s]                             #=> nil

7bit クリーンな文字列

ASCII 互換エンコーディングをもつ 7bit クリーンな文字列はエンコーディングに関わらず ASCII として扱うことができます。例えば String#== は両者の文字エンコーディングが異なっていても true を返します。 ASCII 互換エンコーディングをもつ文字列にエンコーディングの変換なしで結合することができます。

例:

s = "abc"
a = s.encode("EUC-JP")
b = s.encode("UTF-8")
p a == b                           #=> true
p a + b                            #=> "abcabc"

ここで言う「ASCII互換エンコーディング」とは、コードポイントが同一という意味ではなくバイト列が同じことを意味します。従って UTF-16 はASCII互換ではありません。また厳密性を追求せず、おおむね互換なら互換と呼びます。よって Shift_JIS は ASCII 互換です。

バイト列を表す文字列

文字列ではない単なるバイト列も String オブジェクトで表されます。その時のエンコーディングは ASCII-8BIT です。

目次

特異メソッド
インスタンスメソッド

継承しているメソッド

Comparableから継承しているメソッド

特異メソッド

new(string = "") -> String[permalink][rdoc][edit]
new(string = "", encoding: string.encoding, capacity: 127) -> String
new(string = "", encoding: string.encoding, capacity: string.bytesize) -> String

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

[PARAM] string:
文字列
[PARAM] encoding:
作成する文字列のエンコーディングを文字列か Encoding オブジェクトで指定します(変換は行われません)。省略した場合は引数 string のエンコーディングと同じになります(ただし、string が指定されていなかった場合は Encoding::ASCII_8BITになります)。
[PARAM] capacity:
内部バッファのサイズを指定します。指定することで、なんども文字列連結する (そしてreallocがなんども呼ばれる)ときのパフォーマンスが改善されるかもしれません。省略した場合、引数stringのバイト数が127未満であれば127、それ以上であればstring.bytesizeになります。
[RETURN]
引数 string と同じ内容の文字列オブジェクト


text = "hoge".encode("EUC-JP")
no_option = String.new(text)                             # => "hoge"
no_option.encoding == Encoding::EUC_JP                   # => true
with_encoding = String.new(text, encoding: "UTF-8")      # => "hoge"
with_encoding.encoding == Encoding::UTF_8                # => true
String.new("test", encoding: "UTF-8", capacity: 100_000) # => "test"
try_convert(obj) -> String | nil[permalink][rdoc][edit]

obj を String に変換しようと試みます。変換には Object#to_str メソッドが使われます。変換後の文字列を返すか、何らかの理由により変換できなかった場合は nil が返されます。

[PARAM] obj:
変換する任意のオブジェクト
[RETURN]
変換後の文字列または nil


String.try_convert("str")     # => "str"
String.try_convert(/re/)      # => nil

インスタンスメソッド

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

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$][フラグ][幅][.精度]指示子
%[<name>][フラグ][幅][.精度]指示子

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

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

フラグ

フラグには #, +, ' '(スペース), -, 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)  #=> "0"
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, s, p
  • 整数を表す指示子: d, i, u, b, B, o, x, X,
  • 浮動小数点数を表す指示子: f, g, e, E, G

があります

c

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


p sprintf("%c", 97)  #=> "a"
p sprintf("%c", 'a') #=> "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) #=> "-1"
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       "

# ruby 1.9.1 以降では「精度」を指定した場合も、".." は付加されます 
p sprintf("%.10x", -1) #=> "..ffffffff" 
f
e
E
g
G
a
A

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

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

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

a, A は指数表現の16進数("-h.hhh±pd") で数値を出力します。ただし、Float::INFINITYFloat::NAN はそれぞれ 'Inf'、'NaN' になります。詳しくは [ruby-dev:40650] を参照してください。


p sprintf("%a", -0.0)            # => "-0x0p+0"
p sprintf("%a", 729.0/10)        # => "0x1.239999999999ap+6"
p sprintf("%a", Float::INFINITY) # => "Inf"

大文字の指示子(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"
%<name>

Symbol のインスタンス name をキーとする Hash を引数にした場合、対応する値をフォーマットして参照します。


p sprintf('%<foo>f : %<bar>+d', foo: 1, bar: 2) #=> "1.000000 : +2"
%{name}

Symbol のインスタンス name をキーとする Hash を引数にした場合、対応する値をフォーマットせずに参照します。幅や精度を指定するために使用することができます。


p sprintf('%{foo}f : %{bar}+d', foo: 1, bar: 2) #=> "1f : 2+d"
self * times -> String[permalink][rdoc][edit]

文字列の内容を 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][edit]

文字列と 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 -> String | self[permalink][rdoc][edit]

self が freeze されている文字列の場合、元の文字列の複製を返します。 freeze されていない場合は self を返します。



# frozen_string_literal: false
original_text = "text"
unfrozen_text = +original_text
original_text == unfrozen_text      # => true
original_text.equal?(unfrozen_text) # => true

frozen_text = "text".freeze
unfrozen_text = +frozen_text
frozen_text == unfrozen_text        # => true
frozen_text.equal?(unfrozen_text)   # => false

[SEE_ALSO] String#-@

- self -> String | self[permalink][rdoc][edit]

self が freeze されている文字列の場合、self を返します。 freeze されていない場合は元の文字列の freeze された (できる限り既存の) 複製を返します。



# frozen_string_literal: false
original_text = "text"
unfrozen_text = -original_text
original_text == unfrozen_text      # => true
original_text.equal?(unfrozen_text) # => false

frozen_text = "text".freeze
unfrozen_text = -frozen_text
frozen_text == unfrozen_text        # => true
frozen_text.equal?(unfrozen_text)   # => true

[SEE_ALSO] String#+@

self << other -> self[permalink][rdoc][edit]
concat(other) -> self

self に文字列 other を破壊的に連結します。 other が 整数である場合は other.chr(self.encoding) 相当の文字を末尾に追加します。

self を返します。

[PARAM] other:
文字列もしくは 0 以上の整数


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

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

str << 65  # 文字AのASCIIコード
p str    # => "stringXXXYYYA"
concat(*arguments) -> self[permalink][rdoc][edit]

self に複数の文字列を破壊的に連結します。

引数の値が整数である場合は Integer#chr の結果に相当する文字を末尾に追加します。追加する文字のエンコーディングは self.encoding です。

self を返します。

[PARAM] arguments:
複数の文字列もしくは 0 以上の整数


str = "foo"
str.concat
p str    # => "foo"

str = "foo"
str.concat "bar", "baz"
p str    # => "foobarbaz"

str = "foo"
str.concat("!", 33, 33)
p str    # => "foo!!!"
self <=> other -> -1 | 0 | 1 | nil[permalink][rdoc][edit]

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

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][edit]
self === other -> bool

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][edit]

正規表現 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] -> String | nil[permalink][rdoc][edit]
slice(nth) -> String | nil

nth 番目の文字を返します。 nth が負の場合は文字列の末尾から数えます。つまり、 self.size + nth 番目の文字を返します。

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

[PARAM] nth:
文字の位置を表す整数
[RETURN]
指定した位置の文字を表す String オブジェクト


p 'bar'[2]       # => "r"
p 'bar'[2] == ?r # => true
p 'bar'[-1]      # => "r"
p 'bar'[3]       # => nil
p 'bar'[-4]      # => nil

このメソッドの仕様は 1.8.x 以前から大きく変更されていますので注意が必要です。

self[nth, len] -> String | nil[permalink][rdoc][edit]
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[-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][edit]
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][edit]
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[regexp, name] -> String[permalink][rdoc][edit]
slice(regexp, name) -> String

正規表現 regexp の name で指定した名前付きキャプチャにマッチする最初の部分文字列を返します。正規表現が self にマッチしなかった場合は nil を返します。

[PARAM] regexp:
正規表現を指定します。
[PARAM] name:
取得したい部分文字列のパターンを示す正規表現レジスタを示す名前
[EXCEPTION] IndexError:
name に対応する括弧がない場合に発生します。


s = "FooBar"
s[/(?<foo>[A-Z]..)(?<bar>[A-Z]..)/]        # => "FooBar"
s[/(?<foo>[A-Z]..)(?<bar>[A-Z]..)/, "foo"] # => "Foo"
s[/(?<foo>[A-Z]..)(?<bar>[A-Z]..)/, "bar"] # => "Bar"
s[/(?<foo>[A-Z]..)(?<bar>[A-Z]..)/, "baz"] # => IndexError
self[range] -> String[permalink][rdoc][edit]
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][edit]

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

[PARAM] nth:
置き換えたい文字の位置を指定します。
[PARAM] val:
置き換える文字列を指定します。
[RETURN]
val を返します。


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

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][edit]

文字列中の 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][edit]

正規表現 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, name] = val[permalink][rdoc][edit]

正規表現 regexp の name で指定した名前付きキャプチャにマッチする最初の部分文字列を文字列 val で置き換えます。

[PARAM] regexp:
置き換えたい部分文字列のパターンを示す正規表現
[PARAM] name:
置き換えたい部分文字列のパターンを示す正規表現レジスタを示す名前
[PARAM] val:
指定範囲の部分文字列と置き換えたい文字列
[RETURN]
val を返します。
[EXCEPTION] IndexError:
name で指定した名前付きキャプチャが存在しない場合に発生します。


s = "FooBar"
s[/(?<foo>[A-Z]..)(?<bar>[A-Z]..)/, "foo"] = "Baz"
p s # => "BazBar"
self[regexp] = val[permalink][rdoc][edit]

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

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


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

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

[PARAM] range:
置き換えたい範囲を示す Range オブジェクト
[RETURN]
val を返します。
ascii_only? -> bool[permalink][rdoc][edit]

文字列がASCII文字のみで構成されている場合に true を返します。さもなくば false を返します。

例:

'abc123'.ascii_only?        # => true
''.ascii_only?              # => true
'日本語'.ascii_only?        # => false
'日本語abc123'.ascii_only?  # => false
b -> String[permalink][rdoc][edit]

self の文字エンコーディングを ASCII-8BIT にした文字列の複製を返します。



'abc123'.encoding    # => #<Encoding:UTF-8>
'abc123'.b.encoding  # => #<Encoding:ASCII-8BIT>
bytes -> [Integer][permalink][rdoc][edit]
bytes {|byte| ... } -> self

文字列の各バイトを数値の配列で返します。(self.each_byte.to_a と同じです)



"str".bytes # => [115, 116, 114]

ブロックが指定された場合は String#each_byte と同じように動作します。ただし obsolete のため、ブロックを指定する場合は String#each_byte を使用してください。

[SEE_ALSO] String#each_byte

bytesize -> Integer[permalink][rdoc][edit]

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



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

[SEE_ALSO] String#size

byteslice(nth) -> String | nil[permalink][rdoc][edit]

nth バイト目の文字を返します。nth が負の場合は文字列の末尾から数えます。引数が範囲外を指定した場合は nil を返します。

[PARAM] nth:
文字の位置を表す整数を指定します。
[RETURN]
切り出した文字列を返します。戻り値の文字エンコーディングは自身と同じです。


"hello".byteslice(1)  # => "e"
"hello".byteslice(-1) # => "o"
"\u3042".byteslice(0) # => "\xE3"
"\u3042".byteslice(1) # => "\x81"

[SEE_ALSO] String#slice

byteslice(nth, len) -> String | nil[permalink][rdoc][edit]

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

[PARAM] nth:
取得したい文字列の開始バイトを整数で指定します。
[PARAM] len:
取得したい文字列の長さを正の整数で指定します。
[RETURN]
切り出した文字列を返します。戻り値の文字エンコーディングは自身と同じです。


"hello".byteslice(1, 2)              # => "el"
"\u3042\u3044\u3046".byteslice(0, 3) # => "\u3042"

[SEE_ALSO] String#slice

byteslice(range) -> String | nil[permalink][rdoc][edit]

range で指定したバイトの範囲に含まれる部分文字列を返します。引数が範囲外を指定した場合は nil を返します。

[PARAM] range:
取得したい文字列の範囲を示す Range オブジェクト
[RETURN]
切り出した文字列を返します。戻り値の文字エンコーディングは自身と同じです。


"hello".byteslice(1..2)          # => "el"
"\x03\u3042\xff".byteslice(1..3) # => "\u3042"

[SEE_ALSO] String#slice

capitalize(*options) -> String[permalink][rdoc][edit]

文字列先頭の文字を大文字に、残りを小文字に変更した文字列を返します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。


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

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

capitalize!(*options) -> self | nil[permalink][rdoc][edit]

文字列先頭の文字を大文字に、残りを小文字に破壊的に変更します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。
[RETURN]
capitalize! は self を変更して返しますが、変更が起こらなかった場合は nil を返します。


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

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

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

casecmp(other) -> -1 | 0 | 1 | nil[permalink][rdoc][edit]

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

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

String#casecmp? と違って大文字小文字の違いを無視するのは Unicode 全体ではなく、A-Z/a-z だけです。

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


"aBcDeF".casecmp("abcde")     #=> 1
"aBcDeF".casecmp("abcdef")    #=> 0
"aBcDeF".casecmp("abcdefg")   #=> -1
"abcdef".casecmp("ABCDEF")    #=> 0

nil は文字列のエンコーディングが非互換の時に返されます。


"\u{e4 f6 fc}".encode("ISO-8859-1").casecmp("\u{c4 d6 dc}")   #=> nil

[SEE_ALSO] String#<=>, Encoding#compatible?

casecmp?(other) -> bool | nil[permalink][rdoc][edit]

大文字小文字の違いを無視し文字列を比較します。文字列が一致する場合には true を返し、一致しない場合には false を返します。

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


"abcdef".casecmp?("abcde")     #=> false
"aBcDeF".casecmp?("abcdef")    #=> true
"abcdef".casecmp?("abcdefg")   #=> false
"abcdef".casecmp?("ABCDEF")    #=> true
"\u{e4 f6 fc}".casecmp?("\u{c4 d6 dc}") #=> true

nil は文字列のエンコーディングが非互換の時に返されます。


"\u{e4 f6 fc}".encode("ISO-8859-1").casecmp?("\u{c4 d6 dc}")   #=> nil

[SEE_ALSO] String#casecmp

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

長さ 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

chars -> [String][permalink][rdoc][edit]
chars {|cstr| block } -> self

文字列の各文字を文字列の配列で返します。(self.each_char.to_a と同じです)



"hello世界".chars # => ["h", "e", "l", "l", "o", "世", "界"]

ブロックが指定された場合は String#each_char と同じように動作します。ただし obsolete のため、ブロックを指定する場合は String#each_char を使用してください。

[SEE_ALSO] String#each_char

chomp(rs = $/) -> String[permalink][rdoc][edit]

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

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

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



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"

p "string\n".chomp(nil)  # => "string\n"

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

[SEE_ALSO] String#chomp!

[SEE_ALSO] String#chop

[SEE_ALSO] String#delete_suffix

chomp!(rs = $/) -> self | nil[permalink][rdoc][edit]

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

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

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

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


buf = "string\n"
buf.chomp!  # => nil
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"

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

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

[SEE_ALSO] String#chomp

[SEE_ALSO] String#chop!

[SEE_ALSO] String#delete_suffix!

chop -> String[permalink][rdoc][edit]

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



p "string\n".chop    # => "string"
p "string\r\n".chop  # => "string"
p "string".chop      # => "strin"
p "strin".chop       # => "stri"
p "".chop            # => ""

[SEE_ALSO] String#chomp

[SEE_ALSO] String#chop!

[SEE_ALSO] String#delete_suffix

chop! -> self | nil[permalink][rdoc][edit]

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

[RETURN]
chop! は self を変更して返しますが、取り除く文字がなかった場合は nil を返します。


str = "string\r\n"
ret = str.chop!
ret                  # => "string"
str                  # => "string"
str.chop!            # => "strin"
"".chop!             # => nil

[SEE_ALSO] String#chomp!

[SEE_ALSO] String#chop

[SEE_ALSO] String#delete_suffix!

chr -> String[permalink][rdoc][edit]

self の最初の文字だけを含む文字列を返します。



a = "abcde"
a.chr    #=> "a"

Ruby 1.9 で IO#getc の戻り値が Integer から String を返すように変更になりました。 Ruby 1.8 以前と1.9以降の互換性を保つために String#chr が存在します。

例:

# ruby 1.8 系では STDIN.getc が 116 を返すため Integer#chr が呼び出される
$ echo test | ruby -e "p STDIN.getc.chr" # => "t"
# ruby 1.9 系以降では STDIN.getc が "t" を返すため String#chr が呼び出される
$ echo test | ruby -e "p STDIN.getc.chr" # => "t"

[SEE_ALSO] String#ord, Integer#chr

clear -> self[permalink][rdoc][edit]

文字列の内容を削除して空にします。 self を返します。



str = "abc"
str.clear
p str     # => ""

str = ""
str.clear
p str   # => ""
codepoints -> [Integer][permalink][rdoc][edit]
codepoints {|codepoint| block } -> self

文字列の各コードポイントの配列を返します。(self.each_codepoint.to_a と同じです)



#coding:UTF-8
"hello わーるど".codepoints
# => [104, 101, 108, 108, 111, 32, 12431, 12540, 12427, 12393]

ブロックが指定された場合は String#each_codepoint と同じように動作します。ただし obsolete のため、ブロックを指定する場合は String#each_codepoint を使用してください。

[SEE_ALSO] String#each_codepoint

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

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][edit]

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

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

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

注意:

  • Ruby 2.6 から非推奨になったため、引き続き必要な場合は string-crypt gem の使用を検討してください。
  • crypt の処理は crypt(3) の実装に依存しています。 従って、crypt で処理される内容の詳細や salt の与え方については、 利用環境の crypt(3) 等を見て確認してください。
  • crypt の結果は利用環境が異なると変わる場合があります。 crypt の結果を、異なる利用環境間で使用する場合には注意して下さい。
  • 典型的な DES を使用した crypt(3) の場合、 self の最初の 8 バイト、salt の最初の 2 バイトだけが使用されます。
[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][edit]

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"

[SEE_ALSO] String#delete!

delete!(*strs) -> self | nil[permalink][rdoc][edit]

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

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

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

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

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


str = "123456789"
p str.delete!("2378")         #=> "14569"
p str                         #=> "14569"

str = "123456789"
p str.delete!("2-8", "^4-6")  #=> "14569"
p str                         #=> "14569"

str = "abc"
p str.delete!("2378")         #=> "nil"
p str                         #=> "abc"

[SEE_ALSO] String#delete

delete_prefix(prefix) -> String[permalink][rdoc][edit]

文字列の先頭から prefix を削除した文字列のコピーを返します。

[PARAM] prefix:
先頭から削除する文字列を指定します。
[RETURN]
文字列の先頭から prefix を削除した文字列のコピー

"hello".delete_prefix("hel") # => "lo"
"hello".delete_prefix("llo") # => "hello"

[SEE_ALSO] String#delete_prefix!

[SEE_ALSO] String#delete_suffix

[SEE_ALSO] String#start_with?

delete_prefix!(prefix) -> self | nil[permalink][rdoc][edit]

self の先頭から破壊的に prefix を削除します。

[PARAM] prefix:
先頭から削除する文字列を指定します。
[RETURN]
削除した場合は self、変化しなかった場合は nil

"hello".delete_prefix!("hel") # => "lo"
"hello".delete_prefix!("llo") # => nil

[SEE_ALSO] String#delete_prefix

[SEE_ALSO] String#delete_suffix!

[SEE_ALSO] String#start_with?

delete_suffix(suffix) -> String[permalink][rdoc][edit]

文字列の末尾から suffix を削除した文字列のコピーを返します。

[PARAM] suffix:
末尾から削除する文字列を指定します。
[RETURN]
文字列の末尾から suffix を削除した文字列のコピー

"hello".delete_suffix("llo") # => "he"
"hello".delete_suffix("hel") # => "hello"

[SEE_ALSO] String#chomp

[SEE_ALSO] String#chop

[SEE_ALSO] String#delete_prefix

[SEE_ALSO] String#delete_suffix!

[SEE_ALSO] String#end_with?

delete_suffix!(suffix) -> self | nil[permalink][rdoc][edit]

self の末尾から破壊的に suffix を削除します。

[PARAM] suffix:
末尾から削除する文字列を指定します。
[RETURN]
削除した場合は self、変化しなかった場合は nil

"hello".delete_suffix!("llo") # => "he"
"hello".delete_suffix!("hel") # => nil

[SEE_ALSO] String#chomp!

[SEE_ALSO] String#chop!

[SEE_ALSO] String#delete_prefix!

[SEE_ALSO] String#delete_suffix

[SEE_ALSO] String#end_with?

downcase(*options) -> String[permalink][rdoc][edit]

全ての大文字を対応する小文字に置き換えた文字列を返します。どの文字がどう置き換えられるかは、オプションの有無や文字列のエンコーディングに依存します。

[PARAM] options:
オプションの意味は以下の通りです。
オプションなし

完全な Unicode ケースマッピングに対応し、ほとんどの言語に適しています。(例外は以下の :turkic, :lithuanian オプションを参照) Unicode 標準の表 3-14 で説明されている、コンテキスト依存のケースマッピングは、現在サポートされていません。

:ascii

ASCII の範囲内のみ (A-Z, a-z) が影響します。このオプションは他のオプションと組み合わせることはできません。

:turkic

チュルク語族 (トルコ語、アゼルバイジャン語など) に適合した完全な Unicode ケースマッピングです。これはたとえば大文字の I は小文字のドットなしの i (ı) にマッピングされることを意味します。

:lithuanian

現在は、ただの完全な Unicode ケースマッピングです。将来、リトアニア語に対応した完全な Unicode ケースマッピングです。 (上にアクセントがあっても小文字の i のドットを維持します。)

:fold

downcase と downcase! のみで使えます。 Unicode ケースフォールディングは Unicode ケースマッピングより広範囲です。このオプションは今の所、他のオプションと組み合わせることはできません。 (すなわち現在チュルク語族のバリアントはありません。)

ASCII のみの大文字小文字変換で有効ないくつかの仮定は、より一般的なケース変換では成り立たないことに注意してください。例えば、結果の長さは入力の長さと同じとは限りません (文字数でもバイト数でも)。ラウンドトリップできるという仮定も成り立ちません (例えば str.downcase == str.upcase.downcase)。そして、Unicode 正規化 (すなわち String#unicode_normalize) はケースマッピング操作で必ずしも維持されるとは限りません。

現在 ASCII 以外のケースマッピング/フォールディングは、UTF-8, UTF-16BE/LE, UTF-32BE/LE, ISO-8859-1~16 の String/Symbol でサポートされています。他のエンコーディングもサポートされる予定です。



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

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

downcase!(*options) -> self | nil[permalink][rdoc][edit]

全ての大文字を対応する小文字に破壊的に置き換えます。どの文字がどう置き換えられるかは、オプションの有無や文字列のエンコーディングに依存します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。
[RETURN]
self を変更して返します。変更が無かった場合は nil を返します。


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

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

dump -> String[permalink][rdoc][edit]

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



# p だとさらにバックスラッシュが増えて見にくいので puts している
puts "abc\r\n\f\x00\b10\\\"".dump   # => "abc\r\n\f\000\01010\\\""

[SEE_ALSO] String#undump

each_byte {|byte| ... } -> self[permalink][rdoc][edit]
each_byte -> Enumerator

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



"str".each_byte do |byte|
  p byte
end
    # => 115
    # => 116
    # => 114

[SEE_ALSO] String#bytes

each_char {|cstr| block } -> self[permalink][rdoc][edit]
each_char -> Enumerator

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

たとえば、


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

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

h e l l o 世 界

[SEE_ALSO] String#chars

each_codepoint {|codepoint| block } -> self[permalink][rdoc][edit]
each_codepoint -> Enumerator

文字列の各コードポイントに対して繰り返します。

UTF-8/UTF-16(BE|LE)/UTF-32(BE|LE) 以外のエンコーディングに対しては各文字のバイナリ表現由来の値になります。



#coding:UTF-8
"hello わーるど".each_codepoint.to_a
# => [104, 101, 108, 108, 111, 32, 12431, 12540, 12427, 12393]
"hello わーるど".encode('euc-jp').each_codepoint.to_a
# => [104, 101, 108, 108, 111, 32, 42223, 41404, 42219, 42185]

[SEE_ALSO] String#codepoints

each_grapheme_cluster {|grapheme_cluster| block } -> self[permalink][rdoc][edit]
each_grapheme_cluster -> Enumerator

文字列の書記素クラスタに対して繰り返します。

String#each_char と違って、 Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) で定義された書記素クラスタに対して繰り返します。



"a\u0300".each_char.to_a.size # => 2
"a\u0300".each_grapheme_cluster.to_a.size # => 1

[SEE_ALSO] String#grapheme_clusters

each_line(rs = $/, chomp: false) {|line| ... } -> self[permalink][rdoc][edit]
each_line(rs = $/, chomp: false) -> Enumerator

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

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

[PARAM] rs:
行末を示す文字列
[PARAM] chomp:
true を指定すると各行の末尾から "\n", "\r", または "\r\n" を取り除きます。


"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"]  

[SEE_ALSO] String#lines

empty? -> bool[permalink][rdoc][edit]

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



"hello".empty?   #=> false
" ".empty?       #=> false
"".empty?        #=> true
encode(encoding, options = nil) -> String[permalink][rdoc][edit]
encode(encoding, from_encoding, options = nil) -> String
encode(options = nil) -> String

self を指定したエンコーディングに変換した文字列を作成して返します。引数を2つ与えた場合、第二引数は変換元のエンコーディングを意味します。さもなくば self のエンコーディングが使われます。無引数の場合は、Encoding.default_internal が nil でなければそれが変換先のエンコーディングになり、かつ :invalid => :replace と :undef => :replace が指定されたと見なされ、nil ならば変換は行われません。

[PARAM] encoding:
変換先のエンコーディングを表す文字列か Encoding オブジェクトを指定します。
[PARAM] from_encoding:
変換元のエンコーディングを表す文字列か Encoding オブジェクトを指定します。
[PARAM] option:
変換オプションをハッシュで与えます。
[RETURN]
変換された文字列

変換オプション

:invalid => nil

変換元のエンコーディングにおいて不正なバイトがあった場合に、例外 Encoding::InvalidByteSequenceError を投げます。(デフォルト)

:invalid => :replace

変換元のエンコーディングにおいて不正なバイトがあった場合に、不正なバイトを置換文字で置き換えます。

:undef => nil

変換先のエンコーディングにおいて文字が定義されていない場合に、例外 Encoding::UndefinedConversionError を投げます。(デフォルト)

:undef => :replace

変換先のエンコーディングにおいて文字が定義されていない場合に、未定義文字を置換文字で置き換えます。

:replace => string

前述の :invalid => :replace や :undef => :replace で用いられる置換文字を指定します。デフォルトは Unicode 系のエンコーディングならば U+FFFD、それ以外では "?" です。

:fallback => Hash | Proc | Method

未定義の文字に対する置換文字を設定します。このオプションに与えられるオブジェクトは Hash, Proc, Method のいずれかまたは [] メソッドを持つオブジェクトです。キーは現在のトランスコーダのソースエンコーディングで未定義の文字です。値は、変換先のエンコーディングでの変換後の文字です。

:xml => :text

文字列を XML の CharData として適するように処理します。具体的には、'&'、'<'、'>'、をそれぞれ '&amp;'、'&lt;'、'&gt;' に変換し、未定義文字を文字参照 (大文字16進数) に置き換えます。この出力は HTML の #PCDATA として利用することもできます。

:xml => :attr

文字列を XML の AttValue として適するように処理します。具体的には、'&'、'<'、'>'、'"'、をそれぞれ '&amp;'、'&lt;'、'&gt;'、'&quot;' に変換し、未定義文字を文字参照 (大文字16進数) に置き換えます。この出力は HTML の属性値として利用することもできます。

:universal_newline => true

CR 改行および CRLF 改行を LF 改行に置き換えます。

:cr_newline => true

LF 改行を CR 改行に置き換えます。(CRLF は CRCR になります)

:crlf_newline => true

LF 改行を CRLF 改行に置き換えます。(CRLF は CRCRLF になります)

これ以上細かい指定を行いたい場合は、Encoding::Converter#convert を用いましょう。



#coding:UTF-8
s = "いろは"
s.encode("EUC-JP")
s.encode(Encoding::UTF_8)

# U+00B7 MIDDLE DOT, U+2014 EM DASH は対応する文字が Windows-31J には
# 存在しないのでそのまま変換しようとすると Encoding::UndefinedConversionError が発生する
str = "\u00b7\u2014"
str.encode("Windows-31J", fallback: { "\u00b7" => "\xA5".force_encoding("Windows-31J"),
                                      "\u2014" => "\x81\x5C".force_encoding("Windows-31J") })

[SEE_ALSO] String#encode!

encode!(encoding, options = nil) -> self[permalink][rdoc][edit]
encode!(encoding, from_encoding, options = nil) -> self

self を指定したエンコーディングに変換し、自身を置き換えます。引数を2つ与えた場合、第二引数は変換元のエンコーディングを意味します。さもなくば self のエンコーディングが使われます。変換後の self を返します。

(gsub!などと異なり)変換が行なわれなくても self を返します。

[PARAM] encoding:
変換先のエンコーディングを表す文字列か Encoding オブジェクトを指定します。
[PARAM] from_encoding:
変換元のエンコーディングを表す文字列か Encoding オブジェクトを指定します。
[RETURN]
変換後のself


#coding:UTF-8
s = "いろは"
s.encode!("EUC-JP")
s.encode!(Encoding::UTF_8)

[SEE_ALSO] String#encode

encoding -> Encoding[permalink][rdoc][edit]

文字列のエンコーディング情報を表現した Encoding オブジェクトを返します。



# encoding: utf-8
utf8_str = "test"
euc_str = utf8_str.encode("EUC-JP")
utf8_str.encoding   # => #<Encoding:UTF-8>
euc_str.encoding    # => #<Encoding:EUC-JP>

[SEE_ALSO] Encoding

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

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?

[SEE_ALSO] String#delete_suffix, String#delete_suffix!

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

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

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

アルファベットの大文字小文字を無視して比較したい場合は String#casecmp? を使ってください。

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)

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

force_encoding(encoding) -> self[permalink][rdoc][edit]

文字列の持つエンコーディング情報を指定された encoding に変えます。

このとき実際のエンコーディングは変換されず、検査もされません。 Array#pack などで得られたバイト列のエンコーディングを指定する時に使います。

[PARAM] encoding:
変更するエンコーディング情報を表す文字列か Encoding オブジェクトを指定します。


s = [164, 164, 164, 237, 164, 207].pack("C*")
p s.encoding                                  #=> ASCII-8BIT
p s.force_encoding("EUC-JP")                  #=> "いろは"
p s.force_encoding(Encoding::EUC_JP)          #=> "いろは"

u = [12411, 12408, 12392].pack("U*")
u.force_encoding("UTF-8")                     #=> "ほへと"
u.force_encoding(Encoding::UTF_8)             #=> "ほへと"
getbyte(index) -> Integer | nil[permalink][rdoc][edit]

index バイト目のバイトを整数で返します。

index に負を指定すると末尾から数えた位置のバイトを取り出します。範囲外を指定した場合は nil を返します。

[PARAM] index:
バイトを取り出す位置


s = "tester"
s.bytes             # => [116, 101, 115, 116, 101, 114]
s.getbyte(0)        # => 116
s.getbyte(1)        # => 101
s.getbyte(-1)       # => 114
s.getbyte(6)        # => nil
grapheme_clusters -> [String][permalink][rdoc][edit]
grapheme_clusters {|grapheme_cluster| block } -> self

文字列の書記素クラスタの配列を返します。(self.each_grapheme_cluster.to_a と同じです)



"a\u0300".grapheme_clusters # => ["à"]

ブロックが指定された場合は String#each_grapheme_cluster と同じように動作します。ただし deprecated のため、ブロックを指定する場合は String#each_grapheme_cluster を使用してください。

[SEE_ALSO] String#each_grapheme_cluster

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

文字列中で 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][edit]
gsub(pattern) -> 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, String#scan

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

文字列中の pattern にマッチした部分をキーにして hash を引いた値で置き換えます。

[PARAM] pattern:
置き換える文字列のパターン
[PARAM] hash:
置き換える文字列を与えるハッシュ


hash = {'b'=>'B', 'c'=>'C'}
p "abcabc".gsub(/[bc]/){hash[$&]} #=> "aBCaBC"
p "abcabc".gsub(/[bc]/, hash)     #=> "aBCaBC"
gsub!(pattern, replace) -> self | nil[permalink][rdoc][edit]

文字列中で 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][edit]
gsub!(pattern) -> 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

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

文字列中の pattern にマッチした部分をキーにして hash を引いた値へ破壊的に置き換えます。

[PARAM] pattern:
置き換える文字列のパターン
[PARAM] hash:
置き換える文字列を与えるハッシュ


hash = {'b'=>'B', 'c'=>'C'}
str = "abcabc"
str.gsub!(/[bc]/){hash[$&]}
p str     #=> "aBCaBC"

str = "abcabc"
str.gsub!(/[bc]/, hash)
p str     #=> "aBCaBC"
hash -> Integer[permalink][rdoc][edit]

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



"test".hash                        # => 4038258770210371295
("te" + "st").hash == "test".hash  # => true

[SEE_ALSO] Hash

hex -> Integer[permalink][rdoc][edit]

文字列に 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][edit]

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

[PARAM] substr:
検索する文字列


"hello".include? "lo"   #=> true
"hello".include? "ol"   #=> false
"hello".include? ?h     #=> true
index(pattern, pos = 0) -> Integer | nil[permalink][rdoc][edit]

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

引数 pattern は探索する部分文字列または正規表現で指定します。

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

[PARAM] pattern:
探索する部分文字列または正規表現
[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][edit]

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][edit]

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

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

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



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

[SEE_ALSO] String#dump

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

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

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

シンボル文字列にはヌルキャラクタ("\0")、空の文字列の使用も可能です。



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

文字列の文字数を返します。バイト数を知りたいときは bytesize メソッドを使ってください。



"test".length   # => 4
"test".size     # => 4
"テスト".length   # => 3
"テスト".size     # => 3

[SEE_ALSO] String#bytesize

lines(rs = $/, chomp: false) -> [String][permalink][rdoc][edit]
lines(rs = $/, chomp: false) {|line| ... } -> self

文字列中の各行を文字列の配列で返します。(self.each_line.to_a と同じです)


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

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

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

chomp に true を指定すると、分割した各行に対して String#chomp を実行するのと同等の結果を得ることができます。


"hello\nworld\n".lines              # => ["hello\n", "world\n"]
"hello\nworld\n".lines(chomp: true) # => ["hello", "world"]
[PARAM] rs:
行末を示す文字列
[PARAM] chomp:
分割した各行に対して String#chomp と同等の結果を得る場合は true を、そうでない場合は false で指定します。省略した場合は false を指定したとみなされます。

ブロックが指定された場合は String#each_line と同じように動作します。ただし obsolete のため、ブロックを指定する場合は String#each_line を使用してください。

[SEE_ALSO] String#each_line

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

長さ 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][edit]

文字列の先頭にある空白文字を全て取り除いた新しい文字列を返します。空白文字の定義は " \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][edit]

文字列の先頭にある空白文字を全て破壊的に取り除きます。空白文字の定義は " \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, pos = 0) -> MatchData | nil[permalink][rdoc][edit]
match(regexp, pos = 0) {|m| ... } -> object

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

例: regexp のみの場合

'hello'.match('(.)\1')      # => #<MatchData "ll" 1:"l">
'hello'.match('(.)\1')[0]   # => "ll"
'hello'.match(/(.)\1/)[0]   # => "ll"
'hello'.match('xx')         # => nil
例: regexp, pos を指定した場合

'hoge hige hege bar'.match('h.ge', 0)     # => #<MatchData "hoge">
'hoge hige hege bar'.match('h.ge', 1)     # => #<MatchData "hige">
例: ブロックを指定した場合

'hello'.match('(.)\1'){|e|"match #{$1}"}  # => "match l"
'hello'.match('xx'){|e|"match #{$1}"}     # マッチしないためブロックは実行されない

[SEE_ALSO] Regexp#match, Symbol#match

match?(regexp, pos = 0) -> bool[permalink][rdoc][edit]

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



"Ruby".match?(/R.../)    #=> true
"Ruby".match?(/R.../, 1) #=> false
"Ruby".match?(/P.../)    #=> false
$&                       #=> nil

[SEE_ALSO] Regexp#match?, Symbol#match?

succ -> String[permalink][rdoc][edit]
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][edit]
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][edit]

文字列を 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    # => -16
p "-0b10".oct    # => -2

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 を使用します。

ord -> Integer[permalink][rdoc][edit]

文字列の最初の文字の文字コードを整数で返します。

self が空文字列のときは例外を発生します。

[RETURN]
文字コードを表す整数
[EXCEPTION] ArgumentError:
self の長さが 0 のとき発生


p "a".ord   # => 97

[SEE_ALSO] Integer#chr, String#chr

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

セパレータ 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

prepend(other_str) -> String[permalink][rdoc][edit]

文字列 other_str を先頭に破壊的に追加します。

[PARAM] other_str:
追加したい文字列を指定します。

例:

a = "world"
a.prepend("hello ") # => "hello world"
a                   # => "hello world"
prepend(*arguments) -> String[permalink][rdoc][edit]

複数の文字列を先頭に破壊的に追加します。

[PARAM] arguments:
追加したい文字列を指定します。


a = "!!!"
a.prepend # => "!!!"
a         # => "!!!"

a = "!!!"
a.prepend "hello ", "world" # => "hello world!!!"
a                           # => "hello world!!!"
replace(other) -> String[permalink][rdoc][edit]

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



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

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



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

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



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

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

引数 pattern は探索する部分文字列または正規表現で指定します。

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:
探索する部分文字列または正規表現
[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][edit]

長さ 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][edit]

セパレータ 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][edit]

文字列の末尾にある空白文字を全て取り除いた新しい文字列を返します。空白文字の定義は " \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"

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

[SEE_ALSO] String#lstrip,String#strip

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

文字列の末尾にある空白文字を全て破壊的に取り除きます。空白文字の定義は " \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][edit]

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][edit]

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

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


"foobarbazfoobarbaz".scan(/ba./) {|s| p s }
# "bar"
# "baz"
# "bar"
# "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"]
scrub -> String[permalink][rdoc][edit]
scrub(repl) -> String
scrub {|bytes| ... } -> String

self が不正なバイト列を含む場合に別の文字列に置き換えた新しい文字列を返します。

[PARAM] repl:
不正なバイト列を置き換える文字列を指定します。省略した場合は self の文字エンコーディングが Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE, Encoding::UTF_8 のいずれかの場合は "\uFFFD" を表す文字で、それ以外の場合は "?" で置き換えられます。ブロックが指定された場合は不正なバイト列はブロックの戻り値で置き換えられます。


"abc\u3042\x81".scrub      # => "abc\u3042\uFFFD"
"abc\u3042\x81".scrub("*") # => "abc\u3042*"
"abc\u3042\xE3\x80".scrub{|bytes| '<'+bytes.unpack('H*')[0]+'>' } # => "abc\u3042<e380>"

[SEE_ALSO] String#scrub!

scrub! -> String[permalink][rdoc][edit]
scrub!(repl) -> String
scrub! {|bytes| ... } -> String

self が不正なバイト列を含む場合に別の文字列に置き換えます。常に self を返します。

[PARAM] repl:
不正なバイト列を置き換える文字列を指定します。省略した場合は self の文字エンコーディングが Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE, Encoding::UTF_8 のいずれかの場合は "\uFFFD" を表す文字で、それ以外の場合は "?" で置き換えられます。ブロックが指定された場合は不正なバイト列はブロックの戻り値で置き換えられます。


"abc\u3042\x81".scrub!      # => "abc\u3042\uFFFD"
"abc\u3042\x81".scrub!("*") # => "abc\u3042*"
"abc\u3042\xE3\x80".scrub!{|bytes| '<'+bytes.unpack('H*')[0]+'>' } # => "abc\u3042<e380>"

[SEE_ALSO] String#scrub

setbyte(index, b) -> Integer[permalink][rdoc][edit]

index バイト目のバイトを b に変更します。

index に負を指定すると末尾から数えた位置を変更します。

セットした値を返します。

[PARAM] index:
バイトをセットする位置
[PARAM] b:
セットするバイト(0 から 255 までの整数)
[EXCEPTION] IndexError:
範囲外に値をセットしようとした場合に発生します。


s = "Sunday"
s.setbyte(0, 77)
s.setbyte(-5, 111)
s # => "Monday"
slice!(nth) -> String[permalink][rdoc][edit]
slice!(pos, len) -> String
slice!(substr) -> String
slice!(regexp, nth = 0) -> String
slice!(first..last) -> String
slice!(first...last) -> String

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

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



string = "this is a string"
string.slice!(2)        #=> "i"
string.slice!(3..6)     #=> " is "
string.slice!(/s.*t/)   #=> "sa st"
string.slice!("r")      #=> "r"
string                  #=> "thing"
split(sep = $;, limit = 0) -> [String][permalink][rdoc][edit]
split(sep = $;, limit = 0) {|s| ... } -> self

第 1 引数 sep で指定されたセパレータによって文字列を limit 個まで分割し、結果を文字列の配列で返します。ブロックを指定すると、配列を返す代わりに分割した文字列でブロックを呼び出します。

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

正規表現

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

文字列

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

1 バイトの空白文字 ' '

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

nil

常に $; で分割する。 $; も nil の場合は、先頭と末尾の空白を除いたうえで、空白文字列で分割する。

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

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

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

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

limit > 0

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

limit == 0

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

limit < 0

分割個数の制限はなし

[PARAM] sep:
文字列を分割するときのセパレータのパターン
[PARAM] limit:
分割する最大個数
[RETURN]
ブロックを渡した場合は self、ブロックなしの場合は配列


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"
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][edit]

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!(*chars) -> self | nil[permalink][rdoc][edit]

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?(*prefixes) -> bool[permalink][rdoc][edit]

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

[PARAM] prefixes:
パターンを表す文字列または正規表現 (のリスト)


"string".start_with?("str")          # => true
"string".start_with?("ing")          # => false
"string".start_with?("ing", "str")   # => true
"string".start_with?(/\w/)           # => true
"string".start_with?(/\d/)           # => false

[SEE_ALSO] String#end_with?

[SEE_ALSO] String#delete_prefix, String#delete_prefix!

strip -> String[permalink][rdoc][edit]

文字列先頭と末尾の空白文字を全て取り除いた文字列を生成して返します。空白文字の定義は " \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][edit]

先頭と末尾の空白文字を全て破壊的に取り除きます。空白文字の定義は " \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][edit]

文字列中で 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][edit]

文字列中で 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, hash) -> String[permalink][rdoc][edit]

文字列中の pattern にマッチした部分をキーにして hash を引いた値で置き換えます。

[PARAM] pattern:
置き換える文字列のパターン
[PARAM] hash:
置き換える文字列を与えるハッシュ


hash = {'b'=>'B', 'c'=>'C'}
p "abcabc".sub(/[bc]/){hash[$&]} #=> "aBCabc"
p "abcabc".sub(/[bc]/, hash)     #=> "aBCabc"
sub!(pattern, replace) -> self | nil[permalink][rdoc][edit]

文字列中で 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][edit]

文字列中で 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

sub!(pattern, hash) -> String[permalink][rdoc][edit]

文字列中の pattern にマッチした部分をキーにして hash を引いた値で破壊的に置き換えます。

[PARAM] pattern:
置き換える文字列のパターン
[PARAM] hash:
置き換える文字列を与えるハッシュ
[RETURN]
置換した場合は self、置換しなかった場合は nil
sum(bits = 16) -> Integer[permalink][rdoc][edit]

文字列の 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(*options) -> String[permalink][rdoc][edit]

大文字を小文字に、小文字を大文字に変更した文字列を返します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。


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

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

swapcase!(*options) -> self | nil[permalink][rdoc][edit]

大文字を小文字に、小文字を大文字に破壊的に変更します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。

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

このメソッドはマルチバイト文字を認識しません。



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

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

to_c -> Complex[permalink][rdoc][edit]

自身を複素数 (Complex) に変換した結果を返します。

以下の形式を解析できます。i、j は大文字、小文字のどちらでも解析できます。

  • 実部+虚部i
  • 実部+虚部j
  • 絶対値@偏角

それぞれの数値は以下のいずれかの形式で指定します。先頭の空白文字や複素数値の後にある文字列は無視されます。また、数値オブジェクトと同様に各桁の間に「_」を入れる事ができます。

  • "1/3" のような分数の形式
  • "0.3" のような10進数の形式
  • "0.3E0" のような x.xEn の形式

自身が解析できない値であった場合は 0+0i を返します。



'9'.to_c           # => (9+0i)
'2.5'.to_c         # => (2.5+0i)
'2.5/1'.to_c       # => ((5/2)+0i)
'-3/2'.to_c        # => ((-3/2)+0i)
'-i'.to_c          # => (0-1i)
'45i'.to_c         # => (0+45i)
'3-4i'.to_c        # => (3-4i)
'-4e2-4e-2i'.to_c  # => (-400.0-0.04i)
'-0.0-0.0i'.to_c   # => (-0.0-0.0i)
'1/2+3/4i'.to_c    # => ((1/2)+(3/4)*i)
'10@10'.to_c       # => (-8.390715290764524-5.440211108893697i)
'-0.3_3'.to_c      # => (-0.33+0i)
" \t\r\n5+3i".to_c # => (5+3i)
'5+3ix'.to_c       # => (5+3i)
'ruby'.to_c        # => (0+0i)
to_f -> Float[permalink][rdoc][edit]

文字列を 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][edit]

文字列を 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_r -> Rational[permalink][rdoc][edit]

自身を有理数(Rational)に変換した結果を返します。

Kernel.#Rational に文字列を指定した時のように、以下のいずれかの形式で指定します。

  • "1/3" のような分数の形式
  • "0.3" のような10進数の形式
  • "0.3E0" のような x.xEn の形式
  • 数字をアンダースコアで繋いだ形式


'  2  '.to_r       # => (2/1)
'1/3'.to_r         # => (1/3)
'-9.2'.to_r        # => (-46/5)
'-9.2E2'.to_r      # => (-920/1)
'1_234_567'.to_r   # => (1234567/1)
'1_234/5_678'.to_r # => (617/2839)

Kernel.#Rational に文字列を指定した時とは異なる点もあります。

途中に変換できないような文字列が入っていた場合は、それより先の文字列は無視されます。


'21 june 09'.to_r  # => (21/1)
'21/06/09'.to_r    # => (7/2)   # 21/6 を約分して 7/2。

変換できないような文字列を指定した場合は 0/1 を返します。


'foo'.to_r         # => (0/1)
''.to_r            # => (0/1)
'bwv 1079'.to_r    # => (0/1)

[SEE_ALSO] Kernel.#Rational

to_s -> String[permalink][rdoc][edit]
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][edit]

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

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

replace に対しても `-' による範囲指定が可能です。

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

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"

# シーザー暗号の復号
p "ORYV".tr("A-Z", "D-ZA-C") # => "RUBY"

# 全角英数字といくつかの記号の半角化
email = "ruby−lang@example.com"
p email.tr("0-9a-zA-Z.@−", "0-9a-zA-Z.@-")
# => "ruby-lang@example.com"

[SEE_ALSO] String#tr!, String#tr_s

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

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

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

replace に対しても `-' による範囲指定が可能です。

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

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][edit]

文字列の中に 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!(pattern, replace) -> self | nil[permalink][rdoc][edit]

文字列の中に 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

undump -> String[permalink][rdoc][edit]

self のエスケープを戻したものを返します。

String#dump の逆変換にあたります。



"\"hello \\n ''\"".undump #=> "hello \n ''"

[SEE_ALSO] String#dump

unicode_normalize(form = :nfc) -> String[permalink][rdoc][edit]

self を NFC、NFD、NFKC、NFKD のいずれかの正規化形式で Unicode 正規化した文字列を返します。

[PARAM] form:
正規化形式を :nfc、:nfd、:nfkc、:nfkd のいずれかで指定します。省略した場合は :nfc になります。
[EXCEPTION] Encoding::CompatibilityError:
self が Unicode 文字列ではない場合に発生します。

このメソッドでの "Unicode 文字列" とは、UTF-8、UTF-16BE/LE、 UTF-32BE/LE だけではなく GB18030、UCS_2BE、and UCS_4BE を含みます。

また、self が UTF-8 以外のエンコーディングであった場合は一度 UTF-8 に変換してから正規化されるため、UTF-8 よりも遅くなっています。



"a\u0300".unicode_normalize        # => 'à' ("\u00E0" と同じ)
"a\u0300".unicode_normalize(:nfc)  # => 'à' ("\u00E0" と同じ)
"\u00E0".unicode_normalize(:nfd)   # => 'à' ("a\u0300" と同じ)
"\xE0".force_encoding('ISO-8859-1').unicode_normalize(:nfd)
                                   # => Encoding::CompatibilityError raised

[SEE_ALSO] String#unicode_normalize!, String#unicode_normalized?

unicode_normalize!(form = :nfc) -> self[permalink][rdoc][edit]

self を NFC、NFD、NFKC、NFKD のいずれかの正規化形式で Unicode 正規化した文字列に置き換えます。

(gsub!などと異なり)変換が行なわれなくても self を返します。

[PARAM] form:
正規化形式を :nfc、:nfd、:nfkc、:nfkd のいずれかで指定します。省略した場合は :nfc になります。
[EXCEPTION] Encoding::CompatibilityError:
self が Unicode 文字列ではない場合に発生します。


text = "a\u0300"
text.unicode_normalize!(:nfc)
text == "\u00E0"              # => true
text.unicode_normalize!(:nfd)
text == "a\u0300"             # => true

[SEE_ALSO] String#unicode_normalize, String#unicode_normalized?

unicode_normalized?(form = :nfc) -> bool[permalink][rdoc][edit]

self が引数 form で指定された正規化形式で Unicode 正規化された文字列かどうかを返します。

[PARAM] form:
正規化形式を :nfc、:nfd、:nfkc、:nfkd のいずれかで指定します。省略した場合は :nfc になります。
[EXCEPTION] Encoding::CompatibilityError:
self が Unicode 文字列ではない場合に発生します。


"a\u0300".unicode_normalized?        # => false
"a\u0300".unicode_normalized?(:nfd)  # => true
"\u00E0".unicode_normalized?         # => true
"\u00E0".unicode_normalized?(:nfd)   # => false
"\xE0".force_encoding('ISO-8859-1').unicode_normalized?
                                     # => Encoding::CompatibilityError raised

[SEE_ALSO] String#unicode_normalize, String#unicode_normalize!

unpack(template) -> Array[permalink][rdoc][edit]

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

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

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

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

"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!, j!, J! を用います。また、ネットワークプロトコルやファイルフォーマットのように、システムに依存しないデータを扱うときには 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,i!: signed int
  I,I!: unsigned int
  l!: signed long
  L!: unsigned long
  q!: signed long long
  Q!: unsigned long long
  j,j!: intptr_t
  J,J!: uintptr_t
エンディアン依存、整数サイズ非依存 (C99 の stdint.h にある厳密な幅を持つ整数型に適切)
  s: int16_t
  S: uint16_t
  l: int32_t
  L: uint32_t
  q: int64_t
  Q: uint64_t
エンディアンの強制指定(バイナリ解析などに適切)
  S>:  big endian unsigned 16bit(nと同じ)
  s>:  big endian int16_t
  s!>: big endian signed short
  l<:  little endian int32_t
  l!<: little endian signed long

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

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

a

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


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

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

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


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

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

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


["abc"].pack("Z")  # => "a"
["abc"].pack("Z*") # => "abc\x00"
["abc"].pack("Z5") # => "abc\x00\x00"

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

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


"\xFF\x00".unpack("b*") # => ["1111111100000000"]
"\x01\x02".unpack("b*") # => ["1000000001000000"]
"\x01\x02".unpack("b3") # => ["100"]


["1000000001000000"].pack("b*") # => "\x01\x02"
B

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


"\xFF\x00".unpack("B*")  # => ["1111111100000000"]
"\x01\x02".unpack("B*")  # => ["0000000100000010"]
"\x01\x02".unpack("B9")  # => ["000000010"]
"\x01\x02".unpack("B15") # => ["000000010000001"]

["0000000100000010"].pack("B*")  # => "\x01\x02"
["0000000100000010"].pack("B0")  # => ""
["0000000100000010"].pack("B1")  # => "\x00"
["0000000100000010"].pack("B7")  # => "\x00"
["0000000100000010"].pack("B8")  # => "\x01"
["0000000100000010"].pack("B9")  # => "\x01\x00"
["0000000100000010"].pack("B14") # => "\x01\x00"
["0000000100000010"].pack("B15") # => "\x01\x02"
["0000000100000010"].pack("B16") # => "\x01\x02"
h

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


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

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

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


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

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

char (8bit 符号つき整数)


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

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

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


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

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

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

リトルエンディアン:


"\x01\x02\xFE\xFD".unpack("s*") # => [513, -514]

[513, 65022].pack("s*") # => "\x01\x02\xFE\xFD"
[513, -514].pack("s*")  # => "\x01\x02\xFE\xFD"

ビッグエンディアン:


"\x01\x02\xFE\xFD".unpack("s*") # => [258, -259]

[258, 65277].pack("s*") # => "\x01\x02\xFE\xFD"
[258, -259].pack("s*")  # => "\x01\x02\xFE\xFD"
S

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

リトルエンディアン:


"\x01\x02\xFE\xFD".unpack("S*") # => [513, 65022]

[513, 65022].pack("s*") # => "\x01\x02\xFE\xFD"
[513, -514].pack("s*")  # => "\x01\x02\xFE\xFD"

ビッグエンディアン:


"\x01\x02\xFE\xFD".unpack("S*") # => [258, 65277]

[258, 65277].pack("S*") # => "\x01\x02\xFE\xFD"
[258, -259].pack("S*")  # => "\x01\x02\xFE\xFD"
i

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

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("i*") # => [67305985, -50462977]

[67305985, 4244504319].pack("i*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[67305985, -50462977].pack("i*")  # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("i*") # => [16909060, -66052]

[16909060, 4294901244].pack("i*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[16909060, -66052].pack("i*")     # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
I

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

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("I*") # => [67305985, 4244504319]

[67305985, 4244504319].pack("I*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[67305985, -50462977].pack("I*")  # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("I*") # => [16909060, 4294901244]

[16909060, 4294901244].pack("I*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[16909060, -66052].pack("I*")     # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
l

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

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("l*") # => [67305985, -50462977]

[67305985, 4244504319].pack("l*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[67305985, -50462977].pack("l*")  # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("l*") # => [16909060, -66052]

[16909060, 4294901244].pack("l*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[16909060, -66052].pack("l*")     # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
L

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

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("L*") # => [67305985, 4244504319]

[67305985, 4244504319].pack("L*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[67305985, -50462977].pack("L*")  # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"

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


"\x01\x02\x03\x04\xFF\xFE\xFD\xFC".unpack("L*") # => [16909060, 4294901244]

[16909060, 4294901244].pack("L*") # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
[16909060, -66052].pack("L*")     # => "\x01\x02\x03\x04\xFF\xFE\xFD\xFC"
q

64bit 符号付き整数 (エンディアンに依存) (q! は 64bit でなく、long long のサイズに依存)

リトルエンディアン:


"\x01\x02\x03\x04\x05\x06\x07\x08\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8".unpack("q*")
# => [578437695752307201, -506097522914230529]

[578437695752307201, -506097522914230529].pack("q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"
[578437695752307201, 17940646550795321087].pack("q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"

ビッグエンディアン:


"\x01\x02\x03\x04\x05\x06\x07\x08\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8".unpack("q*")
# => [72623859790382856, -283686952306184]

[72623859790382856, -283686952306184].pack("q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"
[72623859790382856, 18446460386757245432].pack("q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"
Q

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

リトルエンディアン:


"\x01\x02\x03\x04\x05\x06\x07\x08\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8".unpack("Q*")
# => [578437695752307201, 17940646550795321087]

[578437695752307201, 17940646550795321087].pack("Q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"
[578437695752307201, -506097522914230529].pack("Q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"

ビッグエンディアン:


"\x01\x02\x03\x04\x05\x06\x07\x08\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8".unpack("Q*")
# => [72623859790382856, 18446460386757245432]

[72623859790382856, 18446460386757245432].pack("Q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"
[72623859790382856, -283686952306184].pack("Q*")
# => "\x01\x02\x03\x04\x05\x06\a\b\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8"
m

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

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


[""].pack("m")             # => ""
["\0"].pack("m")           # => "AA==\n"
["\0\0"].pack("m")         # => "AAA=\n"
["\0\0\0"].pack("m")       # => "AAAA\n"
["\xFF"].pack("m")         # => "/w==\n"
["\xFF\xFF"].pack("m")     # => "//8=\n"
["\xFF\xFF\xFF"].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") # => ["\x00"]
"AA==".unpack("m")   # => ["\x00"]

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

m0 は [RFC4648] 対応


[""].pack("m0")             # => ""
["\0"].pack("m0")           # => "AA=="
["\0\0"].pack("m0")         # => "AAA="
["\0\0\0"].pack("m0")       # => "AAAA"
["\xFF"].pack("m0")         # => "/w=="
["\xFF\xFF"].pack("m0")     # => "//8="
["\xFF\xFF\xFF"].pack("m0") # => "////"

["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"].pack("m0")
# => "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg=="

"".unpack("m0")       # => [""]
"AA==\n".unpack("m0") # => ArgumentError (invalid base64)
"AA==".unpack("m0")   # => ["\x00"]

"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==".unpack("m0")
# => ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]

[SEE_ALSO] base64

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*")
# => "\x00\x00\x00\x01\xFF\xFF\x7F\xFF\x80\x00\xFF\xFF"

"\x00\x00\x00\x01\xFF\xFF\x7F\xFF\x80\x00\xFF\xFF".unpack("n*")
# => [0, 1, 65535, 32767, 32768, 65535]
N

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


[0,1,-1].pack("N*") # => "\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xFF\xFF"

"\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xFF\xFF".unpack("N*") # => [0, 1, 4294967295]
v

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


[0,1,-1,32767,-32768,65535].pack("v*")
# => "\x00\x00\x01\x00\xFF\xFF\xFF\x7F\x00\x80\xFF\xFF"

"\x00\x00\x01\x00\xFF\xFF\xFF\x7F\x00\x80\xFF\xFF".unpack("v*")
# => [0, 1, 65535, 32767, 32768, 65535]
V

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


[0,1,-1].pack("V*") # => "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xFF\xFF\xFF"


"\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xFF\xFF\xFF".unpack("V*") # => [0, 1, 4294967295]
f

単精度浮動小数点数(機種依存)

x86_64 (IEEE754 単精度 リトルエンディアン):


[1.0].pack("f")      # => "\x00\x00\x80?"
[0.0/0.0].pack("f")  # => "\x00\x00\xC0\x7F"      # NaN
[1.0/0.0].pack("f")  # => "\x00\x00\x80\x7F"      # +Inf
[-1.0/0.0].pack("f") # => "\x00\x00\x80\xFF"      # -Inf

MIPS (IEEE754 単精度 ビッグエンディアン):


[1.0].pack("f")      # => "?\x80\x00\x00"
[0.0/0.0].pack("f")  # => "\x7F\xBF\xFF\xFF"      # NaN
[1.0/0.0].pack("f")  # => "\x7F\x80\x00\x00"      # +Inf
[-1.0/0.0].pack("f") # => "\xFF\x80\x00\x00"      # -Inf

VAX (NetBSD 3.0) (非IEEE754):


[1.0].pack("f") # => "\x80@\x00\x00"
d

倍精度浮動小数点数(機種依存)

x86_64 (IEEE754 倍精度 リトルエンディアン):


[1.0].pack("d")      # => "\x00\x00\x00\x00\x00\x00\xF0?"
[0.0/0.0].pack("d")  # => "\x00\x00\x00\x00\x00\x00\xF8\x7F"      # NaN
[1.0/0.0].pack("d")  # => "\x00\x00\x00\x00\x00\x00\xF0\x7F"      # +Inf
[-1.0/0.0].pack("d") # => "\x00\x00\x00\x00\x00\x00\xF0\xFF"      # -Inf

MIPS (IEEE754 倍精度 ビッグエンディアン):


[1.0].pack("d")      # => "?\xF0\x00\x00\x00\x00\x00\x00"
[0.0/0.0].pack("d")  # => "\x7F\xF7\xFF\xFF\xFF\xFF\xFF\xFF"      # NaN
[1.0/0.0].pack("d")  # => "\x7F\xF0\x00\x00\x00\x00\x00\x00"      # +Inf
[-1.0/0.0].pack("d") # => "\xFF\xF0\x00\x00\x00\x00\x00\x00"      # -Inf

VAX (NetBSD 3.0) (非IEEE754):


[1.0].pack("d") # => "\x80@\x00\x00\x00\x00\x00\x00"
e

リトルエンディアンの単精度浮動小数点数(機種依存)

x86_64 (IEEE754):


[1.0].pack("e") # => "\x00\x00\x80?"

MIPS (IEEE754):


[1.0].pack("e") # => "\x00\x00\x80?"
E

リトルエンディアンの倍精度浮動小数点数(機種依存)

x86_64 (IEEE754):


[1.0].pack("E") # => "\x00\x00\x00\x00\x00\x00\xF0?"

MIPS (IEEE754):


[1.0].pack("E") # => "\x00\x00\x00\x00\x00\x00\xF0?"
g

ビッグエンディアンの単精度浮動小数点数(機種依存)

x86_64 (IEEE754):


[1.0].pack("g") # => "?\x80\x00\x00"

MIPS (IEEE754):


[1.0].pack("g") # => "?\x80\x00\x00"

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

ビッグエンディアンの倍精度浮動小数点数(機種依存)

x86_64 (IEEE754):


[1.0].pack("G") # => "?\xF0\x00\x00\x00\x00\x00\x00"

MIPS (IEEE754):


[1.0].pack("G") # => "?\xF0\x00\x00\x00\x00\x00\x00"

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")             # => "\x980\xBEf\x1CV\x00\x00"
["a", "b", "c"].pack("p3") # => "\x98\xE5\x9ER\xD2U\x00\x00p\xE5\x9ER\xD2U\x00\x00H\xE5\x9ER\xD2U\x00\x00"
[nil].pack("p")            # => "\x00\x00\x00\x00\x00\x00\x00\x00"
P

構造体(固定長文字列)へのポインタ


[nil].pack("P")    # => "\x00\x00\x00\x00\x00\x00\x00\x00"
["abc"].pack("P3") # => "\xA0\xEE\er\x84U\x00\x00"

["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")                               # => "\u0000"
[1].pack("U")                               # => "\u0001"
[0x7f].pack("U")                            # => "\u007F"
[0x80].pack("U")                            # => "\u0080"
[0x7fffffff].pack("U")                      # => "\xFD\xBF\xBF\xBF\xBF\xBF"
[0x80000000].pack("U")                      # => RangeError: pack(U): value out of range
[0,256,65536].pack("U3").b                  # => "\x00\xC4\x80\xF0\x90\x80\x80"

"\x00\xC4\x80\xF0\x90\x80\x80".unpack("U3") # => [0, 256, 65536]
"\x00\xC4\x80\xF0\x90\x80\x80".unpack("U")  # => [0]
"\x00\xC4\x80\xF0\x90\x80\x80".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")             # => "\x00"
[1].pack("w")             # => "\x01"
[127].pack("w")           # => "\x7F"
[128].pack("w")           # => "\x81\x00"
[0x3fff].pack("w")        # => "\xFF\x7F"
[0x4000].pack("w")        # => "\x81\x80\x00"
[0x3fffffff].pack("w")    # => "\x83\xFF\xFF\xFF\x7F"
[0x40000000].pack("w")    # => "\x84\x80\x80\x80\x00"
[0xffffffff].pack("w")    # => "\x8F\xFF\xFF\xFF\x7F"
[0x100000000].pack("w")   # => "\x90\x80\x80\x80\x00"

"\x00".unpack("w")              # => [0]
"\x00\x81\x00\x01".unpack("w*") # => [0, 128, 1]

なお、BER圧縮整数でエンコードした結果は大小関係を保存しない。たとえば、[0x3fff].pack("w") > [0x4000].pack("w") である。

x

ヌルバイト(pack)/1バイト読み飛ばし(unpack)


[97, 98].pack("CxC")    # => "a\x00b"
[97, 98].pack("Cx3C")   # => "a\x00\x00\x00b"

"abc".unpack("CxC")  # => [97, 99]
"abc".unpack("Cx3C") # => ArgumentError: x outside of string
X

1バイト後退


[97, 98, 99].pack("CCXC") # => "ac"

"abcdef".unpack("x*XC") # => [102]
@

絶対位置への移動


[97, 98].pack("C @3 C") # => "a\x00\x00b"

"abcd".unpack("C @3 C") # => [97, 100]
j

intptr_t (ポインタの幅の符号つき整数, エンディアンに依存)

J

uintptr_t (ポインタの幅の符号なし整数, エンディアンに依存)

使用例

以下、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\x00\x00by"
"x" で文字を読み飛ばす事が出来る

"Ru\x00\x00by".unpack('ccxxcc')    # => [82, 117, 98, 121]
Hexダンプを数値の配列に変換する例

"61 62 63 64 65 66".delete(' ').lines.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\x00\x00\x00\x00"
リトルエンディアンとビッグエンディアン

[1,2].pack("s2")
# => "\x01\x00\002\x00" # リトルエンディアンのシステムでの出力
# => "\x00\x01\x00\002" # ビッグエンディアンのシステムでの出力

[1,2].pack("n2")
# => "\x00\x01\x00\002" # システムによらずビッグエンディアン

[1,2].pack("v2")
# => "\x01\x00\002\x00" # システムによらずリトルエンディアン
ネットワークバイトオーダの 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'
official_hostname, alias_hostnames, address_family, *address_list = Socket.gethostbyname("localhost")
address_list.find {|address| address.size == 4 }.unpack("C4").join(".")
# => "127.0.0.1"

"127.0.0.1".split(".").collect {|c| c.to_i}.pack("C4")
# => "\x7F\x00\x00\x01"
sockaddr_in 構造体

require 'socket'
[Socket::AF_INET,
 Socket.getservbyname('echo'),
 127, 0, 0, 1].pack("s n C4 x8")
# => "\x02\x00\x00\a\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"

pack/unpack を使う代わりに Socket.pack_sockaddr_in, Socket.unpack_sockaddr_in メソッドがあります。

'\0'終端文字列のアドレス

テンプレート文字 "p" や "P" は、C 言語レベルのインタフェースのためにあります(例えば IO#ioctl)。


["foo"].pack("p")    # => "xp\xC2\x85\vV\x00\x00"

結果の文字列はゴミに見えますが、実際は文字列"foo\0"を指すアドレス(のバイナリ表現)です。以下のようにすれば見慣れた表記で見ることが出来ます


printf "%#014x\n", "xp\xC2\x85\vV\x00\x00".unpack("J")[0] # => 0x560b85c27078

アドレスが指す先のオブジェクト(この例で "foo\0") は、pack の結果が GC されるまではGCされないことが保証されています。

unpack("p"), unpack("P") は、pack の結果からしか unpack できません。


["foo"].pack("p").unpack("p") # => ["foo"]
"xp\xC2\x85\vV\x00\x00".unpack("p")
# => ArgumentError: no associated pointer

"p" や "P" は、nil を特別に扱い NULL ポインタとして解釈します。(以下は、64bitマシンで一般的な結果)


[nil].pack("p")        # => "\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00".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")  # => "\xC0\xCC2L\fV\x00\x00"

で得られます。

UTF-8からUCS-2への変換 (サロゲートを処理していないので UTF-16 とはいえない)

リトルエンディアン:


("Comments").unpack("U*").pack("v*") # => "C\x00o\x00m\x00m\x00e\x00n\x00t\x00s\x00"

ビッグエンディアン:


("Comments").unpack("U*").pack("n*") # => "\x00C\x00o\x00m\x00m\x00e\x00n\x00t\x00s"

[SEE_ALSO] String#unpack1, Array#pack

unpack1(format) -> object[permalink][rdoc][edit]

formatにしたがって文字列をデコードし、展開された1つ目の値を返します。 unpackは配列を返しますがunpack1は配列の1つ目の要素のみを返します。



"ABC".unpack1("C*") # => 65
"ABC".unpack("C*")  # => [65, 66, 67]

[SEE_ALSO] String#unpack, Array#pack

upcase(*options) -> String[permalink][rdoc][edit]

全ての小文字を対応する大文字に置き換えた文字列を返します。どの文字がどう置き換えられるかは、オプションの有無や文字列のエンコーディングに依存します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。


p "stRIng? STring.".upcase   # => "STRING? STRING."

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

upcase!(*options) -> self | nil[permalink][rdoc][edit]

全ての小文字を対応する大文字に破壊的に置き換えます。どの文字がどう置き換えられるかは、オプションの有無や文字列のエンコーディングに依存します。

[PARAM] options:
オプションの詳細は String#downcase を参照してください。


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][edit]

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 を含む。
valid_encoding? -> bool[permalink][rdoc][edit]

文字列の内容が、現在のエンコーディングに照らしあわせて妥当であれば true を返します。さもなくば false を返します。



"\xc2\xa1".force_encoding("UTF-8").valid_encoding?  #=> true
"\xc2".force_encoding("UTF-8").valid_encoding?      #=> false
"\x80".force_encoding("UTF-8").valid_encoding?      #=> false