QA@IT

Stringのscanにおいて正規表現の結果の否定をとりたい

3914 PV

現在rubyを使っていて、urlの最後の/以外の値を取りたいのですが、うまくいきません。

具体的な例を挙げると
ttp://qa.atmarkit.co.jp/q/new.html
があった場合、
ttp://qa.atmarkit.co.jp/q
を取得したいということです。

この処理を実現するためにこのようなコードを書きました。

"http://qa.atmarkit.co.jp/q/new.html".scan(/\/[^\/]*$/)

この結果は"/new.html"になります。
そこでこのscanの結果の否定を取って、"ttp://qa.atmarkit.co.jp/q"を取得したかったのですが、!や[^]を使ってもうまくとりだせません。

どのようにすればいいのでしょうか?

回答

対象の文字列がURLであることが判別済みであれば、単純に

"http://qa.atmarkit.co.jp/q/new.html".scan(/.*\//)
# => ["http://qa.atmarkit.co.jp/q/"]

でどうでしょう?
最長マッチになるので、\/はURLの最後の/にマッチします。

最後の/が邪魔であればchopで削ればよいと思います。

"http://qa.atmarkit.co.jp/q/new.html".scan(/.*\//).first.chop
# => "http://qa.atmarkit.co.jp/q"
編集 履歴 (1)
  • 最長マッチっていう概念があったのですね。知りませんでした、勉強になりました。ありがとうございます。 -

削除したい部分の正規表現を使って部分削除するのはsubを使います。
"http://qa.atmarkit.co.jp/q/new.html".sub(/\/[^\/]*$/,"")

取り出したい部分の正規表現を使って部分を取り出すのは[]を使います。
"http://qa.atmarkit.co.jp/q/new.html"[/.*\//]
"http://qa.atmarkit.co.jp/q/new.html"[/.*\//].chop

編集 履歴 (0)
  • なるほど、このようなマッチを置き換えるメソッドがあったのですね。ありがとうございます。 -

File::dirname(url)でどうでしょう。

編集 履歴 (0)
  • dirnameにこのような使い方があったのですか。参考にさせていただきました。 -
"ttp://qa.atmarkit.co.jp/q/new.html".scan(/(.+)(\/[^\/]*?)$/)[0][0]

それより前も検索対象にしてグループから取得する、こういうのではだめですか?
後ろはグループにする必要はないですが一応してあります。
念のため最小マッチの ?も追加してあります。。

編集 履歴 (1)
  • なるほど、配列にしてとるんですね。参考にさせていただきます。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。