[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