Upgrade to Pro — share decks privately, control downloads, hide ads and more …

String#split何もわかっていなかった/didn-t-know-anything-about-string-split

 String#split何もわかっていなかった/didn-t-know-anything-about-string-split

5ddade6742b9a6ebd269ad0d7255158a?s=128

Masatoshi Moritsuka

May 19, 2022
Tweet

More Decks by Masatoshi Moritsuka

Other Decks in Programming

Transcript

  1. String#split 何もわかって いなかった 森塚 真年(@sanfrecce_osaka) 2022/05/18 K-Ruby#30 #k_ruby

  2. \ ( 祝 )30 回/

  3. 自己紹介 森塚 真年 GitHub: @sanfrecce-osaka Twitter: @sanfrecce_osaka Qiita: @sanfrecce_osaka 株式会社エンペイ

    Ruby3.1/Rails6.1 We are hiring!! from 神奈川
  4. String#split

  5. よく知っている

  6. とある日 スペースで分割したかった # よく使っているパターン ' ほげ ふが '.split(/[[:space:]]/) # =>

    ["", "ほげ", "", "", "", "", "", "", "", "", "ふが"] # 挙動を確認するためirbで実行 ' ほげ ふが '.split(' ') ' ほげ ふが '.split(/ /)
  7. なん・・・だと・・・? ' ほげ ふが '.split(' ') # => ["ほげ", "ふが"]

    ' ほげ ふが '.split(/ /) # => ["", "ほげ", "", "", "", "", "", "", "", "", "ふが"]
  8. String#split の型シグネチャ def split: (?Regexp | string pattern, ?int limit)

    -> Array[String] | (?Regexp | string pattern, ?int limit){ (String) -> void } -> self https://github.com/ruby/rbs/blob/v2.4.0/core/string.rbs#L2660
  9. pattern( 正規表現 ) 通常 正規表現にマッチする部分で分割 括弧によるグルーピングがある場合 グループにマッチした文字列も結果に含む 空文字列にマッチする場合 文字列を1 文字ずつに分割

    マルチバイト文字も認識 ' ほげ ふが '.split(/ /) # => ["", "ほげ", "", "", "", "", "", "", "", "", "ふが"] '1-10,20'.split(/([-,])/) # => ["1", "-", "10", ",", "20"] ' a cat '.split(/\s*/) # => ["", "a", "c", "a", "t"]
  10. pattern( 文字列 ) 通常 その文字列自体にマッチする部分で分割 1 バイトの空白文字 先頭と末尾の空白を除く そのうえで空白文字列で分割 空文字列

    文字列を1 文字ずつに分割 マルチバイト文字も認識 ',,a,b,c'.split(',') # => ["", "a", "b", "c"] ' a \t b \n c'.split(' ') # => ["a", "b", "c"] ' a cat '.split('') # => ["", "a", "c", "a", "t"]
  11. pattern(nil) default( 厳密には$;) 常に$; で分割 $; もnil の場合 先頭と末尾の空白を除く そのうえで空白文字列で分割

    " a \t b \n c ".split(nil) # => ["a", "b", "c"] " a \t b \n c ".split # => ["a", "b", "c"] # split(nil) と同じ
  12. limit limit > 0 最大 limit 個の文字列に分割する limit == 0(default)

    分割個数制限はなしで、配列末尾の空文字列 を取り除く limit < 0 分割個数の制限はなし 他言語のsplit も同様のインターフェース 動きは異なる "a,b,c,d,e".split(/,/, 3) # => ["a", "b", "c,d,e"] ",a,b,c,,,".split(/,/, 0) # => ["", "a", "b", "c"] ",a,b,c,,,".split(/,/, -1) # => ["", "a", "b", "c", ""]
  13. block(2.6.0 〜 ) 配列を返す代わりに分割した文字列でブロック を呼び出す 参考記事内のベンチマークだとブロックなしの およそ倍の速度 fruits = []

    input_str = "apple, mango, potato, banana, cabbage" input_str.split(", ") do |value| fruits << value if is_fruit?(value) end # => "apple, mango, potato, banana, cabbage" fruits # => ["apple", "mango", "banana"] https://techracho.bpsinc.jp/hachi8833/2018_07_31/59885
  14. おまけ (C のコード ) https://github.com/ruby/ruby/blob/v3_1_2/string.c#L8674

  15. 最後に String#split は意外に多彩な動きをする Ruby は奥が深い 便利な処理の裏で色々頑張っている

  16. ご清聴 ありがとうございました