=head1 VERSION
-version 5.20200523
+version 5.20201107
=head1 DESCRIPTION
=head2 Where to find the perlfaq
The perlfaq is an evolving document. Read the latest version at
-L<http://learn.perl.org/faq/>. It is also included in the standard Perl
+L<https://perldoc.perl.org/perlfaq>. It is also included in the standard Perl
distribution.
=head2 How to use the perlfaq
your suggestion create an issue or pull request against
L<https://github.com/perl-doc-cats/perlfaq>.
-Once approved, changes are merged into L<https://github.com/tpf/perlfaq>, the
-repository which drives L<http://learn.perl.org/faq/>, and they are
-distributed with the next Perl 5 release.
+Once approved, changes will be distributed with the next Perl release and
+subsequently appear at L<https://perldoc.perl.org/perlfaq>.
=head2 What if my question isn't answered in the FAQ?
=head1 VERSION
-version 5.20200523
+version 5.20201107
=head1 DESCRIPTION
(contributed by brian d foy)
-If you have Perl 5.10 or later, this is almost trivial. You just smart
-match against an array of regular expression objects:
-
- my @patterns = ( qr/Fr.d/, qr/B.rn.y/, qr/W.lm./ );
-
- if( $string ~~ @patterns ) {
- ...
- };
-
-The smart match stops when it finds a match, so it doesn't have to try
-every expression.
-
-Earlier than Perl 5.10, you have a bit of work to do. You want to
+You want to
avoid compiling a regular expression every time you want to match it.
In this example, perl must recompile the regular expression for every
-iteration of the C<foreach> loop since it has no way to know what
-C<$pattern> will be:
+iteration of the C<foreach> loop since C<$pattern> can change:
- my @patterns = qw( foo bar baz );
+ my @patterns = qw( fo+ ba[rz] );
- LINE: while( <DATA> ) {
- foreach $pattern ( @patterns ) {
- if( /\b$pattern\b/i ) {
- print;
+ LINE: while( my $line = <> ) {
+ foreach my $pattern ( @patterns ) {
+ if( $line =~ m/\b$pattern\b/i ) {
+ print $line;
next LINE;
}
}
}
-The C<qr//> operator showed up in perl 5.005. It compiles a regular
+The C<qr//> operator compiles a regular
expression, but doesn't apply it. When you use the pre-compiled
version of the regex, perl does less work. In this example, I inserted
a C<map> to turn each pattern into its pre-compiled form. The rest of
the script is the same, but faster:
- my @patterns = map { qr/\b$_\b/i } qw( foo bar baz );
+ my @patterns = map { qr/\b$_\b/i } qw( fo+ ba[rz] );
- LINE: while( <> ) {
- foreach $pattern ( @patterns ) {
- if( /$pattern/ ) {
- print;
+ LINE: while( my $line = <> ) {
+ foreach my $pattern ( @patterns ) {
+ if( $line =~ m/$pattern/ ) {
+ print $line;
next LINE;
}
}
In some cases, you may be able to make several patterns into a single
regular expression. Beware of situations that require backtracking
-though.
+though. In this example, the regex is only compiled once because
+C<$regex> doesn't change between iterations:
- my $regex = join '|', qw( foo bar baz );
+ my $regex = join '|', qw( fo+ ba[rz] );
- LINE: while( <> ) {
- print if /\b(?:$regex)\b/i;
+ while( my $line = <> ) {
+ print if $line =~ m/\b(?:$regex)\b/i;
}
+The function L<Data::Munge/list2re> on CPAN can also be used to form
+a single regex that matches a list of literal strings (not regexes).
+
For more details on regular expression efficiency, see I<Mastering
Regular Expressions> by Jeffrey Friedl. He explains how the regular
expressions engine works and why some patterns are surprisingly