More Related Content
Similar to Ruby の String のメソッドについて (7)
More from Tomoya Kawanishi (17)
Ruby の String のメソッドについて
- 2. 大手町.rb #6 発表資料 「Rubyの文字列について」
1自己紹介
Tomoya Kawanishi a.k.a. @cuzic
エネチェンジ株式会社 チーフエンジニア
電力会社、ガス会社を切り替えるなら、エネチェンジ経由で!
一般家庭も!法人も!Ruby関西の中の人
Ruby関西の中の人
発表者として登壇くださる方、あとで声かけください。
大阪RubyKaigi01 を 7月21日に開催予定
大手町.rb の中の人
毎月 大手町.rb を第2火曜日に開催
東京駅、各線大手町駅から直結!
Ruby の初級者がメインターゲット
- 3. 大手町.rb #6 発表資料 「Rubyの文字列について」
今日のテーマ
文字列
便利メソッドの紹介
マルチバイト文字の扱いについて
手元のパソコンで試しながら聞いてください。
2
- 4. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#% 、 String#*
String#% : sprintf のようなフォーマット出力
String#* : 文字列の繰り返し
3
# String#%
irb> "%05d" % 123
"00123"
irb> "=" * 20
=> "--------------------"
- 5. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#+@ 、 String#-@
String#+@ : mutable な文字列を返す
String#-@ : immutable (frozen)な文字列を返す
4
irb> a = "abc"
irb> a.object_id
47022212942940
irb> b = +a
"abc"
irb> b.object_id
47022212942940
irb> c = -a
"abc"
irb> c.object_id
47022212874160
irb> "hoge" << "huga"
"hogehuga"
irb> (-"hoge") << "huga"
RuntimeError: can't modify frozen String
- 6. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#[] 1/2
String#[index] : index位置の文字
String#[start, length] : start から length 文字分
5
a = "hello there"
a[1] #=> "e"
a[2, 3] #=> "llo"
a[2..3] #=> "ll"
a[-3, 2] #=> "er"
a[7..-2] #=> "her"
a[-4..-2] #=> "her"
a[-2..-4] #=> ""
"a¥u0300" #=> "à"
"a¥u0300"[0] #=> "a"
- 7. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#[] 2/2
String#[regexp] :正規表現マッチの全体
String#[regexp, n] :n番目のマッチ
String#[regexp, capture] : capture 文字列に対応す
るマッチ
String#[substr] : サブ文字列があれば、それを返す
6
a = "hello there"
a[/[aeiou](.)¥1/] #=> "ell"
a[/[aeiou](.)¥1/, 0] #=> "ell"
a[/[aeiou](.)¥1/, 1] #=> "l"
a[/[aeiou](.)¥1/, 2] #=> nil
a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "non_vowel"] #=> "l"
a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "vowel"] #=> "e"
a["lo"] #=> "lo"
a["bye"] #=> nil
- 8. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#concat
String#concat:文字列の連結
複数の引数を指定して、一度に連結できる
7
a = "hello "
a.concat("world", 33) #=> "hello world!"
a #=> "hello world!"
b = "sn"
b.concat("_", b, "_", b) #=> "sn_sn_sn"
- 9. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#delete
String#delete:文字の削除
String#delete_prefix : 先頭の削除
String#delete_suffix : 末尾の削除
8
"hello".delete "l","lo" #=> "heo"
"hello".delete "lo" #=> "he"
"hello".delete "aeiou", "^e" #=> "hell"
"hello".delete "ej-m" #=> "ho"
"hello".delete_prefix("hel") #=> "lo"
"hello".delete_prefix("llo") #=> "hello"
"hello".delete_suffix("llo") #=> "he"
"hello".delete_suffix("hel") #=> "hello"
- 10. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#end_with?
String#end_with? : 末尾が引数と一致しているか?
複数指定した場合は、どれか1つでも一致しているか?
9
"hello".end_with?("ello") #=> true
# returns true if one of the +suffixes+ matches.
"hello".end_with?("heaven", "ello") #=> true
"hello".end_with?("heaven", "paradise") #=> false
- 11. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#gsub
文字列の置換
ブロック引数で、任意の置換ロジックを指定できる
ハッシュを渡すと、マッチした部分をキーとして、
ハッシュを引いた値で置き換えられる
10
"hello".gsub(/[aeiou]/, '*') #=> "h*ll*"
"hello".gsub(/([aeiou])/, '<¥1>') #=> "h<e>ll<o>"
"hello".gsub(/./) {|s| s.ord.to_s + ' '} #=> "104 101 108 108
111 "
"hello".gsub(/(?<foo>[aeiou])/, '{¥k<foo>}') #=> "h{e}ll{o}"
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "h3ll*"
- 12. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#match
正規表現のマッチ結果を返す
11
'hello'.match('(.)¥1') #=> #<MatchData "ll" 1:"l">
'hello'.match('(.)¥1')[0] #=> "ll"
'hello'.match(/(.)¥1/)[0] #=> "ll"
'hello'.match(/(.)¥1/, 3) #=> nil
'hello'.match('xx') #=> nil
'hello'.match('(.)¥1') do |str|
p str
end
- 13. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#match?
String#match? : 文字列のマッチ。true, false を返す
$& などを更新しない分高速。
12
"Ruby".match?(/R.../) #=> true
"Ruby".match?(/R.../, 1) #=> false
"Ruby".match?(/P.../) #=> false
$& #=> nil
- 14. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#partition 、 String#rpartition
String#partition :引数 sep で分割して、
sep 以前の文字列、sep 、sep 以降の文字列の3要素の
文字列の配列を返す。見つからない場合、[self, "", ""]
という3要素の配列を返す。
sep は文字列でも正規表現でもいい
末尾から探索する場合、rpartition を使う
13
"hello".partition("l") #=> ["he", "l", "lo"]
"hello".partition("x") #=> ["hello", "", ""]
"hello".partition(/.l/) #=> ["h", "el", "lo"]
"hello".rpartition("l") #=> ["hel", "l", "o"]
"hello".rpartition("x") #=> ["", "", "hello"]
"hello".rpartition(/.l/) #=> ["he", "ll", "o"]
- 15. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#prepend
String#prepend : 先頭に文字列を追加
concat の逆向き。破壊的メソッド
14
a = "!"
a.prepend("hello ", "world") #=> "hello world!"
a #=> "hello world!"
- 16. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#scan
String#scan :引数にマッチする部分を文字列から取り出す。
正規表現のパターンに () があれば、配列の配列を返す
ブロックを与えると、引数のパターンと一致する部分を繰り返しブロックを実
行する
15
a = "cruel world"
a.scan(/¥w+/) #=> ["cruel", "world"]
a.scan(/.../) #=> ["cru", "el ", "wor"]
a.scan(/(...)/) #=> [["cru"], ["el "], ["wor"]]
a.scan(/(..)(..)/) #=> [["cr", "ue"], ["l ", "wo"]]
s = "of the people, by the people, for the people"
hash = Hash.new(0)
s.scan(/¥w+/) {|word| hash[word] += 1 }
p hash #=> {"of"=>1, "the"=>3, "people"=>3, "by"=>1, "for"=>1}
- 17. 大手町.rb #6 発表資料 「Rubyの文字列について」
日本語文字コードの歴史
狭義の Shift_JIS: JIS X 0208符号化文字集合・・・
CP932:マイクロソフトが制定。各ベンダが拡張可能
混乱の時代
NEC 特殊文字、NEC選定IBM拡張文字、IBM拡張文字
マイクロソフトが統一。独自拡張の禁止
Ruby では
Shift_JIS は狭義のシフトJIS
SJIS、CP932、Windows-31J は MS 統一後のシフトJIS
16
- 18. 大手町.rb #6 発表資料 「Rubyの文字列について」
Ruby の文字列の扱い
Ruby 1.8 時代
ただのバイト列だった
エンコーディング情報を持たずどう扱うかはプログラム次第
正規表現にはエンコーディングがあった
Ruby 1.9 以降
文字列のエンコーディングは文字列自体が知っている
バイト列として扱いたいときは、ASCII-8Bit などを指定する
bytes とか each_byte のようなメソッドもある
codepoints とか each_codepoint とかのようなコードポイン
トを順に返すメソッドもある
文字を順に扱いたいときは chars とか each_char を使う
17
- 19. 大手町.rb #6 発表資料 「Rubyの文字列について」
String#encode
encodeには fallback や undef 等のオプションを指定可能
invalid: 変換前の文字コードが不正なときの処理方法を指定
undef: 変換後、対応文字がないときの処理方法を指定
replace: invalid や undef を指定したときの代替文字を指定
crlf_newline: 改行文字"¥n" を "¥r¥n" に置き換える
18
# U+00B7 MIDDLE DOT, U+2014 EM DASH は対応する文字が Windows-31J には
# 存在しないのでそのまま変換しようとすると
Encoding::UndefinedConversionError が発生する
pry> str = "¥u00b7¥u2014"
=> "·—"
pry> str.encode("Windows-31J", fallback: { "¥u00b7" =>
"¥xA5".force_encoding("Windows-31J"), "¥u2014" =>
"¥x81¥x5C".force_encoding("Windows-31J") })
=> "¥xA5¥x{815C}"
pry> str.encode("Windows-31J", undef: :replace)
=> "??"
- 20. 大手町.rb #6 発表資料 「Rubyの文字列について」
まとめ
今日は String クラスの主なメソッドについて紹介しま
した。
すべて知っていた方はかなりの上級者だと思います。
String クラスもバージョンアップにともない、
機能追加、メソッド追加がいろいろあったりします。
私自身も改めて調べてみて、とても勉強になりました
19