電気ウナギ的○○

About Home

こういう場合は「否定先読み」の正規表現を使った方がすっきりするな

shinoda (2012年8月18日 01:54)
あるディレクトリに、

・頭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

がマッチして幸せなのである。

電気ウナギ的○○

電気ウナギ的○○

About Back

コメント(0)

電気ウナギ的○○

電気ウナギ的○○

About Back

トラックバック(0)

トラックバックURL: https://blog.netandfield.com/mt/mt-tb.cgi/2165

電気ウナギ的○○

About This Site

電気ウナギ的○○
岩国在住。広島で働く超零細IT企業社長のいわゆる社長日記。
何か、酒と食い物のことばかり書いているようで・・・お察しのとおり、肥満体です:-)


2011/06/24
iPhone用サイト公開

Create with jQuery, jQTouch.


CLOSE