Reputation: 5749
Sometimes I have a long list and I would like to check whether a string matches anything in the list. I am trying to interpolate a junction inside a regex. They are all errors.
say "12345" ~~ m/ <{ (2,3,4).any }> /
Cannot resolve caller MAKE_REGEX(Int, Bool, Bool, Int, PseudoStash); none of these signatures match:
say "12345" ~~ m/ $( (2,3,4).any ) /
This type cannot unbox to a native string: P6opaque, Junction
Does this error message mean that junctions cannot be used inside regex interpolation?
The work-around I have is
say "12345" ~~ m/ <{ (2,3,4).join("||") }> /
「2」
How can I use junctions inside regex interpolation?
Upvotes: 10
Views: 271
Reputation: 32489
Sometimes I have a long list and I would like to check whether a string matches anything in the list.
Use a list, not a Junction:
my @list = <bar bartoo baragain>;
say 'bartoo' ~~ / @list /; # 「bartoo」
say 'bartoo' ~~ / <{<bar bartoo baragain>}> /; # 「bartoo」
Note that by default you get the longest matching token.
I am trying to interpolate a junction inside a regex. They are all errors. ... Does this error message mean that junctions cannot be used inside regex interpolation?
I think so. (The error message is perhaps LTA.) Junctions are a feature of the main P6 language. It seems reasonable that the pattern matching DSL doesn't support them.
The work-around I have is
say "12345" ~~ m/ <{ (2,3,4).join("||") }> / 「2」
If you join with a doubled pipe (||
) then you get the first token that matches rather than the longest:
say 'bartoo' ~~ / <{'bar || bartoo || baragain'}> /; # 「bar」
say 'bartoo' ~~ / ||@list /; # 「bar」
say 'bartoo' ~~ / ||<{<bar bartoo baragain>}> /; # 「bar」
Not specifying the pipe symbol for these constructs is the same as specifying a single pipe symbol (|
) and matches the longest matching token:
say 'bartoo' ~~ / <{'bar | bartoo | baragain'}> /; # 「bartoo」
say 'bartoo' ~~ / |@list /; # 「bartoo」
say 'bartoo' ~~ / |<{<bar bartoo baragain>}> /; # 「bartoo」
You've asked related questions before. I'll add links to a couple of them here for convenience:
Upvotes: 10
Reputation: 2341
Clarifying for persons seeking info on Junctions and Regexes:
If you want to test a list of values as regexes, use a List or Array:
% raku
Welcome to Rakudo™ v2023.05.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2023.05.
To exit type 'exit' or '^D'
[0] > my @options = <a b>;
[a b]
[1] > say ("a" ~~ / @options /).so;
True
[1] > say so "a" ~~ / @options /;
True
[1] > say "a" ~~ / @options /;
「a」
You can create a junction, but placing it inside a Regex Matcher is problematic:
[2] > my $junction = any(@options);
any(a, b)
[2] > say "a" ~~ $junction;
True
[2] > say "a" ~~ /$junction/;
This type cannot unbox to a native string: P6opaque, Junction
If you want a True/False answer, create a Junction outside your Regex matcher:
[3] > say "a" ~~ any / @options /;
True
[3] > say "z" ~~ any / @options /;
False
[3] > say "z" ~~ none / @options /;
True
HTH.
Upvotes: 0