Any questions involving matching text strings to patterns - the pattern is called a "regular expression."
Moderator: General Moderators
jayshields
DevNet Resident
Posts: 1912 Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England
Post
by jayshields » Fri Feb 10, 2006 10:40 am
Hi guys.
I suck with regex.
All i want to do is make sure the user input is a date. In this format: dd/mm/yy.
I don't want to use checkdate, because I'll have to explode on / and the user could be entering ds/sfds, which would give me some sort of error when i pass $var[2] to checkdate.
I just want the pattern to match number number slash number number slash number number.
My attempt:
It gives unknown modifier error for the slash, and I have tried \/ \\/ /\ [ /.] [/] etc etc. Existing date regex's I've seen don't support the format I want
Thanks for any help!
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Fri Feb 10, 2006 10:45 am
Code: Select all
$p = '#^\s*([0-9]{2})/([0-9]{2})/([0-9]{2})\s*$#';
preg_match($p,$string,$matches);should work fine.. You should send it through
mktime() or something as well though..
jayshields
DevNet Resident
Posts: 1912 Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England
Post
by jayshields » Fri Feb 10, 2006 11:11 am
Thanks feyd.
Could you/someone just explain to me what those extra characters do/mean? So I know for next time?
Thanks.
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Fri Feb 10, 2006 11:18 am
the stickies explain them.
raghavan20
DevNet Resident
Posts: 1451 Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:
Post
by raghavan20 » Fri Feb 10, 2006 11:59 am
but how about a date, "2/2/98" ???
pickle
Briney Mod
Posts: 6445 Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:
Post
by pickle » Fri Feb 10, 2006 12:18 pm
raghavan20 wrote: but how about a date, "2/2/98" ???
Although to be anal, ~jayshields did mention:
jayshields wrote: I just want the pattern to match number number slash number number slash number number.
Last edited by
pickle on Fri Feb 10, 2006 12:29 pm, edited 1 time in total.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
raghavan20
DevNet Resident
Posts: 1451 Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:
Post
by raghavan20 » Fri Feb 10, 2006 12:20 pm
pickle wrote: raghavan20 wrote: but how about a date, "2/2/98" ???
Although to be anal, ~jayshields did mention:
jayshields wrote: I just want the pattern to match number number slash number number slash number number.
I think you though of putting a + behind \d instead of *....he has to check ranges of days and month...
pickle
Briney Mod
Posts: 6445 Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:
Post
by pickle » Fri Feb 10, 2006 12:29 pm
Yep - my bad. Original post edited.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
raghavan20
DevNet Resident
Posts: 1451 Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:
Post
by raghavan20 » Fri Feb 10, 2006 1:07 pm
this may help...
Code: Select all
<pre>
<?php
error_reporting(E_ALL);
$inputString = "01/12/98";
echo preg_match("#[0-9]{2}[/-][0-9]{2}[/-][0-9]{2}#", $inputString);
$inputString = "01/1/98";
echo preg_match("#[0-9]{2}[/-][0-9]{2}[/-][0-9]{2}#", $inputString);
validateDate("01/1/98");
validateDate("13/13/98");
validateDate("29/02/98");
validateDate("31/11/98");
validateDate("30/12/98");
validateDate("29/2/04");
function validateDate($inputString){
$valid = FALSE;
$result = preg_match("#[0-9]{1,2}[/-][0-9]{1,2}[/-][0-9]{1,2}#", $inputString);
if ($result === 1){
list($day, $month, $year) = split ("[/-]", $inputString);
if ($month <= 12 && $month >= 1){
if ($month == 2){
$febDays = ($year%4 == 0)? 29: 28;
//DEBUG//echo "febDays - $febDays";
if ($day <= $febDays && $day >= 1) $valid = TRUE;
}else if ($month == 1 || $month == 3 || $month == 5 || $month == 7 || $month == 8 || $month == 10 || $month == 12){
if ($day <= 31 && $day >= 1) $valid = TRUE;
}else{
if ($day <= 30 && $day >= 1) $valid = TRUE;
}
}
}
echo "<br />". $day, $month, $year."-";
echo ($valid === TRUE)?"Valid ":"Invalid ". "date!!!";
}
?>
</pre>
EDIT: Output...
Code: Select all
10
01198-Valid
131398-Invalid date!!!
290298-Invalid date!!!
311198-Invalid date!!!
301298-Valid
29204-Valid
Last edited by
raghavan20 on Fri Feb 10, 2006 2:35 pm, edited 1 time in total.
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Fri Feb 10, 2006 1:31 pm
raghavan20:
split() uses ereg, which you should remember is slow. I'd suggest using preg_split();
your leap year determination is..buggy.
Code: Select all
(($year % 4) == 0 and ($year % 100) != 0) || (($year % 400) == 0 and ($year % 4000) != 0)is far more accurate.
A month cannot be 1, 3, 5, etc at the same time. Switch the && to ||. Or better yet, use a switch statement for the month length culling.
raghavan20
DevNet Resident
Posts: 1451 Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:
Post
by raghavan20 » Fri Feb 10, 2006 1:39 pm
feyd wrote: raghavan20:
split() uses ereg, which you should remember is slow. I'd suggest using preg_split();
your leap year determination is..buggy.
Code: Select all
(($year % 4) == 0 and ($year % 100) != 0) || (($year % 400) == 0 and ($year % 4000) != 0)is far more accurate.
A month cannot be 1, 3, 5, etc at the same time. Switch the && to ||. Or better yet, use a switch statement for the month length culling.
thanks for that extra information on split...
i know that was not the perfect way to calculate the leap year,,,but I expected him to make it better..
that if condition...i somehow wrongly typed it...sorry..