I used to (before use strict) compose regexps by hiding the components inside an if, e.g.:
$complex_re = /^($ip) ($host) ($msg)$/ if (
$ip = /\d+\.\d+\.\d+\.\d+/,
$host = /[\-\.\w]+/,
$msg = /.*/
);
Nowadays, I use strict and eval, e.g.
my $complex_re = eval {
my $ip = qr/\d+\.\d+\.\d+\.\d+/;
my $host = qr/[\-\.\w]+/;
my $msg = qr/.*/;
return /^($ip) ($host) ($msg)$/;
);
We pay about a 5% penalty for the eval when we use this in a tight loop, however we can solve that by moving the regexp creation outside the loop.
Rate with eval without eval
with eval 116279/s -- -5%
without eval 121951/s 5% --
Patrick