PHP:替换数组中_not_的所有单词

时间:2011-10-25 23:57:57

标签: php regex date

我试图用PHP解析用户输入的字符串日期。我需要删除除这两个可接受类别之外的所有字符:

1) [0-9,\./-] (numerals, comma, period, slash, and dash)
2) An array of acceptable words:
    $monthNames=array(
        "january"=>1,
        "jan"=>1,
        "february"=>2,
        "feb"=>2
    );

我尝试在字符单词bounaries上爆炸()然后删除不在数组中的每个部分,但这导致了相当混乱。是否有一种优雅的方式来实现这一目标?

谢谢!

4 个答案:

答案 0 :(得分:1)

您可以使用strtotime()

echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";

检查失败:

$str = 'Not Good';

// previous to PHP 5.1.0 you would compare with -1, instead of false
if (($timestamp = strtotime($str)) === false) {
    echo "The string ($str) is bogus";
} else {
    echo "$str == " . date('l dS \o\f F Y h:i:s A', $timestamp);
}

请参阅http://php.net/manual/en/function.strtotime.php

DateTime::createFromFormat()也可能有用。

请参阅http://www.php.net/manual/en/datetime.createfromformat.php

答案 1 :(得分:0)

避免这种情况的最佳方法是将日期条目设为仅包含有效选项的表单,并丢弃其余部分。

答案 2 :(得分:0)

你可以使用一个正则表达式来匹配日期,这里是一个非常简单的基本表达式:

preg_match('/((Jan|Feb|Dec|\d{1,2})[ .\/-]){2,2}\d{1,4}/i', $str, $matches);
echo $matches[0];

但是,您必须添加其他月份。

关于不眠之夜的进一步想法:

  • 禁止月份< 1和> 12
  • 禁止2011年1月1日
  • 禁止奇怪的岁月
  • ...
  • 废弃并找到一个好的;)

我采取两步走的方法:

  1. 提取看起来日期的内容
  2. 使用内置时间函数检查是否可以构建一个有意义的时间戳。如果不能,就扔掉它。

答案 3 :(得分:0)

如果可以安全地假设您的$ monthNames数组少于26个元素,那么以下工作(虽然这肯定是“黑客” - 如果我能,我会提供另一个答案想到一些值得被称为“优雅”的东西:

<?php

$text = 'january 3 february 7 xyz';
print 'original string=[' . $text . "]\n";

$monthNames = array(
    'january' => 1,
    'jan' => 1,
    'february' => 2,
    'feb' => 2
    // ... presumably there are some more array elements here...
);

// Map each monthNames key to a capital letter:
$i = 65; // ASCII code for 'A'
$mmap = array();
foreach (array_keys($monthNames) as $m) {
    $c = chr($i);
    $mmap[$c] = $m;
    $i += 1;
}

// Strip out capital letters first:
$text1 = preg_replace('/[A-Z]+/', "", $text);

// Replace each month name with its letter:
$text2 = str_replace(array_keys($monthNames), array_keys($mmap), $text1);

// Filter out everything that is not allowed:
$text3 = preg_replace('/[^0-9,\.\-A-Z]/', "", $text2);

// Restore the original month names:
$text4 = str_replace(array_keys($mmap), array_keys($monthNames), $text3);

print 'filtered string=[' . $text4 . "]\n"; 
?>

备注:

  1. 如果您有超过26个字符串要从过滤中排除,那么您可以编写代码以利用相同的想法,但是IMO使人们可以理解的代码变得相当困难(或者无论如何,由我来。)
  2. 你当然可以调整preg_replace()模式,如果你确定你真的想要它们,那就留下空白。