大前提
正規表現は最後の手段にするべきです。
結論
RFC3986 に従います(後述)。
たとえば対象とする URL が https://pbs.twimg.com/media/FAlJ_JsUUAAgOSq?format=jpg&name=orig であったとします。そのとき、以下のように抽出できます。
url = 'https://pbs.twimg.com/media/FAlJ_JsUUAAgOSq?format=jpg&name=orig' /\A(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?\Z/.match(url)
実行結果
実行結果は以下のようになります。
pry(main)> /\A(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?\Z/.match(url) => #<MatchData "https://pbs.twimg.com/media/FAlJ_JsUUAAgOSq?format=jpg&name=orig" 1:"https:" 2:"https" 3:"//pbs.twimg.com" 4:"pbs.twimg.com" 5:"/media/FAlJ_JsUUAAgOSq" 6:"?format=jpg&name=orig" 7:"format=jpg&name=orig" 8:nil 9:nil>
今回 nil
となっている 8
と 9
の値には「フラグメント(ハッシュ)」が入ります。https://example.com/foobar#hoge
の #hoge
に当たる部分です。
この例の場合には 8
には #hoge
が、9
には hoge
が入ります。
背景
RFC3986 に書かれている正規表現をそのまま Ruby で書きました。 datatracker.ietf.org
(補足)ファイル名を取得する場合
ファイル名を取得するには 5
の値を File.basename
メソッドに渡します。
url = 'https://pbs.twimg.com/media/FAlJ_JsUUAAgOSq.jpg' url_path = /\A(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?\Z/.match(url)[5] File.basename(url_path) #=> "FAlJ_JsUUAAgOSq.jpg"