Правильный код preg_match для сортировки имен файлов по дате?

У меня есть функция, которая берет имя файла из папки, сортирует его по дате, а затем создает ссылку на файл. Однако это работает только в том случае, если в фактическом имени файла есть пробелы между словами. Если я добавляю дефисы в имя файла, порядок по дате работает неправильно.

Имена файлов, которые работают:

Презентация Январь 2011.pdf

Презентация август 2010.pdf

Презентация май 2010.pdf

Если я добавлю дефисы к именам файлов, порядок нарушается:

Презентация-Январь-2011.pdf

Презентация-Август-2010.pdf

Презентация-май-2010.pdf

Как я могу изменить preg_match() так, чтобы он учитывал дефисы? Вот мой код:

$linkdir="documents/presentations";
$dir=opendir("documents/presentations");
$files=array();

while (($file=readdir($dir)) !== false)
{
   if ($file != "." and $file != ".." and $file != "index.php")
   {
    array_push($files, $file);
   }
}

closedir($dir);

function date_sort_desc($a, $b)
{
  preg_match('/\w+ \d{4}/', $a, $matches_a);
  preg_match('/\w+ \d{4}/', $b, $matches_b);
  $timestamp_a = strtotime($matches_a[0]);
  $timestamp_b = strtotime($matches_b[0]);
  if ($timestamp_a == $timestamp_b) return 0;
  return $timestamp_a < $timestamp_b;
}

usort($files, 'date_sort_desc');

foreach ($files as $file){
    $name = substr($file, 0, strrpos($file, '.'));
    $filename = str_replace(" ", "%20", $file);
    $name = str_replace("-", " ", $file);
    print "<li><a href='/$linkdir/$filename' rel='external'>$name</a></li>";
}

Любая помощь в этом будет высоко оценена.


person Jonathan    schedule 07.04.2011    source источник


Ответы (3)


'/\w+ \d{4}/' ищет слово, пробел и четыре цифры; '/\w+[ -]\d{4}/' должен искать пробел или дефис между словом и цифрами.

person Ekkehard.Horner    schedule 07.04.2011

Следующие две строки:

preg_match('/\w+ \d{4}/', $a, $matches_a);
preg_match('/\w+ \d{4}/', $b, $matches_b);

Они соответствуют ряду «словоподобных символов» (\w), пробелу и четырем цифрам (\d).

Вы можете либо изменить регулярное выражение, чтобы оно принимало пробел или тире: '[ -]' или '( |-)' вместо вызова функции пробела ''. This should not break the strtotime().

Если это так, вы можете изменить date_sort_desc(), добавив следующее вверху:

$a = str_replace("-", " ", $a);
$b = str_replace("-", " ", $b);

В этом случае вам не нужно будет изменять регулярные выражения.

person RickN    schedule 07.04.2011
comment
+1, потому что RikkusRukkus решает возможные проблемы с помощью strtotime(). Но средство следует применять перед вызовом матча, иначе шаблон также должен быть изменен. - person Ekkehard.Horner; 07.04.2011

Затем, что происходит, когда используется другой символ, вы постоянно обновляете свой код. Почему бы не использовать что-то вроде /\w+\W?\d{4}/ для захвата любого небуквенно-цифрового символа, который МОЖЕТ появиться?

person Jim    schedule 12.01.2012