Why not save the regular expression and the corresponding format string for DateTime.ParseExact in config?
Of course, you will have to make some efforts to develop the correct values, but then it is just a matter of updating the configuration and its implementation.
You will still have a problem parsing the date if you don't specify its format or if it looks like a standard format, anyway.
Edit: I hope you don't mind me grabbing this question, but I was curious to discuss the Regex vs. discussion TryParseExact and Exception, so I did a little test. The code below parses the same file name 100,000 times to identify and convert the built-in date.
I have definitely run the code in release mode and without a debugger; debugging exception handling with Visual Studio is a killer.
I found that the methods of Regex vs. TryParseExact were very close. Not surprisingly, as the number of levels in the path increases, the Regex method has become a bit more efficient, but there is still nothing in it. If the path does not include a date at all, the balance shifts slightly towards the Regex method, but this is not enough to make a significant difference.
Using the βwrongβ way to rely on exception handling was quite different though!
My timings for the code shown below were:
Using Regex: Duration: 543.0543 Using TryParse: Duration: 429.0429 Using Exceptions: Duration: 11930.4865
This time is in milliseconds. I initially ran 1 million iterations, but I was bored when doing Exceptions; -)
The experiment illustrates that the Regex and TryParseExact methods are fairly comparable in terms of performance, but the TryParseExact method has a significant advantage in that it does not need to define or get a regular expression. Without a doubt, this is a good choice for this problem.
It also illustrates the overhead of handling the exception. Not surprisingly, in reality, the process of unwinding a stack is potentially complex and time-consuming. The application spent 95% of its time handling exceptions. It illustrates well the argument that you should not rely on exception handling for parsing dates - hence the existence of TryParse methods ...
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Globalization; namespace ConsoleApplication1 { class Program { static Regex r = new Regex(@"\d{4}_[a-zA-Z]{3}_\d{1,2}"); static string dateFormat = "yyyy_MMM_d"; static CultureInfo provider = CultureInfo.InvariantCulture; static void Main(string[] args) { string filepath = @"C:\TopDir\SubDir\2011_JUL_26\filename.ext"; DateTime startTime; DateTime endTime; TimeSpan duration; bool success; DateTime result; System.Console.WriteLine("Using Regex:"); startTime = DateTime.Now; for (int ix = 0; ix < 100000; ix++) { success = UsingRegex(filepath, out result); } endTime = DateTime.Now; duration = endTime - startTime; System.Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString()); System.Console.WriteLine("Using TryParse:"); startTime = DateTime.Now; for (int ix = 0; ix < 100000; ix++) { success = UsingTryParse(filepath, out result); } endTime = DateTime.Now; duration = endTime - startTime; System.Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString()); System.Console.WriteLine("Using Exceptions:"); startTime = DateTime.Now; for (int ix = 0; ix < 100000; ix++) { success = UsingExceptions(filepath, out result); } endTime = DateTime.Now; duration = endTime - startTime; System.Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString()); } static bool UsingRegex(string filepath, out DateTime result) { var matches = r.Matches(filepath); if (matches.Count > 0) { return DateTime.TryParseExact(matches[0].Value, dateFormat, provider, DateTimeStyles.None, out result); } result = DateTime.MinValue; return false; } static bool UsingTryParse(string filepath, out DateTime result) { var parts = filepath.Split('\\'); foreach (var part in parts) { if( DateTime.TryParseExact(part, dateFormat, provider, DateTimeStyles.None, out result) ) { return true; } } result = DateTime.MinValue; return false; } static bool UsingExceptions(string filepath, out DateTime result) { var parts = filepath.Split('\\'); foreach (var part in parts) { try { result = DateTime.ParseExact(part, dateFormat, provider, DateTimeStyles.None); return true; } catch(Exception ex) { } } result = DateTime.MinValue; return false; } } }