PDA

View Full Version : regex assistance please


bazz
07-21-2008, 05:28 PM
Hi,

The following regex is to allow only - , and \d

I need to stop injections and errroneous content being submitted


unless ( $room_number =~ /^(\d)(-)(,)+$/ ) # make this allow ,-d


I'm trying to find it out in O'Reilly but am in a rush for this one.

bazz

oesxyl
07-21-2008, 06:58 PM
Hi,

The following regex is to allow only - , and \d

I need to stop injections and errroneous content being submitted


unless ( $room_number =~ /^(\d)(-)(,)+$/ ) # make this allow ,-d


I'm trying to find it out in O'Reilly but am in a rush for this one.

bazz

if $room_number must be numeric only you can use /^(\d+)$/
that's enought to stop any attempt.

about the action now. you have to option:
1. check and if is true do what you need:


if($room_number =~ /^(\d+)$/){
# put your code here
}
exit; # this will stop any action


2. check and if is false exit


exit if $room_number !~ /^(\d+)$/;

# your code here


I don't know if one is better or safer then other but I like second. :)

regards

FishMonger
07-21-2008, 07:01 PM
Try:unless ( $room_number =~ /^[\d,-]+$/ )

bazz
07-21-2008, 07:02 PM
Thanks oesxyl but the room number can be numemric and contain - and ,

It is for inputting a number of rooms at once using an array of 1-4,8-10,15-20

So it needs to do more than allow \d.

bazz

bazz
07-21-2008, 07:05 PM
Ah, nearly missed your post FishMonger.

Thank you very much.

bazz

oesxyl
07-21-2008, 07:08 PM
Thanks oesxyl but the room number can be numemric and contain - and ,

It is for inputting a number of rooms at once using an array of 1-4,8-10,15-20

So it needs to do more than allow \d.

bazz
is my fault, :),
FishMonger regex is what you need, :)

but I'm not sure about using unless, because will loop, this is what you want?
I guess FishMonger will agree with me here, or not?

regards

FishMonger
07-21-2008, 07:10 PM
If you want to be more explicit, you could try (untested):

/^(\d+-\d+,?)+$/

FishMonger
07-21-2008, 07:18 PM
but I'm not sure about using unless, because will loop, this is what you want?



No, unless( ) { } is not a loop construct, it's a conditional test just link if( ) { } but uses the opposite logic.

The loop controls are:

for
foreach
until
while
do..while
do..untill

oesxyl
07-21-2008, 07:19 PM
If you want to be more explicit, you could try (untested):

/^(\d+-\d+,?)+$/
this make me think that maybe bazz want to extract the values in the same time with checking, probably this is the reason for unless and multiple ().

bazz can make clear this, :)

regards

KevinADC
07-21-2008, 07:56 PM
if it were me I would use Fishmongers first regexp as the initial check but I would also check to make sure the specific format (1-2,3-4,etc) is also valid, otherwise people can enter stuff like:

------- or ,,,,,,,,, and the script will allow it.

To allow for minor mistakes in the field I might do something like this (untested):

my $room_nums = param('room_nums') or error('No room number entered');
$room_nums =~ tr/ //d; #remove spaces
$room_nums =~ tr/-,//s; #collapse repeated instances of - and , into one
($room_nums =~ /^[\d,-]+$/) or error('Invalid entry');# initial check to weed out junk
my @rooms = split(/,/,$room_nums,-1);
foreach my $room (@rooms) {
if ($room =~ /^\d+\-\d+$/) {
its good so save it for processing
}
else {
its bad so do something
}
}

bazz
07-21-2008, 07:58 PM
awwww, I think I am over-complicating it again. :(

here's the first part of the code in the script which receives the form data.


my $room_number = $query->param('room_number');

unless ( $room_number =~ /^[\d,-]+$/) # allow -,\d
{
push(@error_count, 'Wrong details entered for Room Number.');
}
else
{
@rooms_numbers = split(',',$room_number); # convert to array for the loop
}


Thie gives me an array like this

@rooms_numbers = 1 3 7-10

Now I need to loop through this to be able to get the numbers:

1,3,7,8,9,10

Surely there is an easier way than this below?


my @new_array;

foreach my $rooms_list (sort @rooms_numbers)
{


if ($rooms_list =~ m/\-/) # if the variable is a range of numbers
{
my @new_var = split('-', $rooms_list);
push (@new_array, @new_var);
}
else
{
push (@new_array, $rooms_list);
}
}

foreach my $room_number sort(@new_array)
{
print qq( rn=$room_number );


bazz

KevinADC
07-21-2008, 08:00 PM
See my post above, it might give you some ideas.

KevinADC
07-21-2008, 08:12 PM
I guess this part woul dneed to be changed:

foreach my $room (@rooms) {
if ($room =~ /^\d+\-\d+$/) {
its good so save it for processing
}
else {
its bad so do something
}
}

change to:

foreach my $room (@rooms) {
if ($room =~ /^\d+$/) {
its good so save it for processing
}
elsif ($room =~ /^(\d+)\-(\d+)$/) {
$room = join(',',$1..$2);
its good so save it for processing
}
else {
its bad so do something
}
}

bazz
07-21-2008, 08:17 PM
Thank you Kevin; that looks more sensible. (your first post)

I'll play about with that and see where it takes me

bazz