State_Space has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,
For the past month I've used this code and it's finally bothering me enough to post. How can I make this code inside the if statement more elegant?
use strict; use warnings; my $text = "Signal\nLTE-FDD 4; Channel 2175"; my $band = ""; my $channel = ""; my $temp = ""; if($text =~ /Signal\nLTE-FDD [\d]{1,2}; Channel [\d]{3,4}/i) { $temp = $&; #store regex match $temp =~ /LTE-FDD [\d]{1,2};/i; $& =~ /[\d]{1,2}/i; $band = $&; #store regex match $temp =~ /Channel [\d]{3,4}/i; $& =~/[\d]{3,4}/i; $channel = $&; #store rege match } print "$band\t$channel\n";
30 Oct Update: The examples and comments posted are very helpful. Thank you for your replies.

Replies are listed 'Best First'.
Re: Quick Regex question
by AppleFritter (Vicar) on Oct 29, 2015 at 22:02 UTC

    Howdy, welcome back to the Monastery!

    Use capturing. Also take advantage of the fact the m// operator returns captures ($1, $2 etc.) in list context, and observe you don't need square brackets around \d:

    my $text = "Signal\nLTE-FDD 4; Channel 2175"; my ($band, $channel) = ($text =~ /Signal\nLTE-FDD (\d{1,2}); Channel ( +\d{3,4})/i); print "$band\t$channel\n";

    More on capturing groups can be found in perlre#Capture groups.

Re: Quick Regex question
by AnomalousMonk (Archbishop) on Oct 29, 2015 at 23:29 UTC

    Also consider that a "channel" number with more than four digits will produce a match:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $text = shift; print qq{text '$text'}; ;; my $match = my ($band, $channel) = $text =~ /Signal LTE-FDD (\d{1,2}) +; Channel (\d{3,4})/i; ;; if ($match) { print qq{band '$band' channel '$channel'}; } else { print 'no match'; } " "Signal LTE-FDD 45; Channel 123456789" text 'Signal LTE-FDD 45; Channel 123456789' band '45' channel '1234'
    You may want to use the  \A \z string beginning/end assertions or a  (?!\d) negative look-ahead to limit such matches. See Assertions and Look-Around Assertions in perlre.

    Update: Note also that use of the  $& regex special variable or its "friends"  $` $' anywhere in a script imposes significant regex matching performance penalties everywhere in the script. See perlvar.


    Give a man a fish:  <%-{-{-{-<

      Note also that use of the $& regex special variable or its "friends" $` $' anywhere in a script imposes significant regex matching performance penalties everywhere in the script.
      Yeah, this used to be true, but has been slightly improved overtime, and has been basically fixed with Perl 5.20. So the penalty may or may not be there depending of the Perl version being used.

      Having said that, I've personally never used those variables for anything else than just testing a couple of times what they do (if only because, at least at work, I'm stuck with a much older version of Perl).