[Purdue-pm] corrected "Raku Perl 6 regular expression one-liner"

Mark Senn mark at purdue.edu
Thu Dec 27 17:46:14 PST 2018


Earlier I wrote:
    Here is a Raku (also known as Perl 6) one-liner to see what
    groups user "fred" is in in a /etc/group file
        perl6 -ne '/<<fred>>/ and .say' /etc/group
    
    Each line of an /etc/group file has the format
        groupname:password:groupid:members (user names separated by commas)
    
    
    DESCRIPTION OF THE RAKU ONE-LINER:
    
        WHAT         DESCRIPTION                              SEE
        perl6        we're running Raku Perl 6                [1]
        -n           don't print anything                     [2]
        e            do following expression for each line    [2]
        '            start the expression
        /            start a regex                            [3]
        <<           match a word start, same as «
        >>           match a word end, same as »
        /            end a regex
        and          if regex matches do what's after "and"
        .say          print $_ followed by a newline, same as $_.say
        '             end the expression
        /etc/group    the file to read
    
    [1] https://colabti.org/irclogger/irclogger_log/perl6?date=2018-10-25#l584
    [2] https://perl6.online/2018/12/20/using-command-line-options-in-perl-6-one-liners/
    [3] Regexes were formerly known as regular expressions.
        https://docs.perl6.org/language/regexes
    
    
    THE FINE PRINT
    
    <<fred>> will not match 'winifred'.
    
    The above one liner will match group names, passwords, or gids
    containing 'fred'.  Change '/<<fred>>/' to '/.*:<<fred>>/'.
    The '.*:' matches everything up to and including the last colon.
    
The '.*:' does not match everything up to and including the last colon!
Regexes in Raku Perl 6 are extremely powerful---much more powerful
than in Perl 5.  From https://docs.perl6.org/language/regexes
    You can prevent backtracking in regexes by
    attaching a : modifier to the quantifier:

Let's do this better.

perl6 -ne '.split(":")[*-1].match(/<<fred>>/) and .say' z

DESCRIPTION OF THIS RAKU ONE-LINER:

    WHAT           DESCRIPTION
    perl6          We're running Raku Perl 6.
    -n             Don't print anything.
    e              Do following expression for each line.
    '              Start the expression.
    .split(":")    Split the line into an array, breaking at colons.
                   Split is optimized and is probably much faster than a
                   regular expression ever could be for this.  Plus,
                   I think this is much easier to understand.
    [*-1]          Get the whatever'th minus one element of the array.
                   "whatever" is a very handy general concept in Perl 6.
    .match(        Does that match a regex?
                   (Formerly called a regular expression.)
    /              Start the regex.
    <<             Match a word start, same as "«" if you prefer that.
                   I like to use the same size operators for everything
                   so nothing gets lost in the "fine print".  If we just
                   used "/fred/", "winifred" would also be matched.
    fred           Match "fred".
    >>             Match a word end, same as "»" if you prefer that.
    /              End the regex
    )              End the "match(".
    and            If the regex matches, do what's after the "and".
    .say           Print $_ followed by a newline, same as "$_.say".
    '              End the expression.
    z              The file to read.

Using a z file of
    abc:def:gg
    abc:fred:ddd
    abc:ddd:fred
    abc:ddd:eee,fred,fff
    abc:ddd:eee,fff,fred
    abc:ddd:eee,fred2,fff
    abc:ddd:eee,2fred,fff
    abc:ddd:eee,2fred2,fff
gives
    abc:ddd:fred
    abc:ddd:eee,fred,fff
    abc:ddd:eee,fff,fred

-mark


More information about the Purdue-pm mailing list