Thanks for the ideas. The core issue I'm probing is runtime construction of
character classes, with an eye towards opening a documentation issue, or
maybe even an issue against the character class implementation.
Simon's workaround m:g/<{$chars.comb}>+/ is interesting, interpolating a
list which turns into alternation - but it isn't a character class. Bill's
proposal with intersecting sets - via a junction, though ∩ aka (&) also
ought to work - is short and clear, but solves a different problem.
Paul's suggestion should create a character class, but my test doesn't work:
#!/usr/bin/env perl6
use v6;
sub matching_chars(Str $chars_to_match, Str $_) {
print "Looking for $chars_to_match in '$_'- ";
my regex x { $chars_to_match ** 1 };
m/<[<x>]>/;
}
say matching_chars('24680', '19584203');
say matching_chars('24680', '24680x');
$ ./*match.p6*
Looking for 24680 in '19584203'- Nil
Looking for 24680 in '24680x'- 「x」
Paul, can you post a more complete working test?
The below works but is "ugly", building up the character class syntax as a
string and then evaluating it
sub matching_chars(Str $chars_to_match, Str $_) {
print "Looking for $chars_to_match in '$_'- ";
m/<{ # Interpolate contents as a regex
"<[" ~ # Open the character class
# Add the char list, with closing bracket backslashed
$chars_to_match.subst(']','\]' ,:g) ~
"]>" # Close the character class
}>+/; # End interpolation, plus sign for one-or-more
}
say matching_chars('24680', '19584203'); # matches 8420
say matching_chars('+/][', 'Apple ][+//e'); # matches ][+//
I see this as a shortcoming in the character class implementation.
Specifically the "literal" vs "metacharacter" distinction
<http://docs.perl6.org/language/regexes#Literals_and_metacharacters> goes
out the window with enumerated character classes, it behaves like a
single-quoting. I want all the different interpolation goodness
<http://docs.perl6.org/language/regexes#Regex_interpolation> to work with
character classes, and it seems that requires a new syntax.
-y
On Sun, Sep 1, 2019 at 9:59 AM Simon Proctor <[email protected]>
wrote:
> Using a set would be good but it doesn't give you the matching string from
> the original (which is what I thought was required) otherwise Sets would be
> my first thought.
>
> On Sun, 1 Sep 2019, 17:57 William Michels, <[email protected]> wrote:
>
>> Hi Yary and Paul and Simon,
>>
>> I ran into the same difficulties as Yary with repeated characters, so
>> I tried the .unique method. Then after a while, I realized that
>> problems like this might best be treated as "Set" problems in Perl6.
>> Note the Set Intersection operator "(&)" below:
>>
>> sub matching_chars(Str $a, Str $b) {
>> my @c = $a.comb.unique;
>> my @d = $b.comb.unique;
>> #say @c; say @d;
>> return @c (&) @d;
>> }
>>
>> say matching_chars("24680", "19584203"); #RETURNS set(0 2 4 8)
>> say matching_chars('+\/\]\[', 'Apple ][+//e'); #RETURNS set(+ / [ ])
>>
>>
>> https://docs.perl6.org/routine/Set
>> https://docs.perl6.org/language/operators#infix_(&),_infix_∩
>>
>> HTH, Bill.
>>
>>
>> On Sat, Aug 31, 2019 at 8:59 PM Paul Procacci <[email protected]>
>> wrote:
>> >
>> > I'm not entirely sure if this is the correct answer, but if you define
>> your own custom character class
>> > with a 'regex' object, you can use that in the grouping.
>> >
>> > sub matching_chars(Str $chars_to_match, Str $_) {
>> > my regex x { $chars_to_match ** 1 };
>> > m/<[<x>]>/;
>> > }
>> >
>> > The above worked for me in the very small testing I did.
>> >
>> > ~Paul
>> >
>> > On Sat, Aug 31, 2019 at 9:54 PM yary <[email protected]> wrote:
>> >>
>> >> I found something easy in Perl 5 that's puzzling me in Perl 6-
>> specifying a character class via a variable.
>> >>
>> >> Perl 5:
>> >> sub matching_chars {
>> >> (my $chars_to_match, local $_) = @_;
>> >> /([$chars_to_match]+)/
>> >> }
>> >>
>> >> say matching_chars('24680', '19584203'); # says 8420
>> >> say matching_chars('+\/\]\[', 'Apple ][+//e'); # says ][+//
>> >>
>> >> Perl 6:
>> >> sub matching_chars(Str $chars_to_match, Str $_) {
>> >> # warnings, treats as string not variable
>> >> m/<[$chars_to_match]>/;
>> >> }
>> >>
>> >> How do I get Perl 6 to interpret a variable in the contents of a
>> character class?
>> >> From http://docs.perl6.org/language/regexes#Regex_interpolation I'd
>> think that Rakudo would use the literal contents of $chars_to_match,
>> instead it's using the literal chars "$ c h a r s _ t o _ m a t c h" and
>> warning about repeated c, underscore, etc.
>> >>
>> >> -y
>> >
>> >
>> >
>> > --
>> > __________________
>> >
>> > :(){ :|:& };:
>>
>