Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check if a filename matches a wildcard pattern

Tags:

.net

regex

I've got a wildcard pattern, perhaps "*.txt" or "POS??.dat".

I also have list of filenames in memory that I need to compare to that pattern.

How would I do that, keeping in mind I need exactly the same semantics that IO.DirectoryInfo.GetFiles(pattern) uses.

EDIT: Blindly translating this into a regex will NOT work.

like image 448
Jonathan Allen Avatar asked Mar 16 '09 20:03

Jonathan Allen


People also ask

How do you use a wildcard in a filename?

When you have a number of files named in series (for example, chap1 to chap12) or filenames with common characters (like aegis, aeon, and aerie), you can use wildcards (also called metacharacters) to specify many files at once. These special characters are * (asterisk), ? (question mark), and [ ] (square brackets).

Which one is a wildcards used for pattern matching?

Use the asterisk ( * ) to match any sequence or string of characters. The ( * ) indicates any characters, including no characters.

What is a filename pattern?

You can specify a file name pattern, using wildcard characters, to identify a file to be read by the FileInput, CDInput, and FTEInput nodes. You can also specify a file name pattern, using a single wildcard character, to name the file to be created by the FileOutput and FTEOutput nodes.

Are wildcards and regex the same?

Wildcards are different from the regular expressions used in grep (although they may look similar at times). Wildcards apply to all commands including grep and are used in place of or in combination with operands. Regular Expressions only apply to grep and a few other UNIX commands.


1 Answers

I have a complete answer in code for you that's 95% like FindFiles(string).

The 5% that isn't there is the short names/long names behavior in the second note on the MSDN documentation for this function.

If you would still like to get that behavior, you'll have to complete a computation of the short name of each string you have in the input array, and then add the long name to the collection of matches if either the long or short name matches the pattern.

Here is the code:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions;  namespace FindFilesRegEx {     class Program     {         static void Main(string[] args)         {             string[] names = { "hello.t", "HelLo.tx", "HeLLo.txt", "HeLLo.txtsjfhs", "HeLLo.tx.sdj", "hAlLo20984.txt" };             string[] matches;             matches = FindFilesEmulator("hello.tx", names);             matches = FindFilesEmulator("H*o*.???", names);             matches = FindFilesEmulator("hello.txt", names);             matches = FindFilesEmulator("lskfjd30", names);         }          public string[] FindFilesEmulator(string pattern, string[] names)         {             List<string> matches = new List<string>();             Regex regex = FindFilesPatternToRegex.Convert(pattern);             foreach (string s in names)             {                 if (regex.IsMatch(s))                 {                     matches.Add(s);                 }             }             return matches.ToArray();         }          internal static class FindFilesPatternToRegex         {             private static Regex HasQuestionMarkRegEx   = new Regex(@"\?", RegexOptions.Compiled);             private static Regex IllegalCharactersRegex  = new Regex("[" + @"\/:<>|" + "\"]", RegexOptions.Compiled);             private static Regex CatchExtentionRegex    = new Regex(@"^\s*.+\.([^\.]+)\s*$", RegexOptions.Compiled);             private static string NonDotCharacters      = @"[^.]*";             public static Regex Convert(string pattern)             {                 if (pattern == null)                 {                     throw new ArgumentNullException();                 }                 pattern = pattern.Trim();                 if (pattern.Length == 0)                 {                     throw new ArgumentException("Pattern is empty.");                 }                 if(IllegalCharactersRegex.IsMatch(pattern))                 {                     throw new ArgumentException("Pattern contains illegal characters.");                 }                 bool hasExtension = CatchExtentionRegex.IsMatch(pattern);                 bool matchExact = false;                 if (HasQuestionMarkRegEx.IsMatch(pattern))                 {                     matchExact = true;                 }                 else if(hasExtension)                 {                     matchExact = CatchExtentionRegex.Match(pattern).Groups[1].Length != 3;                 }                 string regexString = Regex.Escape(pattern);                 regexString = "^" + Regex.Replace(regexString, @"\\\*", ".*");                 regexString = Regex.Replace(regexString, @"\\\?", ".");                 if(!matchExact && hasExtension)                 {                     regexString += NonDotCharacters;                 }                 regexString += "$";                 Regex regex = new Regex(regexString, RegexOptions.Compiled | RegexOptions.IgnoreCase);                 return regex;             }         }     } } 
like image 51
sprite Avatar answered Sep 29 '22 10:09

sprite