Page 1 of 1

Postcode help!

Posted: Thu Jul 28, 2005 12:50 pm
by samip1983
Hi all,

Im currently working on a piece of programming using perl, im using regex to manipulate incoming postcodes. Once entering the postcode a format is also used i.e. U for the postcode to be outputted as uppercase, and format=L for the output to be all lowercase. The problem is i am programming using if and ifels commands and it doesnt seem to work.

Any help would be great

rgds

Sami P

Posted: Thu Jul 28, 2005 12:55 pm
by timvw
*magic ball*

The problem is with you (and your code). Many people have used if-else before without any problem ;)

Meaby if you post some code, explain it what it does (or what it should do) and then we can help you...

Posted: Thu Jul 28, 2005 1:12 pm
by Chris Corbyn
CGI or command line? I don't really understand what you're asking and it's beeen a while since I wrote any perl (ifels? you mean elsif?)...

Code: Select all

#!/usr/bin/perl

print &quote;Enter postcode: &quote;;
$postcode = <STDIN>; #Take input from STDIN
trim;

if ($postcode =~ /їa-z]{1,2}\d{1,2}\s*\dїa-z]{2}/i) #That's UK postcode
{
    print &quote;\nEnter U for uppercase or L for lowercase: &quote;;
    $case = <STDIN>;
    trim;
    
    if ($case == &quote;u&quote; || $case == &quote;U&quote;)
    {
        print uc($postcode).&quote;\n&quote;; #Why?
    }
    elsif ($case == &quote;l&quote; || $case == &quote;L&quote;)
    {
        print lc($postcode).&quote;\n&quote;;
    }
    else
    {
        print &quote;You didn't enter U or L\n&quote;;
    }
}
else
{
    print &quote;That postcode isn't valid\n&quote;;
}
EDIT | Got bored, tested it and fixed the syntax errors ;)

Posted: Thu Jul 28, 2005 5:02 pm
by samip1983
Hi thanks for the replys,

So far i have got some bit working, U = uppercase L = lowercase SP = a space between the postcode, if it is entered together and NS = no space if the postcode is entered with a space.
Some of aspects work and some are just baffeling me in the way they are not working. An example being the if a post code is inputted with a space and the U format is entered in returns an invalid output??

Code: Select all

#!/usr/bin/perl
use strict;
use CGI ':standard';

my ($postcode, $format, $up, $down, $cut, $lft, $rgt, $rigt);

$postcode = param('postcode');
$format = param('format');

$up = param '';
$down = param '';

$up = uc($postcode);
$down= lc($postcode);
#$cut= chop($postcode);
$lft= substr($postcode, 0, 3);
$rgt= substr($postcode, 3, 4);
$rigt = substr($postcode, 3, 7);

print &quote;content-type: text/html\n\n&quote;;

if (  $postcode =~ /\D{2}\d{1,2}\s\d\D{2}/ && $format eq &quote;NS&quote; || $format eq &quote;ns&quote;) {
$postcode =~ s/ //g;

print &quote;$postcode\n&quote;; 

}

elsif ( $postcode =~ /\D{2}\d{1,2}\s*\d\D{2}/g && $format =~/U/) {
print &quote;$up\n&quote;;

}
elsif ( $postcode =~ /\D{2}\d{1,2}\s\d\D{2}/ || $format eq &quote;SP&quote; || $format eq &quote;sp&quote;) {
print &quote;$lft $rgt\n&quote;; 

}
elsif ( $postcode =~ /\D{2}\d{1,2}\s*\d\D{2}/ && $format =~/L/)  {
print &quote;$down\n&quote;;

}

elsif ( $postcode =~ /\D{2}\d{1,2}\s*\d\D{2}/ || $format =~/ /) {
print &quote;$postcode\n&quote;;


}
else
{

  print &quote;Invalid Data\n&quote;;
}
I was wondering if anyone knoew any simpler way to introduce the different formats rather than using the if and elsif beginnings?

any help would be appreciated

thanks

sami p

Posted: Thu Jul 28, 2005 6:00 pm
by Chris Corbyn
if..elsif..else makes perfect sense to me. I wouldnt change that. The only other way to *sometimes* do things like that is to use a switch() condition but that wont work here because of the conditions in each of your steps here.

<side note>
Thanks for reminiding me how nice a language perl is again.
(and that it's "eq" not "==" when dealing with string literals :))
</side note>

Your regex could certainly be improved however.... they will match a postcode yes but they dont represent the actual pattern a postcode takes (we are talking about UK postcodes I assume from looking at your code?).

Might be an idea to drop the

$format eq "NS" || $format eq "ns"

and replace it with

lc($format) eq "ns" ;)

Also, this could explain your problem with getting "Invalid input"...

$format =~/L/

It's case sensitive (and why do a perl re on a single character?)..


Try replacing it with:

lc($format) eq "l"

Code: Select all

#!/usr/bin/perl
use strict;
use CGI ':standard';
 
my ($postcode, $format, $up, $down, $cut, $lft, $rgt, $rigt);
 
$postcode = param('postcode');
$format = param('format');
 
$up = param '';
$down = param '';
 
$up = uc($postcode);
$down= lc($postcode);
#$cut= chop($postcode);
$lft= substr($postcode, 0, 3);
$rgt= substr($postcode, 3, 4);
$rigt = substr($postcode, 3, 7);
 
print &quote;content-type: text/html\n\n&quote;;
 
if (  $postcode =~ /&#1111;a-z]{2}\d{1,2}\s\d&#1111;a-z]{2}/i && lc($format) eq &quote;ns&quote;) {
$postcode =~ s/ //g;
 
print &quote;$postcode\n&quote;; 
 
}
 
elsif ( $postcode =~ /&#1111;a-z]{2}\d{1,2}\s*\d&#1111;a-z]{2}/i && lc($format) eq &quote;u&quote;) {
print &quote;$up\n&quote;;
 
}
elsif ( $postcode =~ /&#1111;a-z]{2}\d{1,2}\s\d&#1111;a-z]{2}/i || lc($format) eq &quote;sp&quote;) {
print &quote;$lft $rgt\n&quote;; 
 
}
elsif ( $postcode =~ /&#1111;a-z]{2}\d{1,2}\s*\d&#1111;a-z]{2}/i && lc($format) eq &quote;l&quote;)  {
print &quote;$down\n&quote;;
 
}
 
elsif ( $postcode =~ /&#1111;a-z]{2}\d{1,2}\s*\d&#1111;a-z]{2}/i || $format =~/^$/) {
print &quote;$postcode\n&quote;;
 
 
}
else
{
 
  print &quote;Invalid Data\n&quote;;
}
I can probably post a method that utilises regex a bit better though (backreferences rather than using substr() since you have the patterns available) ;)

Posted: Thu Jul 28, 2005 6:08 pm
by timvw
It has been ages since i've done some Perl, but i've been told the following ;)

Instead of using (show warnings)

Code: Select all

#!/bin/perl -w
use:

Code: Select all

#!/bin/perl

use warnings;

Posted: Thu Jul 28, 2005 6:14 pm
by Chris Corbyn
Ignore my statement about using a swicth too... it doesnt appear to work in perl lol...

You got me playing with it now :P

Same here timvw... I think i last touched it 3 years ago... best way to learn regex though ;)

TIP: Add ^ and $ to the start and end of your patterns... you're letting invalid data in at the start and end the way you have it ;)

Code: Select all

/^(&#1111;a-z]{2}\d{1,2})(\ *)(\d&#1111;a-z]{2})$/i
Notice I added the parens... you can get everything out of those rather than using substr() ;)

Posted: Thu Jul 28, 2005 6:17 pm
by timvw
perl5.8 seems to support switch ;)

http://perl.active-venture.com/lib/Switch.html (woow, the first version i used was 4.x)

Posted: Thu Jul 28, 2005 6:20 pm
by Chris Corbyn
Ah I have 5.8.5, the syntax must be different to what I thought cheers... i'll have a read up.

samip1983 unless your query is specifically over the regex then we dont really deal with perl (although you got me started now :))...

EDIT | Yes the syntax is not like that of PHP switch()... needs curlies { } and no colon : :)

Posted: Fri Jul 29, 2005 4:20 am
by samip1983
Thanks for all your replys, at work at the moment so ill have a play with iut later......hopefully get it working, the main think thats annoying me is the spacing once ns or sp is entered as a format. it only works when there is a postcode like cv16sy, but doest work if the postcode is like cv116sy.

But i think the change in regex has made a difference, thanks.

cheers.....

Posted: Fri Jul 29, 2005 5:50 am
by timvw
That is because you only accept 1 or 2 numbers.. \d{1,2}

If you want to allow 1-2 or 3 make that \d{1,3}

Posted: Fri Jul 29, 2005 6:39 am
by Chris Corbyn
timvw wrote:That is because you only accept 1 or 2 numbers.. \d{1,2}

If you want to allow 1-2 or 3 make that \d{1,3}
Adding parens like I did should seperate them out anyway (then you can access the LHS and RHS using the backreferences $1 and $2 and $3)...

Posted: Fri Jul 29, 2005 7:26 am
by samip1983
Hi,

i wasnt aware you could access the postcode using lhs and rhs, this might be easier to use the spacing formats ns-no space sp-space.

i was wondering using the code below

Code: Select all

elsif ( $postcode =~ /&#1111;a-z]{2}\d{1,2}\s*\d&#1111;a-z]{2}/i && lc($format) eq &quote;l&quote;)  {print &quote;$down\n&quote;;
why is there lc before the format, i know it means lower case but i need the case depending on what format the user enters.

thanks guys

Posted: Fri Jul 29, 2005 8:04 am
by Chris Corbyn
Well it's lowercase of whatever the user enters comparing against lowercase "l" or "u"... so if upper or lowercase L or U is typed then it still matches.

for example:

Code: Select all

$foo = &quote;BAR&quote;;

if (lc($foo) eq &quote;bar&quote;) print $foo;
Saves doing:

Code: Select all

$foo = &quote;BAR&quote;;

if ($foo eq &quote;BAR&quote; || $foo eq &quote;bar&quote;) print $foo;