Извлечь даты из имени файла - PullRequest
4 голосов
/ 15 июня 2010

У меня есть ситуация, когда мне нужно извлечь даты из имен файлов, чей общий шаблон [filename_]YYYYMMDD[.fileExtension]

например. "xxx_20100326.xls" или x2v_20100326.csv

Следующая программа работает

//Number of charecter in the substring is set to 8 
//since the length of YYYYMMDD is 8

public static string ExtractDatesFromFileNames(string fileName)
{

    return fileName.Substring(fileName.IndexOf("_") + 1, 8);
}

Есть ли лучший способ добиться того же?

Я в основном ищу стандартную практику.

Я использую C # 3.0 и dotnet framework 3.5

Edit:

Мне нравится решение и способ ответа на LC. Я использовал его программу как

string regExPattern = "^(?:.*_)?([0-9]{4})([0-9]{2})([0-9]{2})(?:\\..*)?$";
string result =  Regex.Match(fileName, @regExPattern).Groups[1].Value;

Входные данные для функции: "x2v_20100326.csv"

Но вывод будет: 2010 вместо 20100326 (который является ожидаемым).

Может кто-нибудь помочь, пожалуйста.

Ответы [ 3 ]

2 голосов
/ 15 июня 2010

У вас достаточно кода, если вы уверены, что ввод этого стандартного формата. Если есть вероятность, что этого не произойдет, вам следует добавить обработку ошибок для сценариев, в которых нет подчеркивания или дни / месяцы не представлены 2 цифрами (что приведет к путанице в 8-значном числе подстрок), после чего DateTime.TryParse, чтобы убедиться, что это реальная дата.

Другие ваши варианты:

  • Regex : избыточное количество для такого четко определенного шаблона.
  • LINQ : использование методов SkipWhile, Skip, TakeWhile для игнорирования подчеркивания и захвата чисел, пока не встретится точка. Этот запрос выглядит запутанным, и результат необходимо преобразовать в строку.
  • String.Split : разделить на { '_', '.' } и использовать элемент массива, представляющий дату.

Ни один из этих вариантов не даст код, который выглядит яснее, чем у вас уже есть, и производительность, вероятно, не будет лучше.

2 голосов
/ 15 июня 2010

Я бы использовал регулярное выражение, , особенно если возможно, что в имени файла есть несколько подчеркиваний.Затем вы можете зафиксировать год, месяц, день и вернуть DateTime, если необходимо.Таким образом, вы можете убедиться, что вы извлекаете правильную часть имени файла, и она действительно соответствует шаблону, который вы ищете.

Для шаблона [filename_]YYYYMMDD[.fileExtension], я думаю что-то вроде:

^(?:.*_)?([0-9]{4})([0-9]{2})([0-9]{2})(?:\..*)?$

Тогда вашими захваченными группами будут год, месяц и день в указанном порядке.

Объяснение:

^: началовашей строки.

(?:.*_)?: необязательная группа без захвата, содержащая любое количество символов, за которым следует подчеркивание.

([0-9]{4}): группа захвата, содержащая ровно четыре цифры.

([0-9]{2}): группа захвата, содержащая ровно две цифры.

(?:\..*)?: необязательная группа без захвата, содержащая точку, за которой следует любое количество символов.

$: конец вашей строки.

Тем не менее, я добавлю, что если вы уверены, что ваши имена файлов имеют одно и только одно подчеркивание, а дата следует за этим подчеркиванием, код, который у вас есть, чище ивероятно будет немного быстрее, чем реGEX.Об этом следует помнить, исходя из ожидаемого набора входных данных.

0 голосов
/ 15 июня 2010

Код, который вы получили, в порядке, за исключением того, что вы можете проверить возвращаемое значение IndexOf в случае, если вы встретите файл без _, т.е.чтобы проверить, является ли это действительной датой, вы можете позвонить DateTime.TryParseExact

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...