用于将“星期一 2014 年 12 月 15 日下午 3:15”拆分为至今、小时、分钟、上午/下午的正则表达式


Regular expression to break out "Mon 15 December 2014 3:15 PM" in to date, hour, minute, am/pm

我有一个格式为"星期一 15 十二月 2014 3:15 PM"的字符串,我想分解为:

  • 日期:"2014年12月15日星期一"
  • 小时:"3"
  • 分钟:"15"
  • 上午/下午:"下午"

问题是其中一些可能是空白的,所以我可能有" 3:15 PM",或"星期一 15 十二月 2014 :15",或" 3:"或只是" : "

我知道我可以将其分解为多个步骤并将其分开,但我想知道 PHP 中是否有一种方法可以使用单个(或至少更少)正则表达式来做到这一点。

您可以使用

此模式:

$pattern = '~'A
    's*+ (?=.) # prevent to match an "empty" string
    (?:(?<dayName>Mon|Tue|Wed|Thu|Fri|Sat|Sun) 'h+ )?
    (?:(?<day>'d{1,2}) 'h+)?
    (?:(?<month>January|February|March|April|May|June|July|August|September|October|November|December) 'h+)?
    (?:(?<year> 'd{4}) 'h+)?
    (?: (?<hour>'d{1,2})? : (?<minute>'d{1,2})? (?:'h+(?<ampm>[AP]M))? )?
    's*
    'z
~xi';
if (preg_match($pattern, $strDate, $m)) {
    // depending of the matched fields, you can eventually complete them
    // and validate the date using strtotime.
}

由于所有字段都是可选的,因此我在前面添加了 lookahead (?=.)前面的 's*+ 以检查是否至少有一个非空格字符。

随意改进模式以支持,例如,短月份名称:Jan(?:uary)?

您不必使用正则表达式来实现此目的。以下是使用 date()strtotime() 的简单解决方案:

$date_text = "Mon 15 December 2014 3:15 PM";
$date = explode("_", date("D d F Y_g_i_A", strtotime($date_text)));
print_r($date);

输出:

Array
(
    [0] => Mon 15 December 2014
    [1] => 3
    [2] => 15
    [3] => PM
)

PHPFiddle 链接: http://phpfiddle.org/main/code/q3us-tg6c

或者,如果您真的想使用正则表达式,那么这里有另一种解决方案:

$pattern = '/((Mon|Tue|Wed|Thu|Fri|Sat|Sun)'s(['d]{1,2})'s(January|February|March|April|May|June|July|August|September|October|November|December)'s(['d]{4}))'s(['d]{1,2}):(['d]{1,2})'s(AM|PM)/';
$date_text = 'Mon 15 December 2014 3:15 PM';
$matches = array();
preg_match($pattern, $date_text, $matches);
echo "Date: " . $matches[1] . "<br />";
echo "Hour: " . $matches[6] . "<br />";
echo "Minute: " . $matches[7] . "<br />";
echo "AM/PM: " . $matches[8] . "<br />";

输出:

Date: Mon 15 December 2014
Hour: 3
Minute: 15
AM/PM: PM

PHPFiddle 链接: http://phpfiddle.org/main/code/gt94-dydb

你试过date_parse_from_format吗?