Jump to content

Recommended Posts

Hi lovelycesar,

 

For speed, I adapted the core expression from the RegexBuddy library, then added some code.

Displaying all the pieces for you, just take those you need:

 

Input:

is there a date like 07/03/12 or 31/12/2008 in here?

 

Code:

<?php
$regex=',(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/((?:19|20)?[0-9]{2}),';
$string='is there a date like 07/03/12 or 31/12/2008 in here?';
$size=preg_match_all($regex, $string, $m);
for ($i=0;$i<$size;$i++) {
echo "Date # ".($i+1).": ".$m[0][$i]."<br />";
echo "Day / Match # ".($i+1).": ".$m[1][$i]."<br />";
echo "Month / Match # ".($i+1).": ".$m[2][$i]."<br />";
echo "Year / Match # ".($i+1).": ".$m[3][$i]."<br />";
}
?>

 

Output:

Date # 1: 07/03/12

Day / Match # 1: 07

Month / Match # 1: 03

Year / Match # 1: 12

Date # 2: 31/12/2008

Day / Match # 2: 31

Month / Match # 2: 12

Year / Match # 2: 2008

 

Note that this is NOT a date validator: for instance, it will match 31 November, even though November only has 30 days.

Let me know if this is what you are looking for and if you have any questions!

:)

 

You are right, regex cannot tell whether the date is valid or not, and since it cannot do that, there's no point in doing even most of what you did, because you will have to validate it by some other means anyways.  So all you really *need* is something like this:

 

~[0-9]+/[0-9]+/[0-9]+~

Hi .josh,

 

Truly nice to hear from you, I enjoy your posts a lot.

 

you use commas for pattern delimiters? eww ... that makes for unnecessary escaping

Thankfully not, because I tend to use delimiters that don't need escaping, depending on the expression within. Usually either commas, tildes or hashes. As you know, whichever delimiter you choose, it may need escaping sometimes. Commas are part of the syntax, so they certainly need escaping more often than tildes.

 

On an esthetic level I like commas a lot, as they let the regex stand out like a building over the horizon. I like tildes a lot too. Hashes are a bit blocky for my taste. To me #Hashes# feel like SHOUTING. And slashes tend to degenerate into wiggle art. \/\/

 

there's no point in doing even most of what you did

I don't want to get into an argument with you, but "no point" seems a bit strong.

The expression does get us in the ballpark of something that is very close to a date, except for odd cases like 31/11.

 

IMO, whether this is helpful is not, neither of us can judge. It's for the OP to say, depending on his needs. Not knowing his exact needs, I made something that seemed close to his question, offering to help if that was not what he was looking for. What you offered could be exactly what he needs, I cannot say.

 

For instance, he could be looking at input where he knows that all strings of the xx/xx/xx format are dates perfectly formed on a dd/mm/yy pattern, so that we don't need to validate anything, and your solution is perfect. Or he could have a mixture of perfectly formed dates (again no validation needed) but in a variety of formats, such as mm/dd/yy, dd/mm/yy and dd/mm/yyyy, and be looking for a way to fish out the two formats he indicated in the post.

 

Another note: in my experience, imperfect, "best guess" matching is often a reality when you look at long texts. For instance is 07/01/12 January 7, or July first? You have probably noticed that the board gets loads of requests to match an email address. And none of the email address checkers can truly ensure that you have a valid email address. Knowing this, should we just look for (stuff)@(stuff)? Or try to get in the ballpark? That depends on the what we know about the input and the on needs of the user.

 

I'm certainly not attached the expression, I never am---always delighted to see someone coming up with something better or pointing out potential improvements. And this is one of the rare cases when I didn't even craft a regex from scratch (I tweaked something out of the RB library), so I don't have a strong feel for the "balance" of the expression---how it would feel in the hand if it were a hammer.

 

Btw, did you notice that I used your benchmark() function on a recent post? Love it, thanks for that. I used to do my own home-made benchmarking in a way that wasn't nearly so elegant.

 

Sorry for the long message, I just love talking about regex! Not faulting your expression in any way, just a little chat about shades of grey.

 

Wishing you a fun day.

 

I'm certainly not attached the expression . . .

 

Yet you felt the need to write a couple paragraphs to defend it? jk

 

But, I agree with josh. The difficulty in trying to craft a RegEx to find "valid" dates is not worth the effort. Simply use the regex to pull "possible" date matches and then validate that they are valid using some other means, e.g. checkdate()

 

Besides, by trying to inject validation into the expression it is actually modifying invalid inputs into valid inputs. If a user wanted to enter a date of 2/3/2011 and accidentally entered 2/3/20011, the RegEx you provided would not capture the last '1' and would find a "valid" date of 2/3/2001. The same problem exists with the beginning of the matches.

 

Following josh's method, just capture any possible matches THEN use a proper method to validate the matches.

 

Building upon josh's expression, I made two changes. 1) I used \d instead of 0-9 and 2) I captured the month, day, year parts as separate values expressly for the purpose of running them through checkdate()

//Find possible matches
preg_match_all("#([\d]+)/([\d]+)/([\d]+)#", $INPUT, $matches, PREG_SET_ORDER);

//Find matches that are VALID dates and put into array
$valid_dates = array(); //Array to hold all valid dates
foreach($matches as $match)
{
    if(checkdate ($match[1], $match[2], $match[3]))
    {
        //Save the date to the array of valid dates.
        //Can convert to timestamp or specific format as needed
        $valid_dates[] = $match[0];
    }
}

 

Also, if you wanted to also allow dates that use a dash as the delimiter (e.g. 2-15-2003) you could use this expression

"#([\d]+)[/|-]([\d]+)[/|-]([\d]+)#"

Yet you felt the need to write a couple paragraphs to defend it?

Not to defend it, but to lay out the pros and cons of various methods depending on the input and the user's needs. I am not attached to it, that would make me a complete idiot.

I'm curious, after reading my post, does it really sound like I am attached to that regex? If so, I have a lot to learn about expressing myself.  :'(

 

I like your solution. Simple and elegant.

Of course we still don't know much about the OP's input and his actual needs.

Wishing you all a fun day.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.