On Jan 17, 2016, at 11:07 AM, Tom Browder <tom.brow...@gmail.com> wrote:
> I'm trying to write all new Perl code in Perl 6. One thing I need is > the equivalent of the Perl 5 qr// and, following Perl 6 docs, I've > come to use something like this (I'm trying to ignore certain > directories): > > # regex of dirs to ignore > my regex dirs { > \/home\/user\/\.cpan | > \/home\/tbrowde\/\.emacs > } > > for "dirlist.txt".IO.lines -> $line { > # ignore certain dirs > if $line ~~ m{<dirs>} { > next; > } > } > > My question: Is there a way to have Perl 6 do the required escaping > for the regex programmatically, i.e., turn this: > > my $str = '/home/usr/.cpan'; > > into this: > > my regex dirs { > \/home\/usr\/\.cpan > } > > automatically? I think that your regex needs anchors to do what you want; your current regex will also exclude `/home/user/.cpanabcedfg`, for example. This is how I do it in Perl 5 (when using regexes instead of a hash): my $dirs = join '|', map { quotemeta } qw( /home/user/.cpan /home/tbrowde/.emacs ); my $dirs_re = qr/^(?:$dirs)$/; So, `quotemeta` is what you are looking for. Except that https://design.perl6.org/S29.html#Obsolete_Functions says: quotemeta Because regex escaping metacharacters can easily be solved by quotes ("Simplified lexical parsing of patterns" in S05), and variables are not automatically interpolated ("Variable (non-)interpolation" in S05), quotemeta is no longer needed. http://design.perl6.org/S05.html#Simplified_lexical_parsing_of_patterns http://design.perl6.org/S05.html#Variable_%28non-%29interpolation Summary of `Variable_%28non-%29interpolation`: In Perl 5, /$var/ deposits the contents of `$var` into the regex, just like of you had typed them in the source code. In Perl 6, /$var/ runs quotemeta on the contents of `$var`. If you want the Perl 5 behavior, then you write it as /<$var>/. Also, if you embed an array in a regex, it automatically treats it as `|` alternatives. So cool! # Plain text, *not* regex! my @dirs_to_skip = < /home/user/.cpan /home/tbrowde/.emacs > ; ... next if $line ~~ / ^ @dirs_to_skip $ /; Or, precompiled: my @dirs_to_skip = < /home/user/.cpan /home/tbrowde/.emacs > ; my $dir_re = / ^ @dirs_to_skip $ /; ... next if $line ~~ $dir_re; If you know that your exclusion list is always literal, you can leave the regex engine out of the process, and just do a hash lookup (which is even easier in Perl 6 with `set`, which sets the values all to `True`): my %dirs_to_skip = set < /home/user/.cpan /home/tbrowde/.emacs > ; ... next if %dirs_to_skip{$line}; -- Hope this helps, Bruce Gray (Util of PerlMonks)