sub template_to_regexp { my($template) = @_; my $seen_count; my %seen_at; my $regexp = ''; for my $i (0 .. length($template) - 1) { my $chr = substr($template, $i, 1); my $seen = $seen_at{$chr}; if (defined $seen) { $regexp .= "\\$seen"; next; } # else it's a new template character $regexp .= sprintf '(?!%s)', join '|', map "\\$_", 1 .. $seen_count if $seen_count; $seen_at{$chr} = ++$seen_count; $regexp .= '(.)'; } return qr{$regexp}; }