views:

60

answers:

5

Hello everyone,

I am trying to match a date in PHP using preg_match, split it and assign parts of it to an array, the date looks like "20100930", here is the code I am using:

// Make the tor_from date look nicer
$nice_from = $_POST['tor_from'];

$matches = array();
$ideal_from = '';
preg_match('/\d{4}\\d{2}\\d{2}\/', $nice_from, $matches, PREG_OFFSET_CAPTURE, 0);
// if (isset($matches[0])) $nice_from = $matches[0];
echo $matches[0];
echo "<br />";
echo $matches[1];
echo "<br />";
echo $matches[2];
echo "<br />";
echo $matches[3];
echo "<br />";

Ive been using: http://php.net/manual/en/function.preg-match.php and http://stackoverflow.com/questions/1179165/php-preg-match-question to formulate ideas on how to do this, however I have had no luck in getting it to work. Any help would be greatly appreciated.

A: 

You need to put some parenthesis around the patterns that you would like to show up in $matches. Also i don't think you want the double \\ in between your \d's because that will escape the second \ and leave you matching a literal 'd'.

Kevin
+3  A: 

Although regex isn't really a good solution for parsing a date in YYYYMMDD format, let's walk through why your pattern isn't working.

Your pattern \d{4}\\d{2}\\d{2}\ says: "match 4 digits (\d{4}), followed by a backslash character (\\), followed by the letter d twice (d{2}), followed by another backslash (\\) and then finally another two d's (d{2})."

As you might have figure out by now, you don't want the double slashes!

\d{4}\d{2}\d{2}

Will match 4 digits, followed by 2 digits, and then another 2 digits.

Furthermore, you are not specifying any capturing groups, so your subpatterns will never be filled. What you probably meant was:

(\d{4})(\d{2})(\d{2})

See this in action at http://www.ideone.com/iAy7K. Note that there really isn't any reason in your case to be specifying the PREG_OFFSET_CAPTURE flag (which returns the position of each match) or 0 for the offset.

Daniel Vandersluis
+2  A: 

Regex is not the best way to go here if the pattern is this simple. Use substr instead:

$date = '20100930';
$year = substr($date,0,4);
$month = substr($date,4,2);
$day = substr($date,6,2);
lonesomeday
Thank you! This worked really well and was simple for someone like me to understand!
imbadatjquery
+2  A: 

Forget preg_match, use strtotime():

echo date('Y/m/d', strtotime($_POST['tor_from']));
Alex Howansky
+1 strtotime regularly amazes me with what it will accept. This solution is less helpful, however, if you want the parts separately...
lonesomeday
Just assign the output of strtotime to a variable, then you can use date('Y', $date) to get year, date('m', $date) to get month, etc.
Alex Howansky
@Alex that's a lot of processing just to split a string into three parts...
Daniel Vandersluis
If the input is from a trusted source and you're 100% certain that it will never deviate from the YYYYMMDD format, then sure, a substring match is fine. Also, it seems to me that from the sample code, the only purpose of splitting the string up is to just put it back together again in a prettier format. I.e., it seems there's no need to split it, but to "pretty" it.
Alex Howansky
+1  A: 

It's better like this, using preg_match and indexed names.

$res = preg_match("/(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})/", $date, $matches);

And Matches will look like:,

array('year' => 2010, 'month' => 12, 'day' => 07);

Cheers.

flaab