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 "e;Enter postcode: "e;;
$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 "e;\nEnter U for uppercase or L for lowercase: "e;;
$case = <STDIN>;
trim;
if ($case == "e;u"e; || $case == "e;U"e;)
{
print uc($postcode)."e;\n"e;; #Why?
}
elsif ($case == "e;l"e; || $case == "e;L"e;)
{
print lc($postcode)."e;\n"e;;
}
else
{
print "e;You didn't enter U or L\n"e;;
}
}
else
{
print "e;That postcode isn't valid\n"e;;
}
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 "e;content-type: text/html\n\n"e;;
if ( $postcode =~ /\D{2}\d{1,2}\s\d\D{2}/ && $format eq "e;NS"e; || $format eq "e;ns"e;) {
$postcode =~ s/ //g;
print "e;$postcode\n"e;;
}
elsif ( $postcode =~ /\D{2}\d{1,2}\s*\d\D{2}/g && $format =~/U/) {
print "e;$up\n"e;;
}
elsif ( $postcode =~ /\D{2}\d{1,2}\s\d\D{2}/ || $format eq "e;SP"e; || $format eq "e;sp"e;) {
print "e;$lft $rgt\n"e;;
}
elsif ( $postcode =~ /\D{2}\d{1,2}\s*\d\D{2}/ && $format =~/L/) {
print "e;$down\n"e;;
}
elsif ( $postcode =~ /\D{2}\d{1,2}\s*\d\D{2}/ || $format =~/ /) {
print "e;$postcode\n"e;;
}
else
{
print "e;Invalid Data\n"e;;
}
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 "e;content-type: text/html\n\n"e;;
if ( $postcode =~ /їa-z]{2}\d{1,2}\s\dїa-z]{2}/i && lc($format) eq "e;ns"e;) {
$postcode =~ s/ //g;
print "e;$postcode\n"e;;
}
elsif ( $postcode =~ /їa-z]{2}\d{1,2}\s*\dїa-z]{2}/i && lc($format) eq "e;u"e;) {
print "e;$up\n"e;;
}
elsif ( $postcode =~ /їa-z]{2}\d{1,2}\s\dїa-z]{2}/i || lc($format) eq "e;sp"e;) {
print "e;$lft $rgt\n"e;;
}
elsif ( $postcode =~ /їa-z]{2}\d{1,2}\s*\dїa-z]{2}/i && lc($format) eq "e;l"e;) {
print "e;$down\n"e;;
}
elsif ( $postcode =~ /їa-z]{2}\d{1,2}\s*\dїa-z]{2}/i || $format =~/^$/) {
print "e;$postcode\n"e;;
}
else
{
print "e;Invalid Data\n"e;;
}
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)
use:
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
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
/^(їa-z]{2}\d{1,2})(\ *)(\dї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 =~ /їa-z]{2}\d{1,2}\s*\dїa-z]{2}/i && lc($format) eq "e;l"e;) {print "e;$down\n"e;;
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 = "e;BAR"e;;
if (lc($foo) eq "e;bar"e;) print $foo;
Saves doing:
Code: Select all
$foo = "e;BAR"e;;
if ($foo eq "e;BAR"e; || $foo eq "e;bar"e;) print $foo;