3

在自由格式文本中查找日期的最佳方法是什么?用户可以通过多种不同方式在其中放置日期的帖子,例如:

  1. 7 月 14 日至 15 日
  2. 7/14 和 7/15
  3. 7-14 & 7-15
  4. 周六 14 日和周日 15 日
  5. 7月14日至15日星期六

等等。正则表达式是我处理这类事情的最佳选择preg_match吗?我还想搜索是否有两个日期,一个是开始日期,另一个是结束日期,但在我搜索的文本中可能有一个或两个日期。

到目前为止,这是我的 PHP 代码:

$dates1 = '01-01';
$dates2 = 'July 14th & 15th';
$dates3 = '7/14 & 7/15';
$dates4 = '7-14 & 7-15';
$dates5 = 'Saturday 14th and Sunday 15th';
$dates6 = 'Saturday July 14th and 15th';

$regexes = array(
        '/\s(1|2|3|4|5|6|7|8|9|10|11|12)\/\d{1,2}/',  //finds a date
        '/\s(1|2|3|4|5|6|7|8|9|10|11|12)-\d{1,2}/',  //finds another date
        '%\b(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])\b%', //finds date format dd-mm or dd.mm
        );
foreach($regexes as $regex){
preg_match($regex,$dates,$matches);
}
var_dump($matches);
4

4 回答 4

0

PHP 有一个名为 DateTime 的类来管理时间戳。它使您可以非常轻松地在字符串和 DateTime 对象之间进行转换……前提是您的字符串使用 PHP 为您提供的格式。

例如,

$date = DateTime::createFromFormat('d-m', '01-01');
$date = DateTime::createFromFormat('F d', 'July 14');
$date = DateTime::createFromFormat('d-M-Y', '15-Feb-2009');

也就是说,这就是我要做的:

按优先级顺序创建一系列可接受的格式:

$formats = array("d-m", "j-M-Y" ... );

使用 RegEx 来按摩您的输入,使其与您的格式相匹配。

// Add the current year to this one:
$dates1 = '01-01';

// Split these into "July 14" and "July 15", and add the year
//  (this one will be the toughest)
$dates2 = 'July 14th & 15th';

// Split these into "7/14" and "7/15", and add the year
$dates3 = '7/14 & 7/15';

// Split these into "7-14" and "7-15", and add the year
$dates4 = '7-14 & 7-15';

// Split these, and add a month and year
$dates5 = 'Saturday 14th and Sunday 15th';

// Split these, and add a year:
$dates6 = 'Saturday July 14th and 15th';

尝试构造一个 DateTime 对象:

$date = false;
foreach ($formats as $format)
{
    $date = DateTime::createFromFormat($format, $dateString);
    if ($date) break;
}
于 2012-07-11T03:30:24.277 回答
0

查看 PHP 认为有效的日期格式:http: //us.php.net/manual/en/datetime.formats.date.php

理想情况下,您希望将日期隔离然后使用strtotime(),但由于这不是一个选项,您会陷入困境。您必须量化您想要支持的所有格式,并创建一组涵盖所有基础的正则表达式。上面提到的列表是一个很好的起点。

然而,请意识到,您将难以猜测日期的1/2/2005含义……是 1 月 2 日,还是按照许多地区的标准,是 2 月 1 日?在模棱两可的情况下,您可能不得不将它们扔掉或将它们发送到某个地方以进行手动评估。

于 2012-07-11T03:30:39.107 回答
0

我假设您尝试解析的文本包含您感兴趣的日期文本。如果是这样,我将修改 UI,以便如果需要两个日期,则必须输入两个文本字段。这消除了弄清楚如何将它们分开的问题。

现在有了文本中的一个日期,我会将整个文本交给strtotime(). 这就解决了第二个问题。如果您收到废话(strtotime()如果是废话,会告诉您),您可以告诉用户您无法理解给出的日期。

于 2012-07-11T03:18:47.807 回答
0

我有一个非常相似的问题的 Perl 答案,这里有一个不太复杂的蛮力解决方案: 从字符串中提取格式不一致的日期(日期解析,NLP)

基本方法是将自由格式文本分解为可能是日期的连续字符块,然后查看这些字符是否解析为有效的查找日期。在 Perl 中,我可以(ab)使用 Date::Parse 模块来做到这一点。如果 PHP 没有解析任意自由格式日期的等效模块,您可以使用一些正则表达式来近似它。

于 2012-07-11T03:19:09.120 回答