in reply to Use global flag when declaring regular expressions with qr?

Unrelated tips:

use v5.10; use strict; use warnings; my $re = ...; while ( <> ) { say $1 while /$re/g; }

Replies are listed 'Best First'.
Re^2: Use global flag when declaring regular expressions with qr?
by unmatched (Sexton) on Oct 28, 2024 at 19:41 UTC
    I hope you're using use strict; use warnings; or equivalent, but simply left it out for brevity.

    Yes, of course, that's one of the very first things that I learned! The rest of the code is just a bunch of regular expressions. Although I'm not using use v5.10, didn't know it was necessary. I would've guessed that the code runs at the same version as the interpreter does.

    Thank you for all these tips. With the main issue out of the way, all that's left is refactor into a nice looking script with more options. On that note, how would I implement it such that I could either provide any number of files, or read from standard input? This is what I came up with (should I open a new question for this?):

    sub match_url { my $row = shift @_; while ($row =~ /$re/g) { say "$&"; } } if ( !@ARGV || $ARGV[0] eq "-") { @ARGV = <STDIN>; chomp(@ARGV); match_url(@ARGV); } else { # Do I need to handle the error case with this syntax? while (<>) { chomp $_; match_url($_); } }

    Again, thank you all for your input!

      The use VERSION says that the perl running the code must be at least that version and enables the bundle of features recommended for that version. For 5.10, this is bareword_filehandles, indirect, multidimensional, say, state, and switch. See feature for details.
      --
      A math joke: r = | |csc(θ)|+|sec(θ)| |-| |csc(θ)|-|sec(θ)| |

        That's good to know. I'll be sure to read up on that. Thank you all!

      Some operations can be shortened even further. It is up to the reader to decide if that increases or decreases maintainability :)

      sub match_url { my $row = shift; # No @_ required, that is the default my @matches = ($row =~ m/$re/g) or return; # do something with @matches } if (!@ARGV or $ARGV[0] eq "-") { chomp (@ARGV = <STDIN>); # chomp can be done in one go match_url ($_) for @ARGV; # Your match_url takes one arg, not a li +st } else { # Do I need to handle the error case with this syntax? while (<>) { chomp $_; # Is chomp really needed? match_url probably ignores + trailing EOL in $re match_url ($_); } }

      for vs while

      ($str =~ m/$re/g) (note the parens) returns all matches in one list

      use 5.012003; use warnings; my $str = "abacadabra"; my $rex = qr{(a\w)}; say "-- say"; say for ($str =~ m/$rex/g); say "-- while"; while ($str =~ m/$rex/g) { say $1; } -> -- say ab ac ad ab -- while ab ac ad ab

      Enjoy, Have FUN! H.Merijn
        (note the parens) ... say for ($str =~ m/$rex/g);
        The parens in the for? Those do absolutely nothing.
        --
        A math joke: r = | |csc(θ)|+|sec(θ)| |-| |csc(θ)|-|sec(θ)| |
        It is up to the reader to decide if that increases or decreases maintainability :)

        On the one hand, I really like how there are so many similarities with shell scripting, in terms of syntax at least. On the other, it's a bit confusing to keep track of so many implicit behaviors. I was always told to be explicit whenever possible as it makes code easier to reason about. I'm afraid to forget what variables like @_ do if I don't use them often enough! :D

        Thanks for the tips!

      while ( <> ) already defaults to STDIN.
      $ t() { perl -Mv5.10 -e'while (<>) { chomp; say "<$_>"; }' "$@"; } $ t \ <( echo 'Contents of virtual file 1' ) \ <( echo 'Contents of virtual file 2' ) <Contents of virtual file 1> <Contents of virtual file 2> $ echo 'Contents of virtual file' | t <Contents of virtual file>

        Clearly, I still have a lot to learn. I'll go have a read on all the basics a little more before I continue with this I think.

        Thank you again!