やりたい事
動画ファイルの拡張子をまとめた正規表現を作って、
その正規表現でgrep
すると、動画ファイルの名前だけの配列が取得できるようにしたい。
例
Dir.glob('*')
# => ["hoge.mp4", "huga.png", "homu.mov"]
Dir.glob('*').grep(video_extensions_regexp)
# => ["hoge.mp4", "homu.mov"]
とりあえず、手動で拡張子を登録してみる
動画ファイルの拡張子を思いつくだけ配列に格納して、正規表現として展開する
extensions = %w(mp4 m4v avi mov)
joined_extensions = extensions.join('|')
#=> "mp4|m4v|avi|mov"
video_extensions_regexp = /\.(#{joined_extensions})$/
#=> /\.(mp4|m4v|avi|mov)$/
一応これで出来ますが、絶対漏れがありそうですよね…。
そこで、mime-typesを導入してみます。
mime-typesを使って拡張子を登録する
mime-types
には、 MIMEのタイプが網羅されているだけでなく、各タイプに該当する拡張子も登録されています。便利!
実際に試してみたい方は、gem install mime-types
して、
irbやpryなどからrequire 'mime/types'
して、下記の例を実行してみてください。
mime-typesの例
MIME::Types['video/mp4']
#=> [#<MIME::Type: video/mp4>]
# 配列が返ってくる
MIME::Types['video/mp4'].first.extensions
#=> ["mp4", "mpg4", "f4v", "f4p", "mp4v"]
# この拡張子一覧を使う
MIME::Types[/^video/]
#=> [#<MIME::Type: video/1d-interleaved-parityfec>,
#<MIME::Type: video/3gpp>,
#<MIME::Type: video/3gpp-tt>,
#<MIME::Type: video/3gpp2>,
#...
# 正規表現を渡すと、該当するMIME Typesが全部返ってくる
これを使えば、全てのvideoファイルの拡張子一覧が作れそうですね!
完成形
extensions = MIME::Types[/^video/].flat_map(&:extensions)
#=> ["3gp", "3gpp", "3g2", "3gpp2", "dl", "dv", "gl"...]
joined_extensions = extensions.join('|')
#=> "3gp|3gpp|3g2|3gpp2|dl|dv|gl..."
video_extensions_regexp = /\.(#{joined_extensions})$/
#=> /\.(3gp|3gpp|3g2|3gpp2|dl|dv|gl...)$/
といった感じで、ほとんど全ての動画ファイル形式をカバーした正規表現が作れました。
ついでに、method_missingを使って、動画以外(画像とか)にも使えるようにしたModuleを作ってみました。
複数形式に対応したModule
require 'mime/types'
module ExtReg
def self.method_missing(name, *args)
if instance_variable_defined?("@#{name}")
instance_variable_get("@#{name}") # インスタンス変数に保存されていればそれを取ってくる
elsif !(types = MIME::Types[/^#{name}/]).empty? # 該当のMIMEタイプが存在するか確認する
extensions = types.flat_map(&:extensions)
joined_extensions = extensions.join('|')
extensions_regexp = /\.(#{joined_extensions})$/
instance_variable_set("@#{name}", extensions_regexp) # @videoなどに保存しておく
extensions_regexp
else
super
end
end
end
ExtReg.video
#=> /\.(3gp|3gpp|3g2|3gpp2|dl|dv|...)$/
ExtReg.image
#=> /\.(bmp|cgm|g3|gif|ief|jp2|...)$/
これを使うと、頭の例がこうなります。
Dir.glob('*')
# => ["hoge.mp4", "huga.png", "homu.mov"]
Dir.glob('*').grep(ExtReg.video)
# => ["hoge.mp4", "homu.mov"]
簡単に目的達成できました!
これでもう、拡張子を自力で列挙しなくて済む…。