memo

#!/usr/bin/perl

use re 'eval';

my $key = "192.168.[0-100].*";
my $re = make_re($key);

print "[$re]\n";

my @lines = grep {$_} split /\n/,qq{
192.168.99.112 - - [10/Jul/2013:13:53:15 +0900] "GET /top.html HTTP/1.1" 404 1426 "http://facebook.com" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
192.168.81.20 - - [10/Jul/2013:15:06:33 +0900] "GET /hogehoge.html HTTP/1.1" 404 4374 "http://paiza.jp" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
192.168.223.58 - - [10/Jul/2013:21:32:01 +0900] "GET /hoge.html HTTP/1.1" 304 6601 "http://paiza.jp" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0"
};

for(@lines){
	if(m@^$re@){
		s@\[|\]@@gim;
		my($ip,$date,$file) = (split / /)[0,3,6];
		print "$ip $date $file\n";
	}
}

sub make_re{

	my $pattern = shift;

	my @re;
	my $count = 1;

	for my $n ($pattern =~ m@([^\.]+)@g){
		if($n =~ m@\[@){ # レンジ指定
			my @n = $n =~ m@(\d+)@gim;
			push @re,sprintf '(\d+)(?(?{range($%s,%s,%s)})|(?!))',$count,$n[0],$n[1];
			$count++;
		} elsif($n eq "*") { #アスタリスク
			push @re,'\d+';
		} else { #数値
			push @re,"$n";
		}
	}
	return join('\.',@re);
}

sub range{
	my ($n,$min,$max) = @_;
	return ($n >= $min && $n <= $max)
}