在自由格式文本中查找日期的最佳方法是什么?

时间:2012-07-11 03:00:14

标签: php regex perl date

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

  1. 7月14日&第十五
  2. 7/14& 7/15
  3. 7-14& 7-15
  4. 星期六14日和星期日15日
  5. 7月14日星期六和15日
  6. 等等。正则表达式是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 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我有一个非常类似问题的Perl答案,这里有一个非常复杂的暴力解决方案: Extract inconsistently formatted date from string (date parsing, NLP)

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

答案 2 :(得分: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;
}

答案 3 :(得分:0)

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

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

然而,要意识到,您将难以猜测像1/2/2005这样的日期是什么意思......是1月2日还是许多领域的标准,那将是2月1日?在模棱两可的情况下,您可能需要将它们丢弃或将它们发送到某个地方进行手动评估。