概要
読んで字の如し(※時々書き換えます)
基本
- 三項演算子は判定式?真の場合:偽の場合
- <=>演算子は「左が大きければ 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,b
をa,b=func()
で受け取れる。 - 無限ループを書く場合、イテレータ不要なら
loop{ブロック}
かwhile true ~ end
、必要なら1.upto(0/0.0){|i|ブロック}
とする - 複数行の標準入力を受け取る場合、
STDIN
をファイル扱いできるのでSTDIN.each
やSTDIN.read.split("\n")
できる - 破壊的メソッドを自作する場合は、自作クラスの場合フツーにメンバ変数(@xなど)を書き換えれば良し、モンキーパッチの場合はself.replace(新しい中身)とすれば良し
- Object#cloneおよびObject#dupメソッドはオブジェクトを「浅く」コピーする。
- 乱数の基本:
random = Random.new
してからrandom.rand
やrandom.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 Mozilla
、iPhone
、Mac 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大辞典」