使用zerofill匹配datastamp多个变体,没有等

时间:2016-08-03 21:46:26

标签: php regex

我需要匹配文本字符串中的各种日期戳

在日/月中使用zerofill的模式

$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);

匹配

时有效
01-05-2015
01-05-15
01052015
010515

但我还需要匹配日期/月份没有zerofill的日期戳。但是,日期戳必须在日,月和年之间有分隔符

1-5-2015

模式必须匹配

152015

2 个答案:

答案 0 :(得分:2)

您可以为前两个表达式添加其他替代选项:

  • 日期模式:[1-9](?=\D)
  • 月份模式:(?<=\D)[1-9](?=\D)

这将成为:

$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)";

以上内容甚至可以匹配奇怪但非模糊的字符串,如:

2-0116

...但不允许:

201-16

请注意,\D相当于[^\d]

答案 1 :(得分:1)

您可以使用conditional subpattern feature,即如果匹配前导0,则将分隔符设为可选,否则强制使用。

$date_pattern = 
'(?<!\d)((0)?[1-9]|[12][0-9]|3[01])(?(2)\D?|\D)(0?[1-9]|1[0-2])(?(2)\D?|\D)([12][0-9]|20[12][0-9])(?!\d)';
  • 可选捕获的第2组为(0)?
  • (?(2)\D?|\D)如果匹配组#2,则\D可选,否则需要\D(非数字)。

RegEx Demo