RegexCheatSheet.pm: adding support for simple character classes like "regex [1-6]" etc

master
Rob Emery 2013-11-09 22:42:21 +00:00
parent 9cefa77e70
commit 3e6e76243c
2 changed files with 106 additions and 60 deletions

View File

@ -151,14 +151,49 @@ our %syntax_map = (
'$&' => 'Entire matched string',
);
sub are_same_case($$) {
my ($a, $b) = @_;
my $both_uc = $a eq uc($a) && $b eq uc($b);
my $both_lc = $a eq lc($a) && $b eq lc($b);
return ($both_uc || $both_lc);
}
sub are_valid_char_classes($$) {
my ($a, $b) = @_;
# must be both numbers or both lowercase or both uppercase
if ($a =~ /[0-9]/ && $b =~ /[0-9]/ || $a =~ /[a-z]/ && $b =~ /[a-z]/ || $a =~ /[A-Z]/ && $b =~ /[A-Z]/) {
return $b gt $a;
}
return;
}
sub difference_between($$) {
my ($a, $b) = @_;
return ord($b) - ord($a);
}
handle remainder => sub {
# If the user has requested information on a specific pattern.
if (length $_ > 0) {
my $syntax_key = $_;
# Let the user provide [a-e], [1-2], nice simple examples only!
if ($_ =~ /\[([a-zA-Z0-9])\-([a-zA-Z0-9])\]/) {
return unless are_same_case($1, $2) && are_valid_char_classes($1, $2);
#if there are < 3 between them then output all between them, otherwise "0 or 1 .. or 9" style
my $range_string = "";
if (difference_between($1, $2) < 3) {
$range_string = join(" or ", ($1..$2));
}
else {
$range_string = join(" or ", ($1..$2)[0,1]) . " ... or $2";
}
return answer => "$_ - Single character range ($range_string)",
html => "<code> $_ </code> - Single character range ($range_string)";
}
# Let the user provide a number for the {n} pattern, e.g., {5} would say "Exactly 5 occurrences".
if ($_ =~ /\{([0-9]+)\}/) {
elsif ($_ =~ /\{([0-9]+)\}/) {
return answer => "$_ - Exactly $1 occurrences",
html => "<code>" . encode_entities($_) . "</code> - Exactly " . encode_entities($_) . " occurrences";
}
@ -218,7 +253,6 @@ handle remainder => sub {
$text_output .= "\n";
$new_table .= "</table>\n";
$html_columns[$column] .= $new_table;
}
}

View File

@ -29,7 +29,19 @@ ddg_goodie_test(
'regexp \s' => test_zci(
'\s - Whitespace',
html => '<code> \s </code> - Whitespace'
)
),
'regular expression [a-e]' => test_zci(
'[a-e] - Single character range (a or b ... or e)',
html => '<code> [a-e] </code> - Single character range (a or b ... or e)'
),
'regular expression [M-Y]' => test_zci(
'[M-Y] - Single character range (M or N ... or Y)',
html => '<code> [M-Y] </code> - Single character range (M or N ... or Y)'
),
'regex [1-2]' => test_zci(
'[1-2] - Single character range (1 or 2)',
html => '<code> [1-2] </code> - Single character range (1 or 2)'
),
);
done_testing;