2013-08-09 2 views
1

Я пытаюсь проанализировать имя файла в формате даты, например.Заменить разделы кода даты строки

C:\Documents/<yyyy>\<MMM>\Example_CSV_<ddMM>.csv 

и вернуть фамилию «Сегодня».

Так в приведенном выше примере, я хотел бы вернуться (на 9 августа 2013 года), C: \ Documents \ 2013 \ Aug \ Example_CSV_0908.csv

Интересно, если Regex будет работать, но я просто с ментальный блок относительно того, как подойти к нему!

Я не могу просто заменить xth на yth секциями на дату, так как файлы, которые я буду обрабатывать, хранятся в разных папках по всей системе (не моя идея). Все даты коды будут содержаться в <> однако, так, насколько я знаю, я не мог сделать что-то вроде

Return DateTime.Today.ToString(RawFileName); 

Кроме того, я предполагаю, что это будет иметь непредсказуемые последствия, если часть обычного filename можно интерпретировать как код даты!

Если кто-то может дать мне указатель в правильном направлении, это было бы здорово. Если вам нужно немного больше контекста, вот это класс, который будет содержать этот метод:

public class ImportSetting 
    { 
     public string ID { get; private set; } 
     public List<ImportMapping> Mappings { get; set; } 
     public string RawFileName { get; set; } 

     public string GetFileName() 
     { 
      string ToFormat = RawFileName; //e.g. C:\Documents/<yyyy>\<MMM>\Example_CSV_<ddMM>.csv 

      //Do some clever stuff. 

      return ToFormat; //C:\Documents\2013\Aug\Example_CSV_0908.csv 
     } 
     public int GetCSVColumn(string AttributeName) { return Mappings.First(x => x.Attribute == AttributeName).ColumnID; } 

     public ImportSetting(string Name) 
     { 
      ID = Name; 
      Mappings = new List<ImportMapping>(); 
     } 
    } 

Thankyou очень много для вашей помощи!

ответ

0
var path = new Regex("<([dMy]+)>").Replace(pathFormat, o => DateTime.Now.ToString(o.Groups[1].Value)); 

Nb: Добавить все возможные буквы/символы, которые могут больше появляться в квадратных скобках ,

Nb2: Это, однако, не ограничивает странные строки DateTime. Если вы хотите, чтобы обеспечить униформу формата, вы могли бы сделать более ограничительный Regex так:

var path = new Regex("<(ddMM)|(MMM)|(yyyy)>").Replace(pathFormat, o => DateTime.Now.ToString(o.Groups[1].Value)); 

Edit: Должно любить остроты :)

+0

Ты гений. Надеюсь, что я смогу ограничить ошибки, предотвратив их, когда пользователь вводит имя файла и его сохранение в файл XML, а не когда я его читаю. Из интереса, каков будет пример строки даты, которая вызовет исключение? –

+0

Один лайнер вообще не вызывает исключения. Он ссылается на пользователей, вводящих что-то вроде dMdM, что не является правильной последовательностью. –

+0

Да, я просто сказал, что из рефлекса. Но это не приведет к исключениям. Я редактирую ответ, когда мы говорим. – Pluc

0

Что вы могли бы сделать (хотя я не могу imágen это реальный сценарий, но это может быть моим недостаток imagenation является следующим регулярным выражением;

<([fdDmMyYs]+?)> 

Это даст вам какие-либо матчи в рамках < и> символы, как можно короче, так в тестировании для меня он вернулся,

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

Тогда просто использовать DateTime.Now.ToString (RegexMatchWithout <> здесь)

И заменить матч с выходом.

Так пример кода (непроверенные, но я чувствую себя уверенно ;-)) будет:

public string GetFileName(string fileName) 
{ 
    Regex regex = new Regex(@"<([fdDmMyYs]+?)>"); 

    foreach(Match m in regex.Matches(fileName)) 
    { 
     fileName = fileName.Replace(m.Value, DateTime.Now.ToString(m.Value.Substring(1, m.Value.Length - 2))); 
    } 

    return fileName; 
} 
+0

Спасибо, это точная вещь, которую я искал! Проблема только в том, что она поднимает все выражения, которые нужно сопоставить, и ничего не заменяет ...? –

+0

Сделал глупую опечатку, не чувствовал, что уверен в моем непроверенном коде. Однако лучше использовать StringBuilder, а не инициализировать новую строку каждый раз, а что нет. Это функциональный код, но есть возможности для улучшения. –

2

Там нет необходимости заменять что-либо в тексте как вы можете использовать дату.Метод ToString() с форматом строки, как это:

public string GetFileName(DateTime date) 
{ 
    string format = @"'C:\\Documents'\\yyyy\\MMM'\\Example_CSV_'ddMM'.csv'"; 
    return date.ToString(format); 
} 

Вызов GetFileName с сегодняшней датой:
Console.WriteLine(GetFileName(DateTime.Now));

Выход:
C:\Documents\2013\Aug\Example_CSV_0908.csv

Все, что вы не хотите быть разобраны в качестве даты, поставьте одиночные кавычки ', чтобы он анализировался как строковый литерал. Полный список строк формата даты можно найти здесь: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

+0

Спасибо за это предложение Мэтт! Я не знаю, как я пропустил литеральный разделитель строк! Я обновил свой ответ, чтобы включить литеральный разделитель строк. Я должен был все еще избегать обратной косой черты, поскольку это особые случаи. –

+0

Теперь выглядит лучше. Я думаю, что обратная косая черта может проходить внутри или вне кавычек и будет работать одинаково. Ура! –

Смежные вопросы