in reply to Nonrepeating characters in an RE

G'day BernieC,

I considered a solution using List::Util::uniqstr(). Unfortunately, your OP is somewhat ambiguous: you first say 'the *template* that says "these letters should be distinct"'; then you say 'my "template" might look like this: "abcdefa"' (where, with two 'a's, the letters are not distinct). I've provided two solutions; hopefully, one of them does what you want.

[Caveat: uniqstr first appeared in List::Util v1.45; the first stable Perl version with that version of List::Util is v5.26; if you have an older version of Perl, you can get a newer version of List::Util from CPAN.]

Solution 1 (pm_11146148_uniq_str_chars.pl):

#!/usr/bin/env perl use strict; use warnings; use List::Util 1.45 'uniqstr'; use Test::More; my @tests = ( [abcdefa => 0], [abcdef => 1], [xyz => 1], [zzz => 0], ); plan tests => 0+@tests; for my $test (@tests) { my ($str, $exp) = @$test; is length($str) == uniqstr(split //, $str), !!$exp; }

Output:

$ ./pm_11146148_uniq_str_chars.pl 1..4 ok 1 ok 2 ok 3 ok 4

Solution 2 (pm_11146148_uniq_str_chars_2.pl):

#!/usr/bin/env perl use strict; use warnings; use List::Util 1.45 'uniqstr'; use Test::More; my @tests = ( ['abc', abcdefa => 0], ['def', abcdefa => 1], ['abc', abcdef => 1], ['xyz', xyz => 1], ['xyz', zzz => 0], ['xy', zzz => 1], ); plan tests => 0+@tests; for my $test (@tests) { my ($tmpl, $str, $exp) = @$test; my %tmpls = map +($_ => 1), split //, $tmpl; my @chars = split //, $str; my @tmpl_chars = grep exists $tmpls{$_}, @chars; is 0+@tmpl_chars == uniqstr(@tmpl_chars), !!$exp; }

Output:

$ ./pm_11146148_uniq_str_chars_2.pl 1..6 ok 1 ok 2 ok 3 ok 4 ok 5 ok 6

— Ken