2


I need some help with a regular expressions. I'm trying to validate if a string looks like 'yyyy-mm-dd', this is my code so far:

case "date":
                if (preg_match("/^[0-9\-]/i",$value)){
                    $date = explode("-",$value);
                    $year = $date[0];
                    $month = $date[1];
                    $day = $date[2];
                    if (!checkdate($month,$day,$year))
                    {
                        $this->errors[] = "Ogiltigt datum.";
                    }
                } else {
                    $this->errors[] = "Ogiltigt datum angivet.";
                }
            break;

I am very new to regular expressions, thanks.

3 Answers3

10

You can use this:

if ( preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}\z/', $value) ) { ...

however this kind of pattern can validate something like 0000-40-99

pattern details:

/         # pattern delimiter
^         # anchor: start of the string
[0-9]{4}  # four digits
-         # literal: -
[0-9]{2}
-
[0-9]{2}
\z        # anchor: end of the string
/         # pattern delimiter
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • Thanks that works great, but could anyone explain why? I'd like to know why and how it works, thanks. – Petter Pettersson Jan 11 '14 at 16:41
  • @PetterPettersson: `[0-9]` = any character between 0 to 9. `{4}` previous character class (0 to 9) 4 times. `-` dash, and so on. See https://www.debuggex.com/r/iDL-oQxvjyTC2AhF – Madara's Ghost Jan 11 '14 at 16:42
  • @PetterPettersson: I added a description of the pattern, however keep in mind that this use only very basic regex notions. I suggest you to read a tutorial about regex, for example: http://regular-expressions.info – Casimir et Hippolyte Jan 11 '14 at 16:46
  • Thanks, I will check this out. I will use your answer as best answer. – Petter Pettersson Jan 11 '14 at 16:47
2

Using capturing group, you don't need call explode.

if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value, $matches)) {
    $year = $matches[1];
    $month = $matches[2];
    $day = $matches[3];
    ...
}
  • \d matches any digit characters.
  • {n} is quantifier: to match previous pattern exactly 4 times.
  • You can access the matched group using $matches[1], $matches[2], ...
    • $matches[0] contains entire matched string.
falsetru
  • 357,413
  • 63
  • 732
  • 636
0

While you can use regex one can also use a simple function to validate the date according to the Swedish format (yyyy-mm-dd) or any other format for that matter.

function validateDate($date, $format = 'Y-m-d H:i:s') {
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

var_dump(validateDate('2014-01-11', 'Y-m-d')); // true
var_dump(validateDate('2014-1-11', 'Y-m-d')); // false

function was copied from this answer or php.net

Community
  • 1
  • 1
user555
  • 1,564
  • 2
  • 15
  • 29