我需要匹配文本字符串中的各种日期戳
$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
答案 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)';
(0)?
(?(2)\D?|\D)
如果匹配组#2,则\D
可选,否则需要\D
(非数字)。