NAME
Number::Range::Regex - create regular expressions that check for integers in a given range
SYNOPSIS
use Number::Range::Regex;
my $lt_20 = range( 0, 19 );
my $lt_20_re = $lt_20->regex();
print "your stuff contains an integer < 20" if $jibberish =~ /$lt_20_re/;
print "your stuff is an integer < 20" if $jibberish =~ /$^lt_20_re$/;
if( $line =~ /^\S+\s+$lt_20_re\s/ ) {
print "the second field is an integer < 20";
}
my $nice_numbers = rangespec( "42,175..192" );
my $special_values_re = $lt_20->union( $nice_numbers )->regex;
if( $line =~ /^\S+\s+$special_values_re\s/ ) {
print "the second field has a special value";
}
my $lt_10 = range( 0, 9 );
my $primes_lt_30 = rangespec( "2,3,5,7,11,13,17,19,23,29" );
my $primes_lt_10 = $lt_10->intersection( $primes_lt_30 );
my $primes_lt_10_re = $primes_lt_10->regex;
my $nonprimes_lt_10 = $lt_10->minus( $primes_lt_30 );
print "nonprimes under 10 contains: ".join",", $nonprimes_lt_10->to_string;
my $nonprimes_lt_10_re = $nonprimes_lt_10->regex;
if( $something =~ /^$nonprimes_lt_10_re$/ ) {
print "something($something) is a nonprime less than 10";
}
if( $nonprimes_lt_10->contains( $something ) ) {
print "something($something) is a nonprime less than 10";
}
my $octet = range(0, 255)->regex;
my $ip4_match = qr/^$octet\.$octet\.$octet\.$octet$/;
my $re_96_to_127 = range(96, 127)->regex;
my $my_slash26_match = qr/^192\.168\.42\.$re_96_to_127$/;
my $my_slash19_match = qr/^192\.168\.$re_96_to_127\.$octet$/;
my $in_a_or_in_b_but_not_both = $a->xor($b);
my $it = $range->iterator();
$it->first;
do { print $it->fetch } while ($it->next);
$it->last;
do { print $it->fetch } while ($it->prev);
DESCRIPTION
which is more legible - this?
$date =~ m/^0*(?:[1-9]|[12][0-9]|3[01])\/0*(?:[0-9]|1[012])$/;
or this?
my $day_range = range(1, 31)->regex();
my $month_range = range(1, 12)->regex();
$date =~ m/^$day_range\/$month_range$/;
(bonus points if you spotted the bug)
NOTES
It's usually better to check for number-ness only in the regular expression and verify the range of the number separately, eg: $line =~ /^\S+\s+(\d+)/ && $1 > 15 && $1 < 32; but it's not always practical to refactor in that way.
If you like one-liners, something like the following may suit you... m{^${\( range(1, 31)->regex )}\/${\( range(1, 12)->regex )}$} but, for readability's sake, please don't do that!
NOTES
Non-negative integers only for now.
BUGS AND LIMITATIONS
Please report any bugs or feature requests through the web interface at http://rt.cpan.org.
AUTHOR
Brian Szymanski <ski-cpan@allafrica.com> -- be sure to put Number::Range::Regex in the subject line if you want me to read your message.
SEE ALSO
perl(1), Number::Range, etc.