Brad Gilbert <b2gi...@gmail.com> wrote:
> You don't want to use <{…}>, you want to use ""

>     if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {

Well, as contrived examples go this one could be
improved.  Instead of directly dereferencing a
hash, maybe I should've used a sub call.

> Note that {} is there to update $/ so that $0 works the way you would expect

And notably you really need to know that trick to
get that to work, but the direction I was
going using <{ ... }> just works without it.

I can confirm that the gratuitous code block trick fixes
the approach I really thought should work:

   / (^P\d+) \s+ {} $( %products{$0} ) /

This had me wondering if named captures might work
differently, but they don't, you still need the {}
there:

   / $<prod_id>=(^P\d+) \s+
            {}
            $( %products{$<prod_id>.Str} ) /


> Although I would do something like this instead:
>
>     my ($code,$desc) = $line.split( /\s+/, 2 );
>     if %products{$code} eq $desc {

Yes, there's other simpler ways... I was just
looking for an excuse to try regex code
interpolation, particularly when using capture
variables in the code... and it does turn out
there's an unexpected (to me) gotcha there.


On 6/15/20, Brad Gilbert <b2gi...@gmail.com> wrote:
> You don't want to use <{…}>, you want to use ""
>
>     if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {
>
> Note that {} is there to update $/ so that $0 works the way you would
> expect
>
> Although I would do something like this instead:
>
>     my ($code,$desc) = $line.split( /\s+/, 2 );
>     if %products{$code} eq $desc {
>
> On Sun, Jun 14, 2020 at 6:44 PM Joseph Brenner <doom...@gmail.com> wrote:
>
>> In part because of the recent discussion here, I decided to
>> play around with using Raku code embedded in a regexp.
>> I came up with a contrived example where I was going to
>> examine a product listing in a text block to see if the product
>> descriptions matched the product codes.  The valid associations
>> I have in a hash, so I'm (1) matching for product codes; (2)
>> using embedded code to look-up the associated description in the hash;
>> (3) using the returned description inside the regex.
>>
>> my %products = ( 'P123' => "Green Labels That Say Magenta",
>>                  'P666' => 'Darkseid For President Bumpersticker',
>>                  'P912' => "Corn dogs",
>>                  );
>>
>> my $text =  q:to/END/;
>> P123  Viridian Green Label Saying Magenta
>> P666  Yoda puppets
>> P912  Corn dogs
>> END
>>
>> my @lines = $text.lines;
>> say @lines;
>>
>> for @lines -> $line {
>>    say "checking line: $line";
>>    ## This line works, but it's not a complete solution:
>>    if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> /
>> {
>>        say "Matched, line looks good";
>>    }
>>    else {
>>        say "NO: bad line.";
>>    }
>> }
>>
>> I'd thought that a line like this would work:
>>
>>     if $line ~~ / (^P\d+) \s+ <{ %products{$0} }> / {
>>
>> The trouble though is I've got spaces inside the descriptions,
>> so if the returned string is treated as a regexp, I get these
>> warnings:
>>
>>    Potential difficulties:
>>        Space is not significant here; please use quotes or :s
>> (:sigspace) modifier (or, to suppress this warning, omit the space, or
>> otherwise change the spacing)
>>
>> Reading a bit, I thought this should work
>>
>>     if $line ~~ / (^P\d+) \s+ $( %products{$0} ) / {
>>
>> That's supposed to use the return string as a literal match.
>> Instead I get a lot of strange messages like:
>>
>>    Use of Nil in string context   in regex
>>
>> Flailing around I considered lots of variations like this:
>>
>>    if $line ~~ / (^P\d+) \s+ Q[<{ %products{$0}}>] / {
>>
>> But I think that ends up treating everything inside the Q[]
>> literally, so you never do the hash lookup.
>>
>> Another thing that might solve this problem is some sort of
>> regexp quote function I could use inside the code before
>> returning the string, but I don't know what that would be...
>>
>

Reply via email to