それ Regexp::Assemble

ん?ループ云々を抜きにして、こういうのは Regexp::Assemble の出番じゃないの?添削だから?それともパフォーマンスとか?

use Regexp::Assemble;

my %analyze = (
    qr/Pattern 1/ => 'Pattern 1',
    qr/Pattern 2/ => 'Pattern 2',
    qr/Pattern 3/ => 'Pattern 3',
);

my $re = Regexp::Assemble->new;
$re->track->add(keys %analyze);

while (my $log = $logs->readline) {
    next unless $log->{ua} and defined (my $matched = $re->match($log->{ua}));
    my $pattern = $analyze{$matched};
    # do something for pattern
}

こっちの方が、簡単かつ分かりやすいと思う。