ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Is it possible to match a numeric pattern in using regex in perl? I want to print something if the variable my $a has a numeric value between 000 and 999? How do i do that,i cant seem to find a solution for that.
my $a=;
{
if ($a=~<in range 000-999> {
print "In range";
else {
print "Not in Allowed Range";
}
You can use Perl's grep function to test if something is included in a list, and the range is a kind of list. This is an indirect test, but it works. (In a nutshell, if the item isn't found in the list, grep will return false. So it can function as a pseudo-boolean here.)
So, something like this works, I believe:
Code:
#!/usr/bin/env perl
use strict;
use warnings;
print "Gimme a value: ";
chomp(my $a = <STDIN>);
if (grep { $a == $_ } (000..999)) {
print "In Range\n";
}
else {
print "Out of range\n";
}
Even smarter, however, is to use the first function from List::Util because grep will run through all the numbers no matter what, but first will bail out the moment it gets a hit. (E.g., if the included number is 001, grep keeps going, but first stops right away.)
Code:
#!/usr/bin/env perl
use strict;
use warnings;
use List::Util qw/first/;
print "Gimme a value: ";
chomp(my $a = <STDIN>);
if (first { $a == $_ } (000..999)) {
print "In Range\n";
}
else {
print "Out of range\n";
}
Last edited by Telemachos; 11-04-2009 at 01:06 PM.
Thanks telemachos,its working,but it doenst work when i write something like this
if (grep(/(000..999)/,$a))
Program gets executed for every value i input it says out of range.
Right, that doesn't work. It looks like you're trying to use a simpler syntax of grep where it does a default regular expression test, but a regular expression match won't work here.
Here's how grep works:
You give grep a block and a list. (There's also an alternative form where you use an expression and a list - which is what it looks like you were trying to do - but I think that the block form is better in general and better suited for this task. So I'm only going to talk about that form here. See perldoc -f grep for the full story.)
Perl takes goes through the items in the list, one at a time, setting $_ to each member of the list in turn.
Inside the block, you write some kind of test. It can be a regular expression match, but it can also be something else.
If the test comes out true for an item, that item is passed along by grep. If not, the item is not passed along.
In list context, grep returns the list of items that passed the test. In scalar context, grep returns the number of items that passed the test. (A good thing to keep in mind if you want to check how many items in a given array or hash match a certain criterion.)
I used grep in a conditional - a scalar context. In essence, grep will return 1 (if the number is in range) or 0 (if the number is not in range). 1 evaluates in Perl to true, so the if code is executed. 0 evaluates as false, so the else code is run.
But the way the test block works is that I test whether each item (aliased to $_ by Perl automatically) is equivalent to one of the items in the range. When grep finds a match, it returns 1. The test itself is not a regular expression, but a simple numeric equality test:
Code:
grep { $a == $_ } (000..999)
This checks is $a numerically equal to 001, 002, 003, 004 etc. I think this is the test you want, rather than a regular expression.
Thanks telemachos for the explanation :-), I used the grep function in my code and it works,but i am not sure if this is an efficient way of doing it. All i have to do is take input from user,and the input has to be of this standard ABC-XXX,Where ABC- will be a default entry for any put only the XXX (Which is an interger from 000 to 999) must vary,For Ex: ABC-001,ABC-100...etc
Code:
print "Enter ID number";
chomp ($Id=<STDIN>);
if ($Id) {
my @Arr = split('-',$Id)
if(($Arr[0] eq "ABC") and (grep{$Arr[1] == $_}(000..999)) {
print "ID Number Valid";
}
else {
print "Not Valid";
}
The Bad thing in the above code is am using 2 lines of code,along with split function and comparing the values using grep function,where i guess it can be done using a simpler regex. Thanks again for the help!!
The Bad thing in the above code is am using 2 lines of code,along with split function and comparing the values using grep function,where i guess it can be done using a simpler regex. Thanks again for the help!!
I hear what you're saying, and I hadn't realized that you count narrow in on a regex quite so much. (I was imagining a more complex situation.) Still, I got curious a wrote a simple benchmark script. The results are worth looking at:
Code:
#!/usr/bin/env perl
use strict;
use warnings;
use List::Util qw/first/;
use Benchmark qw(:all);
my $grep_way = sub {
my @caught;
while (<DATA>) {
my @fields = split('-', $_);
if (($fields[0] eq 'ABC') and (grep { $fields[1] == $_ }(000..999))) {
push @caught, $_;
}
}
};
my $first_way = sub {
my @caught;
while (<DATA>) {
my @fields = split('-', $_);
if (($fields[0] eq 'ABC') and (first { $fields[1] == $_ }(000..999))) {
push @caught, $_;
}
}
};
my $regex_way = sub {
my @caught;
while (<DATA>) {
if ($_ =~ m/^ABC-[0-9]{3}$/) {
push @caught, $_;
}
}
};
cmpthese(-15, {
'Grep:' => $grep_way,
'Regexp:' => $regex_way,
'First:' => $first_way,
});
__DATA__
ABC-010
BCC-999
ABC-1011
ABC-001
XCB-111
ABC-010
BCC-999
ABC-1011
ABC-001
XCB-111
ABC-010
BCC-999
ABC-1011
ABC-001
XCB-111
ABC-010
BCC-999
ABC-1011
ABC-001
XCB-111
ABC-010
BCC-999
ABC-1011
ABC-001
XCB-111
A regular expression here is quicker, but the difference is negligible. Unless you are doing hundreds of thousands of these computations, I would say go with whatever method makes more sense to you. Later, when you have to reread the code (or explain it to someone else), that will matter most.
Thanks you very much telemachos you have been of great help to me with your explanation and examples!! . I wanted to know one more thing,i coudlnt find any chapter regarding connecting to mysql Db in the system admin pdf i downloaded from the site you gave me perltraining.au,is there a seprate tutorial for that which i must download? Thanks again for that site!!
I wanted to know one more thing,i coudlnt find any chapter regarding connecting to mysql Db in the system admin pdf i downloaded from the site you gave me perltraining.au,is there a seprate tutorial for that which i must download? Thanks again for that site!!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.