Erosia has asked for the wisdom of the Perl Monks concerning the following question:

Good afternoon,

I have a very simple question to which I seek answers:

use warnings; open FILE, "Testus.txt" or die "Couldn't open file."; while (<FILE>) { print "$_ \n" for /^(\d+\.\d+\t\d+\.\d+)/ };

That is my RegEx which matches strings like 234.555 "tab" 43.235 etc.

However, now I want one of the \d+ (the 3rd one of the 4) to only match numbers which are above 50 and below 250. How do I modify a \d+ to only match a certain value of numbers? Thanks alot

Replies are listed 'Best First'.
Re: How to modify \d in RegEx
by kennethk (Abbot) on Apr 07, 2010 at 14:21 UTC
    I can come up with three possible solutions to your issue. First, you could capture the number and then test it:

    if (/^(\d+\.\d+\t(\d+)\.\d+)/ and $2 > 50 and $2 < 250) {

    Second, rather than simply using \d+, you could use a series of character classes linked together with alternators:

    /^(\d+\.\d+\t(?:5[1-9]|[6-9]\d|1\d{2}|2[0-4]\d|250)\.\d+)/

    Lastly, you could incorporate Perl code into your regular expression, as described in A bit of magic: executing Perl code in a regular expression. Reading material is available on all these options in perlretut. Frankly, the first option is going to be the most clear when you look at your code again next year.

Re: How to modify \d in RegEx
by SuicideJunkie (Vicar) on Apr 07, 2010 at 14:27 UTC

    Before getting to the question, a comment: \d is probably not matching what you expect... it does indeed match [0-9], but also matches a whole lot more, and that could cause problems later.

    Building a vanilla regex to match 50 - 250 is quite wordy. (Starts with a 5, 6, 7, 8 or 9 plus one more digit, or starts with a 1 with two more digits, or starts with a two followed by 0, 1, 2, 3, or 4 plus one more digit, or exactly 250)

    The simplest way might be to capture up to three digits, and then do a next unless ($3 > 50 && $3 < 250) after you've found a candidate.

Re: How to modify \d in RegEx
by JavaFan (Canon) on Apr 07, 2010 at 14:42 UTC
    A simple way:
    my @numbers = (51 .. 249); while (<FILE>) { local $" = "|"; print "$_\n" for /^([0-9]+\.[0-9]+\t(?:@numbers)\.[0-9]+)/ }
Re: How to modify \d in RegEx
by Anonymous Monk on Apr 07, 2010 at 14:21 UTC
    perl -MRegex::PreSuf -le"print presuf( 51 .. 249 )"
    my $range51to249 = qr!(?:1(?:0[0123456789]|1[0123456789]|2[0123456789] +|3[0123456789]|4[0123456789]|5[0123456789]|6[0123456789]|7[0123456789 +]|8[0123456789]|9[0123456789])|2(?:0[0123456789]|1[0123456789]|2[0123 +456789]|3[0123456789]|4[0123456789])|5[123456789]|6[0123456789]|7[012 +3456789]|8[0123456789]|9[0123456789])!; /^(\d+\.\d+\t$range51to249\.\d+)/
Re: How to modify \d in RegEx
by nvivek (Vicar) on Apr 08, 2010 at 04:48 UTC
    You try this,
    use warnings; open FILE, "Testus.txt" or die "Couldn't open file."; while (<FILE>) { print "$_ \n" if(/^(\d+\.\d+\t(\d+)\.\d+)/ and grep { +$2} (41 .. 249)};
    First match will check for digit,followed by period,then digit,then tab and finally digit in a line and second grep will check the third digit in the match is greater than 40 and less than 250.