Nov 022010
 

Every once in a while I need a little C# method to do some dirty work.  Here is an example of how to use Regular Expressions to match Windows style filemask matching.

private bool FitsMask(string fileName, string fileMask)
{
    string pattern =
         ‘^’ +
         System.Text.RegularExpressions.Regex.Escape(fileMask.Replace(“.”, “__DOT__”)
                         .Replace(“*”, “__STAR__”)
                         .Replace(“?”, “__QM__”))
             .Replace(“__DOT__”, “[.]”)
             .Replace(“__STAR__”, “.*”)
             .Replace(“__QM__”, “.”)
         + ‘$’;
    return new System.Text.RegularExpressions.Regex(pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase).IsMatch(fileName);
}

Here is the pure C# method of doing the same thing.

/// <summary>
/// Filemask can be “*|[*]filenamepart[*].*|[*]extpart[*]”
/// </summary>
/// <param name=”fileName” ></param>
/// <param name=”fileMask” ></param>
/// <returns>Boolean</returns>
/// <remarks>
/// Handles positional start and/or ending wildcards.
/// </remarks>
private bool FileMatchesMask(string fileName, string fileMask)
{
   const string asterisk = “*”;
   string se = string.Empty;
   if (fileMask.Equals(“*.*”))
      return true;

   // first, get comparable filenames and extensions
   string fn = Path.GetFileNameWithoutExtension(fileName).ToLower();
   string ext = Path.GetExtension(fileName).Replace(“.”, se).ToLower();

   string maskName = Path.GetFileNameWithoutExtension(fileMask).ToLower();
   string maskExt = Path.GetExtension(fileMask).ToLower().Replace(“.”, se);
   string maskExtStripped = maskExt.ToLower().Replace(asterisk, se);
   string maskNameStripped = maskName.ToLower().Replace(asterisk, se);
   wcPos fnWCP = GetWildCardPosition(maskName);
   wcPos extWCP = GetWildCardPosition(maskExt);

   if (maskExt.Equals(asterisk))
   {
     // ext can be anything, but fn may be masked
     if (maskName.IndexOf(asterisk) > -1)
     {
      // fn masked, ck position of wildcard
      switch (fnWCP)
      {
          case wcPos.wrap:
          return IsValueMatch(fn, maskNameStripped, wcPos.wrap);
          case wcPos.start:
          return IsValueMatch(fn, maskNameStripped, wcPos.start);
          case wcPos.@end:
          return IsValueMatch(fn, maskNameStripped, wcPos.@end);
          default:
          return IsValueMatch(fn, maskNameStripped, wcPos.wrap);
      }
     }
     else
     {
      // need exact match on filename, any ext is ok
      if (maskName.Equals(fn))
          return true;
     }
   }
   else if (maskName.Equals(asterisk))
   {
     // fn can be anything, but ext may be masked
     if (maskExt.IndexOf(asterisk) > -1)
     {
      // ext masked, ck position of wildcard
      switch (extWCP)
      {
          case wcPos.wrap:
          return IsValueMatch(ext, maskExtStripped, wcPos.wrap);
          case wcPos.start:
          return IsValueMatch(ext, maskExtStripped, wcPos.start);
          case wcPos.@end:
          return IsValueMatch(ext, maskExtStripped, wcPos.@end);
          default:
          return IsValueMatch(ext, maskExtStripped, wcPos.wrap);
      }
     }
     else
     {
      // need exact match on ext, any filename is ok
      if (maskExt.Equals(ext))
          return true;
     }
   }
   else
   {
     // here neither fn or ext = asterisk so must ck for
          // existence of asterisk in either
     // b/c of position of * this will get hairy…
     if (extWCP != wcPos.none)
     {
      // ext is masked, ck for masking in fn
      if (maskName.IndexOf(asterisk) > -1)
      {
          // ext and fn are masked
          return IsValueMatch(fn, maskNameStripped, fnWCP) &
                         IsValueMatch(ext, maskExtStripped, extWCP);
      }
      else
      {
          // fn not masked, look for fn exact match and
                  // ext masked
          if (fn.Equals(maskName) &&
                     IsValueMatch(ext, maskExtStripped, extWCP))
            return true;
      }
     }
     else
     {
      // ext is not masked, requires exact ext
               // and ck for fn masking
      if (maskName.IndexOf(asterisk) > -1)
      {
          // fn masked
          if (IsValueMatch(fn, maskNameStripped, fnWCP) &&
                     ext.Equals(maskExtStripped))
            return true;
          else if (fn.Equals(maskName) &&
                           ext.Equals(maskExtStripped))
            return true;
      }
     }
   }
   return false;
}