あるディレクトリに、
という命名条件のファイルがあった時、そのファイル一覧の中から、2月9日(0209)の日付のもので、
という時、(1) のファイル名に当てる正規表現は簡単だよな。
例えばファイル名の一覧が、
だったら、
で 0209C01.jpg だけがマッチする。(.{1}のところは、[A-Z]{1}じゃないかと言われそうだけど、ここには必ずアルファベットが入っているので .{1}で十分なんだ。{1}はいらないけど、わかりやすくするためにね)
じゃあ、(2) の抽出はその否定でいいのか?って言うと、それは駄目だよね。
では、
が全部マッチしてしまう。実際にマッチさせたいのは先頭が 0209 のものだけなのに。
まあ、
とすればいいんだけど、何か 2つの条件を && でつなげるのも格好悪いなあ、何となく。
こういう時に、日頃はあんまり使わない「否定先読み」を使うと正規表現一発で済むので格好良い。
これなら、
にマッチするので、上記の例なら、
がマッチして幸せなのである。
・頭4桁が月日(色々な月日のファイルが混在)
・その後に1文字のアルファベット(まあ、他の文字でもいいんだけど)
・その更に後ろに2桁の数字
・最後に、JPEG の拡張子(.jpg)
という命名条件のファイルがあった時、そのファイル一覧の中から、2月9日(0209)の日付のもので、
(1)アルファベットの後ろの 2桁の数字が 01 のものをまず抽出したい。
(2)その後、2桁の数字が 01以外のファイルを抽出したい。
という時、(1) のファイル名に当てる正規表現は簡単だよな。
例えばファイル名の一覧が、
0209C01.jpg
0209C02.jpg
0209Q38.jpg
0209C10.jpg
0209A28.jpg
0210C28.jpg
0209Y28.jpg
0212C01.jpg
だったら、
if ($d =~ /^0209.{1}01\.jpg$/) {...}
で 0209C01.jpg だけがマッチする。(.{1}のところは、[A-Z]{1}じゃないかと言われそうだけど、ここには必ずアルファベットが入っているので .{1}で十分なんだ。{1}はいらないけど、わかりやすくするためにね)
じゃあ、(2) の抽出はその否定でいいのか?って言うと、それは駄目だよね。
if ($d !~ /^0209.{1}01\.jpg$/) {...}
では、
0209C02.jpg
0209Q38.jpg
0209C10.jpg
0209A28.jpg
0210C28.jpg
0209Y28.jpg
0212C01.jpg
が全部マッチしてしまう。実際にマッチさせたいのは先頭が 0209 のものだけなのに。
まあ、
if ($d !~ /^0209.{1}01\.jpg$/ && $d =~ /^0209/) {...}
とすればいいんだけど、何か 2つの条件を && でつなげるのも格好悪いなあ、何となく。
こういう時に、日頃はあんまり使わない「否定先読み」を使うと正規表現一発で済むので格好良い。
if ($d =~ /^0209.{1}((?!01).){2}\.jpg$/) {...}
これなら、
・2月9日(頭 4桁が 0209)のものだけで
・アルファベットの後ろの 2桁が 01 以外のもの
にマッチするので、上記の例なら、
0209C02.jpg
0209Q38.jpg
0209C10.jpg
0209A28.jpg
0209Y28.jpg
がマッチして幸せなのである。