How do I efficiently match many regular expressions at once?

The following is extremely inefficient:

    # slow but obvious way
    @popstates = qw(CO ON MI WI MN);
    while (defined($line = <>)) {
	for $state (@popstates) {
	    if ($line =~ /\b$state\b/i) {  
		print $line;
		last;
	    }
	}
    }                                        
That's because Perl has to recompile all those patterns for each of the lines of the file. As of the 5.005 release, there's a much better approach, one which makes use of the new qr// operator:

    # use spiffy new qr// operator, with /i flag even
    use 5.005;
    @popstates = qw(CO ON MI WI MN);
    @poppats   = map { qr/\b$_\b/i } @popstates;
    while (defined($line = <>)) {
	for $patobj (@poppats) {
	    print $line if $line =~ /$patobj/;
	}
    }

Back to perlfaq6