Hi Joe,
1. I got your first "if" line (below) from June 14th to work, the one
you said, "it's not a complete solution":
1> if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / {
2. I got Brad's "if" line (below) from June 15th to work:
2> if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {
3. However, I couldn't get the {}-updated "if" line (below) you posted
from June 17th to work:
3> if / (^P\d+) \s+ {} $( %products{$0} ) / {
4. Nor could I get your named-capture "if" line (below) from June 17th to work:
4> if / $<prod_id>=(^P\d+) \s+
{}
$( %products{$<prod_id>.Str} ) / {
By "works", I mean that the third "Corn dogs" example matches, while
the first two fail:
checking line: P123 Viridian Green Label Saying Magenta
NO: bad line.
checking line: P666 Yoda puppets
NO: bad line.
checking line: P912 Corn dogs
Matched, line looks good
"This is Rakudo version 2020.02.1.0000.1 built on MoarVM version
2020.02.1 implementing Raku 6.d."
HTH, Bill.
On Wed, Jun 17, 2020 at 1:13 PM Joseph Brenner <[email protected]> wrote:
>
> Brad Gilbert <[email protected]> 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 <[email protected]> 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 <[email protected]> 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...
> >>
> >