如何用PHP preg_match匹配日期区间:7th January 2017 - 29th December 2018
没问题,我来帮你搞定这个日期匹配的需求~下面分两种场景给你详细说明:
1. 匹配整个日期区间字符串
如果只是要验证输入的字符串是否符合「数字+序数后缀+月份+年份 - 数字+序数后缀+月份+年份」的格式,可以用这个正则:
$pattern = '/^\d+(st|nd|rd|th)\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}\s-\s\d+(st|nd|rd|th)\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}$/'; $dateStr = "7th January 2017 - 29th December 2018"; if (preg_match($pattern, $dateStr)) { echo "字符串符合日期区间格式"; } else { echo "字符串不符合日期区间格式"; }
正则各部分的含义:
\d+:匹配1位或多位数字(对应日期的数字部分,比如7、29)(st|nd|rd|th):覆盖所有英文序数后缀\s:匹配空格(January|...|December):列出所有英文月份,确保只匹配合法的月份名称\d{4}:匹配4位年份\s-\s:匹配日期之间的分隔符(空格+减号+空格)^和$:确保匹配整个字符串,避免前后有多余字符
2. 单独提取两个日期
如果需要把区间里的「7th January 2017」和「29th December 2018」单独提取出来,可以给每个完整日期加上捕获组,调整后的正则和示例代码如下:
$dateStr = "7th January 2017 - 29th December 2018"; // 用非捕获组(?:...)优化重复的月份匹配,减少捕获组数量 $pattern = '/^(\d+(st|nd|rd|th)\s(?:January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4})\s-\s(\d+(st|nd|rd|th)\s(?:January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4})$/'; if (preg_match($pattern, $dateStr, $matches)) { $startDate = $matches[1]; // 提取第一个日期:7th January 2017 $endDate = $matches[3]; // 提取第二个日期:29th December 2018 echo "开始日期:{$startDate}\n"; echo "结束日期:{$endDate}\n"; } else { echo "无法匹配目标日期格式"; }
这里用(?:...)是非捕获组,它只会参与匹配,不会被存入$matches数组,这样我们的捕获组就只保留了两个完整日期,更方便后续使用。
小补充:如果需要更严谨的日期有效性验证(比如避免出现“32nd January”这种错误日期),单纯正则会比较复杂,建议提取日期后用PHP的DateTime类再做一次验证,比如:
$startDateObj = DateTime::createFromFormat('jS F Y', $startDate); if ($startDateObj && $startDateObj->format('jS F Y') === $startDate) { echo "开始日期有效"; }
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

