正規表現で最後に出てきたものを取りたい
たとえば、次のようなファイル名のファイルがあるとして、ここから、数字を取り出したい。
しかも欲しい数字は(2)の2が欲しい。
2016-08-07の売上報告のコピー(2).xls # 欲しい数字2、それも(2) の中の2が欲しい。
どうやるか。
通常であれば、数字にマッチさせ、マッチ個数を見て、最後を取り出せば、いいんだろうけど。
正規表現だけで実現できないかなと思いついたので調べみました。
正規表現で、最後にマッチしたものだけを取り出せないか、考えてみました。
考えた結果がコレ
/([\d]+)[^\d]+$/
実際の結果はこちら
'2016-08-07の売上報告のコピー(13).xls'.match /([\d]+)[^\d]+$/ #=> #<MatchData "13).xls" 1:"13">
ポイント
最初に、数字にマッチさせてみた。
>> '2016-08-07の売上報告のコピー(13).xls'.scan /([0-9]+)/ => [["2016"], ["08"], ["07"], ["13"]]
数字にマッチさせてみると、それっぽいのが取れるんで。
つぎに、数字+数字以外+行末にマッチさせる。
>> '2016-08-07の売上報告のコピー(13).xls'.scan /([\d]+)[^\d]*$/ => [["13"]]
これでいける。つまり、ココから言えることは、
最後の出現を取りたいときは、欲しい文字+欲しい文字以外+末尾
とすればいいとわかる。
最後の出現=(欲しい文字+欲しい文字以外)の組み合わせ。
英単語(小文字)で一番最後に出現したものを取る場合
>> 'iPhone は iOS を使った Apple の製品です。'.scan /([A-Za-z]+)[^A-Za-z]*$/ => [["Apple"]]
N番目の出現は、流石にしんどいけど、何個か組み合わせば、実現できそう
最後から二つ目を取るには
>> 'iPhone は iOS を使った Apple の製品です。'.scan /([A-Za-z]+)[^A-Za-z]*[A-Za-z]*[^A-Za-z]*$/ => [["iOS"]] >>
正規表現で (欲しい文字)+欲しい文字以+外欲しい文字+欲しい文字以外
と組み合わせで実現できそうですね。
先頭から2番めに出てきた数字列にマッチさせる。
この方法を考えていけば、先頭から2回めに出てきた文字列にマッチさせることが出来ると思いました。
>> '2016-08-07の売上報告のコピー(13).xls'.scan /^[^\d]*[\d]+[^\d]*([\d]+)/ => [["08"]] >> '2016-08-07の売上報告のコピー(13).xls'.scan /^[^\d]*[\d]+[^\d]*[\d]+[^\d]*([\d]+)/ => [["07"]]
あとはコレを複数個組み合わせれば、先頭からN番目も一回の正規表現で取り出せそうですね。
まぁ実際には、マッチ配列から取出すことのほうが多いんですけど。