Ruby
正規表現
文字列
チートシート
ハッシュ
More than 1 year has passed since last update.

概要

 読んで字の如し(※時々書き換えます)

基本

  • 三項演算子は判定式?真の場合:偽の場合
  • <=>演算子は「左が大きければ 1, 等しければ0, 右が大きければ -1」という意味
  • sprintfはC言語と大体一緒。#で接頭辞、+で符号(' 'で符号分の空白)、-で左寄せ、.で精度
  • 外部ファイル実行はsystem(何か)とすれば幾らでも可能。標準出力を垂れ流す場合はリダイレクトで握り潰せる
  • Marshal.dump(hoge)でオブジェクトhogeをStringにできる。逆にMarshal.load(str)とすると元に戻せるのでディープコピーに使える
  • 多次元配列の初期化でArray.new(3,Array.new(3))などとするのはNG。Array.new(3){Array.new(3)}と書こう
  • 複数行改行は=beginで初めて=endまで。C++等より不便なのはご愛嬌
  • 複数の戻り値を関数から返す場合、Rubyの場合は多重代入で書ける。つまり、return a,ba,b=func()で受け取れる。
  • 無限ループを書く場合、イテレータ不要ならloop{ブロック}while true ~ end、必要なら1.upto(0/0.0){|i|ブロック}とする
  • 複数行の標準入力を受け取る場合、STDINをファイル扱いできるのでSTDIN.eachSTDIN.read.split("\n")できる
  • 破壊的メソッドを自作する場合は、自作クラスの場合フツーにメンバ変数(@xなど)を書き換えれば良し、モンキーパッチの場合はself.replace(新しい中身)とすれば良し
  • Object#cloneおよびObject#dupメソッドはオブジェクトを「浅く」コピーする
  • 乱数の基本:random = Random.newしてからrandom.randrandom.rand(1..6)など

正規表現

  • 正規表現内に文字列変数を埋め込む場合は/#{str}/などとする
  • \wは[a-zA-Z0-9_]、\sは空白文字[\t\r\n\f\v]、\dは10進数字[0-9]、\hは16進数字[0-9a-fA-F]に対応する
  • {n}はちょうどn回、{n,}はn回以上、{,n}はn回以下、{n,m}はn~m回
  • *・+・?・{}は末尾に?を追加すると最短マッチングする
  • 正規表現における「.」は通常改行の\nにマッチしない。/hoge./mのように、/~//~/mとすればマッチするようになる
pattern 名称 意味
(?=pat) 肯定先読み ある位置から続く文字列とマッチする
(?!pat) 否定先読み ある位置から続く文字列とマッチしない
(?<=pat) 肯定後読み ある位置の直前までの文字列とマッチする
(?<!pat) 否定後読み ある位置の直前までの文字列とマッチしない

String

検索系

  • empty?:空文字列ならtrue
  • include?(str):strが含まれていたらtrue
  • index(pattern[,int]):patternが含まれる位置を返す(無ければnil)。intは最初の検索位置で、負数だと末尾からの位置
  • [int]:その位置の文字を返す。負数だと末尾から数える
  • [pos,len]:posからlen文字
  • [pattern]:マッチした最初の部分
  • str=~regexp:マッチしたらその位置を整数で返す
  • match(pattern):hogeとマッチした部分を返す。()を使うと該当箇所が配列で取得できる
  • scan(pattern):hogeとマッチしたすべての部分を配列で返す
  • StringにStringを末尾に足す場合、+=より<<を使う方が速い。つまり「str+=a」より「str<<a」の方が良い

変換系

  • [pattern]=str:patternとマッチした部分文字列をstrで置き換える
  • gsub(pattern,str):patternとマッチした全ての部分をstrで置き換える
  • gsub(pattern,hash):hashは{マッチした文字列=>置換文字列}と指定
  • gsub(pattern){|match| block}:マッチ箇所に対してブロックを実行
  • sub:hogeとマッチした最初の部分をfugaで置き換える
  • split(pattern):分割して配列を返す(未指定なら空白、""なら1文字づつ区切る)
  • strip:先頭と末尾の空白文字(半角空白と制御文字)を除去
  • each_line{|line| block}:改行で分割してブロック処理
  • each_line(str){|line| block}:strを改行文字とする
  • chomp:末尾の改行を取り除く
  • upcase,downcase:小文字を大文字にする,大文字を小文字にする
  • swapcase:小文字を大文字に、大文字を小文字にする
  • capitalize:英字を先頭大文字・後小文字に変換する
  • 全角英数字を半角英数字に(その1):str.tr('0-9a-zA-Z', '0-9a-zA-Z')
  • 全角英数字を半角英数字に(その2):NKF.nkf('-m0Z1 -Ww', "ガルパン") ※文字コード依存。入力がSJISなら-S、出力がEUCなら-eとなる
  • とりあえず一通り正規化させたい(unf):UNF::Normalizer.normalize(text, :nfkc)
  • とりあえず一通り正規化させたい(unicode):Unicode::nfkc('㈱㌧㌦Ⅲ')
  • 濁点半濁点を弾きたい:まずrequire 'unf'してからstr.to_nfd「ガルパン」を「カ゛ルハ゜ン」に変換。その後は濁点と半濁点をgsub等で排除すればいい。ただし、この際の濁点と半濁点はUnicodeの奴なので\u3099\u309Aとして扱うこと。

その他

  • 文字列内に文字列でない変数を埋め込む場合は"#{val}"などとする

Array

  • index(obj):objがある位置を返す(存在しない場合はnil)
  • [index, length]:index番目の要素からlength個だけ抜き出す
  • slice!(index):index番目の要素を削除する
  • slice!(index, length):index番目の要素からlength個だけ削除する
  • all?{|item| block}:ブロックの戻り値が全て真ならtrue
  • uniq:重複を削除した配列を返す
  • count(obj):objと同じ要素の数(ブロックを渡すと、ブロックが真になった要素数)
  • shuffle:要素をシャッフルする
  • sample:要素をランダムに返す
  • array.product(other_array, ...):要素積を作成する
  • unshift,push:配列の先頭および末尾に要素を追加する
  • shift,pop:配列の先頭および末尾の要素を削除する
  • rotate(int):intだけ要素を循環シフトする(正の数で左向き)
  • transpose:配列の行と列を入れ替える
  • permutation([n]){|arr| block}:順列を生成してarrに順次代入する
  • combination([n]){|arr| block}:組み合わせを生成してarrに順次代入する
  • repeated_combination([n]){|arr| block}:重複組合せを生成してarrに順次代入する
  • 逆順にソートしたい:array.sort{|a, b|b <=> a}のようにする
  • 2次元配列:Array.new(3){Array.new(4)}と、ブロックを作成して初期化すること

Hash

  • has_key?(key):keyと同じキーがあればtrue
  • hash.has_value?(val):valと同じ値があればtrue
  • merge(other_hash):他のハッシュと結合する
  • delete(key):指定したキーに一致する{キー => 内容}を削除する(戻り値はキーの値だがキーが存在しない場合はnil)
  • Hash.new(obj):ハッシュのデフォルト値をobjとする
  • default(obj):ハッシュのデフォルト値を返す(=演算子で変更可能)
  • keys,values:キーや値の一覧を配列で返す
  • assoc(key):あるキーを持つキー・値のペアを配列として取り出す(配列版もある)
  • rassoc(val):ある値を持つキー・値のペアを配列として取り出す(配列版もある)
  • 配列をハッシュにその1:配列ary=[[key1,val1],[key2,val2],...]を用意して「hash=Hash[*ary.flatten]」
  • 配列をハッシュにその2:配列keyとvalを用意して「ary=[key,val].transpose;hash=Hash[*ary.flatten]」
  • ハッシュを配列に:個別ならkeysかvaluesメソッド、両方ならto_aメソッドでいい
  • キーでソート:hash.sort_by{|key,val| key}とする(これをすると配列に変換されるので注意)
  • 値でソート:hash.sort_by{|key,val| val}とする(これをすると配列に変換されるので注意)

Enumerable

選択系

  • select:trueになる要素だけ[1,2,3,4,5,6].select{|n| n%2==0} => [2,4,6]
  • reject:falseになる要素だけ[1,2,3,4,5,6].reject{|n| n%2==0} => [1,3,5]
  • find:trueになる最初の要素[1,5,8,2,6,3].find{|n| n%3==0} => 6
  • find_index:trueになる最初の要素のインデックス[1,5,8,2,6,3].find_index{|n| n%3==0} => 4
  • grep:マッチする要素だけ['a1','bb','c2','dd','5e'].grep(/[0-9]/) => ["a1","c2","5e"]
  • take_while:falseになる手前の要素まで[1,2,3,4,5,6].take_while{|i| i<3} => [1,2]
  • drop_while:falseになった以降の要素すべて[1,2,3,4,5,6].drop_while{|i| i<3} => [3,4,5,6]
  • min,max,minmax:最小値,最大値,最小値と最大値の配列[1,"3",5].max{|a, b|a.to_i<=>b.to_i} => 5
  • join:配列全体をto_sして結合する[1,2,3,4,5,6].join =>'123456'

全体系

  • collect/map:式を実行した結果[1,2,3].map{|n| n*3} => [3,6,9]
  • 全要素を整数に変換:map(&:to_i)
  • inject/reduce:最後までのブロックの実行結果[1,2,3,4,5].inject(10){|result,item| result+item} => 25`
  • group_by:結果をキー、対応する要素の配列を値とするハッシュ[1,2,3,4,5,6].group_by{|i| i%2} => {1=>[1,3,5],0=>[2,4,6]}`
  • sort_by:<=> 演算子で比較し、昇順にソート[1,5,7,2,4,9].sort_by{|v| -v} => [9,7,5,4,2,1]`

RoR拡張

  • include?:含まれている場合true[1,2,3].include?(5) => false
  • exclude?:含まれていない場合true[1,2,3].exclude?(5) => true
  • any?:条件を満たす要素が1つ以上ある場合にtrue[1,2,3,4,5].any?{|n| n<2} => true
  • many?:条件を満たす要素が2つ以上ある場合にtrue[1,2,3,4,5].many?{|n| n<2} => false
  • sum:各要素内の合計[1,2,3].sum => 6

ファイル関係

  • File.exist?(path):ファイルやフォルダの存在を確認する
  • File.read(path):ファイルを読み込んで格納する
  • File.delete(path)::ファイルを削除する
  • ファイル書き込みその1:io=File.open(path,"w")してからio.putsして``io.close``する
  • ファイル書き込みその2:IO.write(path,x)とすれば式xをそのまま書き出せる
  • ファイル書き込みその3:open(path, "w"){|f|f.putsなど}とすれば自動でcloseしてくれる
  • Shift_JISで入力:'r:SHIFT_JIS'と指定する。UTF-8にしたい際はr:SHIFT_JIS:UTF-8とする
  • Shift_JISで出力:'w:SHIFT_JIS'と指定する
  • 複雑な文字変換:NKF.nkf(option, str)
  • 文字コード変換:String#encodeを使う。str.encode("EUC-JP")など
  • 文字コード変換でエラー回避:str.encode("Shift_JIS", :invalid => :replace, :undef => :replace)
  • 文字コード周りでArgumentError:Encoding.default_external = "UTF-8"
  • ファイル名を取り出す:File.basename("/home/user/bin/ruby/file.rb")
  • ディレクトリ名を取り出す:File.dirname("/home/user/bin/ruby/file.rb")
  • 拡張子を取り出す:File.extname("/home/user/bin/ruby/file.rb")
  • dirnameとbasenameした結果の配列を返す:File.split("/home/user/bin/ruby/file.rb")
  • dirnameとbasenameを結合する:File.join("/hoge", "hoge.txt")
  • 相対パスを絶対パスに変更:File.expand_path("../../../bin")

Nokogiri

  • データ分析:doc = Nokogiri::HTML.parse(html, nil, charset)
  • タイトル:doc.title
  • 要素取得(css):doc.css('dic[class="hoge"]')
  • 要素取得(xPath):doc.xpath('//div[@class="hoge"]')
  • 属性値の部分:doc.css('a').attribute('href').value

Mechanize

  • インスタンスの生成:agent = Mechanize.new
  • ページの取得(Mechanize::Page):page = agent.get("http://hoge.com")
  • 要素取得(全て):elements = page.search('title')
  • 要素取得(最初の1件のみ):elements = page.at('li a')
  • タグ内部の部分:text = ele.inner_text
  • 属性値の部分:url = element.get_attribute(:href)url = element[:href]
  • BASIC認証を行う:agent.add_auth('http://example.org', 'admin', 'password')
  • UA偽装:agent.user_agent_alias = 'Windows IE 9'
  • UA偽装例:Windows MozillaiPhoneMac Safari
  • プロキシサーバ(ユーザー名以降は端折れる):agent.set_proxy('proxy.example.com', 8080, 'admin', 'password')
  • 不正なSSL認証を無視する:agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
  • ファイルダウンロード:data = agent.get_file('http://example.com/file.zip')
  • POSTでパラメータを指定して投げつけ、結果を受け取る:response = agent.post("http://hoge.com/", {param1: "1", param2: "2"})して、response.bodyが本体、response.codeがステータスコード?

Capybara

  • PhantomJSをpoltergeist経由で使用するための準備:
Capybara.register_driver :poltergeist do |app|
    Capybara::Poltergeist::Driver.new(app,
    {:js_errors => false, :timeout => 1000})
end
  • インスタンスの生成:session = Capybara::Session.new(:poltergeist)
  • BASIC認証:session.driver.basic_authorize('admin', 'password')
  • ページの遷移:session.visit url
  • ボタンをクリック:click_button 'button'
  • リンクをクリック:click_link 'link'
  • ボタンかリンクをクリック:click_on 'target'
  • リンク付き画像をクリック(Alt属性を参照):click_on 'Alt'click_link 'Alt'
  • hiddenに値をセット:find('#secret', visible: false).set('secret')
  • テキストボックスを埋める(idかnameかplace_holderで指定可能):fill_in 'user_name', with: '山田太郎'
  • セレクトボックスを選択:select '項目1', from: 'list'
  • チェックボックスをチェック:check 'use_option'uncheck 'use_option'
  • HTMLソース:session.body
  • HTMLソースを保存:session.save_page('hoge.html')
  • スクショ(PhantomJSを操っている場合でも使える):session.save_screenshot('hoge.png')
  • タグ検索:
# 当てはまるタグ全て(Capybara::Elementを返す)
`session.all(:css, 'a#person_123')` //CSSセレクタ
`session.all(:xpath, '//a[@id="person_123"]')` //XPathセレクタ
# 当てはまる先頭タグ(Objectを返す)
`session.first(:css, 'a#person_123')` //CSSセレクタ
`session.first(:xpath, '//a[@id="person_123"]')` //XPathセレクタ
  • タグから結果を抜き出す:hoge[:attribute]で要素の値、hoge.valueでvalue要素、hoge.textでinner_textの値

Date

  • インスタンス作成1:date = Date.new(2016,6,3)
  • インスタンス作成2:date = Date.today
  • インスタンス作成3:date = Date.strptime('2014年6月2日','%Y年%m月%d日')
  • 月末からのオフセット:day = Date.new(2016, 5 , -1) #2016/5/31
  • 読み出し用メソッド:year, month, day, wday(曜日), yday(通算日)
  • Date→文字列:str = date.strftime("%Y-%m-%d %H:%M:%S")
  • 現在時刻:Time.now

JSON

  • JSON文字列→配列・ハッシュ:data = JSON.parse(str)
  • 配列・ハッシュ→JSON文字列:str = JSON.generate(data)str = obj.to_json
  • 整形しつつJSON化:str = JSON.pretty_generate(data)
  • parseとgenerateはJSON#[]で置き換えられる(省略記法)

参考資料

Rubyリファレンス
Ruby 1.9.3 リファレンスマニュアル > 正規表現
配列からハッシュを作成する
selectなどの配列の抽出・検索を行うメソッドまとめ
mapなどの配列の値を操作するメソッドまとめ
Ruby on Railsで拡張されているEnumerableのメソッドまとめ
【Ruby】よく使うFileクラスを使ったファイル読み込み処理
Rubyの破壊的メソッドと参照の値渡し
Marshalで配列やハッシュをディープコピーする
Rubyでかな/カタカナ(全角のみ)の濁点を本体の文字と分ける
Rails スクレイピング手法 Mechanizeの使い方
文字列の表記揺れをUnicode正規化で簡単に解決する方法
ファイル名/フォルダ名の抽出など
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」