clarkk clarkk - 4 months ago 12
PHP Question

match datastamp multiple variations with zerofill, without etc

I need to match a variety of datestamps in a text string

pattern with zerofill in day/month



$date_day_pattern = '0[1-9]|[12][0-9]|3[01]';
$date_month_pattern = '0[1-9]|1[0-2]';
$date_year_pattern = '[12][0-9]|20[12][0-9]';

$date_pattern = "(?<!\d)($date_day_pattern)[^\d]?($date_month_pattern)[^\d]?($date_year_pattern)(?!\d)";
preg_match("/$date_pattern/m", $input, $matches);


This works when matching for

01-05-2015
01-05-15
01052015
010515


But I also need to match for datestamps where day/month doesn't have zerofill. But then the datestamp must have a seperator between day, month and year

1-5-2015


The pattern must not match

152015

Answer

You could add an additional alternative to the first two expressions:

  • For the day pattern: [1-9](?=\D)
  • For the month pattern: (?<=\D)[1-9](?=\D)

This will become:

$date_day_pattern = '0[1-9]|[12][0-9]|3[01]|[1-9](?=\D)';
$date_month_pattern = '0[1-9]|1[0-2]|(?<=\D)[1-9](?=\D)';
$date_year_pattern = '[12][0-9]|20[12][0-9]';

$date_pattern = "(?<!\d)($date_day_pattern)\D?($date_month_pattern)\D?($date_year_pattern)(?!\d)";

The above will even match weird, but non-ambiguous strings like:

2-0116

... but it will not allow:

201-16

Note that \D is equivalent to [^\d].