04

09

[Ruby] 正規表現コレクション

2012.04.09(06:18)

「Rubyiestとしての歴史は、どういうパターンにマッチする正規表現を書き続けてきたかの歴史かもしれない」

Ruby 正規表現
http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fregexp.html


文字列の先頭と末尾にマッチさせる。
マッチするとその位置を返し、マッチしないとnilを返します。
E:\>ruby -v
ruby 1.9.3p0 (2011-10-30) [i386-mingw32]

E:\>irb
irb(main):001:0> /\AABC/ =~ "ABC XYZ"
=> 0
irb(main):002:0> /ABC\z/ =~ "ABC XYZ"
=> nil
irb(main):003:0> /XYZ\z/ =~ "ABC XYZ"
=> 4
irb(main):004:0> /\AXYZ/ =~ "ABC XYZ"
=> nil

文字列の先頭と末尾にマッチさせる
irb(main):001:0> /\AABC/ =~ "ABC XYZ"
=> 0
irb(main):002:0> /ABC\z/ =~ "ABC XYZ"
=> nil
irb(main):003:0> /XYZ\z/ =~ "ABC XYZ"
=> 4
irb(main):004:0> /\AXYZ/ =~ "ABC XYZ"
=> nil

空白で区切られた3つの英数字を取り出す。
後方参照でマッチした結果を使う。
irb(main):001:0> s="abc  def ghi"
=> "abc  def ghi"
irb(main):002:0> /(\w+)\s+(\w+)\s+(\w+)/ =~ s
=> 0
irb(main):003:0> p $1,$2,$3
"abc"
"def"
"ghi"
=> ["abc", "def", "ghi"]
空白で区切られた3つの英数字を取り出す。
の別解
String::splitを使う。
irb(main):026:0> "abc def ghi".split(/\s+/)
=> ["abc", "def", "ghi"]
irb(main):027:0> first,second,third = "abc def ghi".split(/\s+/)
=> ["abc", "def", "ghi"]
irb(main):028:0> p first,second,third
"abc"
"def"
"ghi"
=> ["abc", "def", "ghi"]

コンマで区切られた3つの英数字を取り出す。
CSVファイルはこれで読める。
irb(main):029:0> "abc,def,ghi".split(/,/)
=> ["abc", "def", "ghi"]

数値n桁にマッチさせる。
後方参照でマッチした結果を利用する。
irb(main):009:0> time = "2011/12/09 11:39:45"
=> "2011/12/09 11:39:45"
irb(main):010:0> /(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2})/ =~ time
=> 0
irb(main):011:0> year,month,day,hour,minute,second = $1,$2,$3,$4,$5,$6
=> ["2011", "12", "09", "11", "39", "45"]
irb(main):012:0> printf "#{year}/#{month}/#{day} #{hour}:#{minute}:#{second}\n"
2011/12/09 11:39:45
=> nil

(おおざっぱに)float数値かどうかを判定する。
irb(main):021:0> /(\-{0,1}\d*\.\d+)/ =~ '-123.45'
=> 0

コンマで区切られた16進数を、
整数の配列に変換する。
irb(main):032:0> "0x100,0x200,0x300".split(/,/)
=> ["0x100", "0x200", "0x300"]
irb(main):033:0> "0x100,0x200,0x300".split(/,/).map{|s| s.to_i(16)}
=> [256, 512, 768]

カレントディレクトリにあるmp3とmp4ファイルのリストを得る
irb(main):021:0> Dir.glob("*.mp[34]")

ファイルの拡張子が".rb"かどうか調べる
irb(main):022:0> path = 'E:\Ruby\1102_Linecount\line_count.rb'
=> "E:\\Ruby\\1102_Linecount\\line_count.rb"
irb(main):023:0> /\.rb\z/ =~ File.extname(path)
=> 0
irb(main):024:0> /\.txt\z/ =~ File.extname(path)
=> nil

URLをホスト名とパス名に分ける
irb(main):015:0> url = 'http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fregexp.html'
=> "http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fregexp.html"
irb(main):016:0> /http:\/\/([^\/]*)(.*)/ =~ url
=> 0
irb(main):017:0> host,path = $1,$2
=> ["doc.ruby-lang.org", "/ja/1.9.3/doc/spec=2fregexp.html"]

IPアドレスが10.8.ドメインかどうかを調べる
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> require 'resolv'
=> true
irb(main):003:0> /\A10\.8\./=~ Resolv.getaddress(Socket::gethostname)
=> 0
irb(main):004:0> /\A10\.9\./=~ Resolv.getaddress(Socket::gethostname)
=> nil

インテルCPUか調べる
irb(main):005:0> RUBY_PLATFORM
=> "i386-mingw32"
irb(main):006:0> /i386/ =~ RUBY_PLATFORM
=> 0

'check'で始まる行を見つける。
空行を見つける。
File.open(in_file,"r") { |f|
 while line = f.gets
 break if /^check/ =~ line       # 'check'で始まる行
 end
処理
 while line = f.gets
 break if /^$/ =~ line # 空行を見つけるまで
 end
処理
 }

"[a0,a1,[a2,a3]]"のように、
左括弧と右括弧で入れ子になった文字列で、
一番内側にある左括弧から右括弧までを
取り出す。
irb(main):041:0> /\[([^\[\]]+)\]/ =~ "[a0,a1,[a2,a3]]"
=> 7
irb(main):042:0> $1
=> "a2,a3"
irb(main):043:0> /\[([^\[\]]+)\]/ =~ "[a0,a1,[a2,a3,[a4,a5]],[a6,a7]]"
=> 14
irb(main):044:0> $1
=> "a4,a5"

加減乗除のどれかだったら
irb(main):050:0> '+|-|*|/'.split('|')
=> ["+", "-", "*", "/"]
irb(main):051:0> '+|-|*|/'.split('|').include?("+")
=> true
irb(main):052:0> '+|-|*|/'.split('|').include?("x")
=> false

アマゾンの書籍のURLから
ISBNコードを抽出する。
irb(main):053:0> url = "http://www.amazon.co.jp/Jenkins%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%EF%BD%9</A><BR>E%E3%83%93%E3%83%AB%E3%83%89%E3%83%BB%E3%83%86%E3%82%B9%E3%83%88%E3%83%BB%E3%83%<BR>87%E3%83%97%E3%83%AD%E3%82%A4%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82<BR>%8B%E6%8A%80%E8%A1%93-WEB-DB-PRESS-plus/dp/4774148911/ref=pd_sim_b_2"
irb(main):054:0> /dp\/(\d+\w{0,1})\// =~ url
=> 276
irb(main):055:0> $1
=> "4774148911"

irb(main):056:0> url = "http://www.amazon.co.jp/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%85%A5%E9%96%80-%E9%96%8B%E7%99%BA%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B47%E3%81%AE%E4%BD%9C%E6%B3%95-%E3%83%9D%E3%83%BC%E3%83%AB%E3%83%BBM%E3%83%BB%E3%83%87%E3%83%A5%E3%83%90%E3%83%AB/dp/482228395X/ref=pd_bxgy_b_text_b"
irb(main):057:0> /dp\/(\d+\w{0,1})\// =~ url
=> 372
irb(main):058:0> $1
=> "482228395X"

「Rubyiestとしての歴史は、どういうパターンにマッチする正規表現を書き続けてきたかの歴史かもしれない」
と思って、これまで書いたRubyプログラムから=~を検索してまとめてみた。しかし、私がこれまで書いた正規表現の「パターン」はだいたいここらへんで収束する。意外に少なかった。

4月3日、プログラム言語「Ruby」が「国際規格ISO/IEC 30170」として承認された
http://www.ipa.go.jp/about/press/20120402_2.html
の記念として書いてみました。

「プログラム言語Ruby」は JISX3017 ここ
http://www.jisc.go.jp/app/JPS/JPSO0020.html
の一番上で X3017 を入力するとPDFが読めます。


おまけ

正規表現の読解能力をあげるのにおすすめのソース
  • 標準ライブラリの cgi/util.rb 

プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示