正規表現のパターンを変数に入れる
いつもいつも「あれ?どうやるんだっけ?」と悩んでググったり、irbで試したりしてしまうので、ここに書いておくと忘れないんじゃないかと。
いろいろなケース
irb> ptn = '^http://.+?/' ← URIのルートを取ってくるパターン => "^http://.+?/" irb> uri = "http://2.5-55.jp/items/etc" ← テスト用URI => "http://2.5-55.jp/items/etc"
まず、ノーマルなケース。変数を入れるのについつい "#{}"とダブルコートでくくってしまいそうになりますが、そうするとダブルコート込みのパターン認識になってしまいます。
irb> uri.scan(/#{ptn}/) ← 正しい => ["http://2.5-55.jp/"] irb> uri.scan(%r|#{ptn}|) ← 正しい => ["http://2.5-55.jp/"] irb> uri.scan(/"#{ptn}"/) ← 間違い => []
パターンは一度変数に入れると「/」はエスケープしなくてもいいみたいですね。「/」をエスケープしてみても同じ結果です。
irb> ptn = '^http:\/\/.+?\/' ← /エスケープ => "^http:\\/\\/.+?\\/" irb> uri.scan(/#{ptn}/) ← OK => ["http://2.5-55.jp/"] irb> uri.scan(%r|#{ptn}|) ← OK => ["http://2.5-55.jp/"]
パターンを表す「/」まで変数に入れてみたらどうなるでしょうか。ダメですね。
irb> ptn = '/^http:\/\/.+?\//' ← /を追加 => "/^http:\\/\\/.+?\\//" irb> uri.scan(/#{ptn}/) ← NG => irb> uri.scan(%r|#{ptn}|) ← NG =>
では、「%r」を変数に入れたらどうでしょう。配列の先頭だけみると正しい結果が返ってきています。ただ、返ってきてる結果をみるとちょっと嫌な感じなので、やらないほうが無難ですね。
irb> ptn = '%r|^http:\/\/.+?\/|' ← %r||を追加 => "%r|^http:\\/\\/.+?\\/|" irb> uri.scan(/#{ptn}/) => ["http://2.5-55.jp/", "", "", "", "", "", "", "", "", "", ""] irb> uri.scan(%r|#{ptn}|) => ["http://2.5-55.jp/", "", "", "", "", "", "", "", "", "", ""] irb>