tags:

views:

1117

answers:

7

Is there a built-in mechanism in .NET to match patterns other than Regular Expressions? I'd like to match using UNIX style (glob) wildcards (* = any number of any character).

I'd like to use this for a end-user facing control. I fear that permitting all RegEx capabilities will be very confusing.

A: 

I don't know if the .NET framework has glob matching, but couldn't you replace the * with .*? and use regexes?

Ferruccio
I could, but I don't want the rest of the RegEx functionality.
dmo
+5  A: 

If you use VB.Net, you can use the Like statement, which has Glob like syntax.

http://www.getdotnetcode.com/gdncstore/free/Articles/Intoduction%20to%20the%20VB%20NET%20Like%20Operator.htm

torial
this is exactly what I'm looking for, but is it available in C#?
dmo
torial
Otherwise, you'll need to write the module in VB.Net as a DLL project, and reference the DLL in C#. VB.Net users have to do that to take advantage of the yield return statement.
torial
The link above from torial is specific to VB.Net as well.
dmo
C# is pretty much out of luck...
torial
Thanks for pointing out the Like operator!
magnifico
A: 

There is a way to turn these into regex patterns. You can download some code from here, it doesn't explain how to do it, but it is in the code somewhere.

Jonathan C Dickinson
+5  A: 

I found the actual code for you:

Regex.Escape( wildcardExpression ).Replace( @"\*", ".*" ).Replace( @"\?", "." );
Jonathan C Dickinson
you probably also want to tack a "^" before and a "$" at the end of that to mimic UNIX/DOS globbing, right?
yoyoyoyosef
You may be right, I just copied that code verbatim (my regex isn't really as good as it should be).
Jonathan C Dickinson
I think I would replace "\*" with @"[^\\\.]*" - implying, any character except dot or slash, which are meaningful in the filename format.
Cheeso
+1  A: 

I wrote a FileSelector class that does selection of files based on filenames. It also selects files based on time, size, and attributes. If you just want filename globbing then you express the name in forms like "*.txt" and similar. If you want the other parameters then you specify a boolean logic statement like "name = *.xls and ctime < 2009-01-01" - implying an .xls file created before January 1st 2009. You can also select based on the negative: "name != *.xls" means all files that are not xls.

Check it out. Open source. Liberal license. Free to use elsewhere.

Cheeso
A: 

Based on previous posts, I threw together a C# class:

using System;
using System.Text.RegularExpressions;

public class FileWildcard
{
    Regex mRegex;

    public FileWildcard(string wildcard)
    {
        string pattern = string.Format("^{0}$", Regex.Escape(wildcard)
            .Replace(@"\*", ".*").Replace(@"\?", "."));
        mRegex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
    }
    public bool IsMatch(string filenameToCompare)
    {
        return mRegex.IsMatch(filenameToCompare);
    }
}

Using it would go something like this:

FileWildcard w = new FileWildcard("*.txt");
if (w.IsMatch("Doug.Txt"))
   Console.WriteLine("We have a match");

The matching is NOT the same as the System.IO.Directory.GetFiles() method, so don't use them together.

Doug Clutter
A: 

.NET Version 4 adds support for filename globs to the Directory class. The 2- and 3-argument variants of methods like GetFiles() and EnumerateDirectories() take a search string as their second argument that supports filename globbing, with both * and ?.

class GlobTestMain
{
    static void Main(string[] args)
    {
        string[] exes = Directory.GetFiles(Environment.CurrentDirectory, "*.exe");
        foreach (string file in exes)
        {
            Console.WriteLine(Path.GetFileName(file));
        }
    }
}

would yield

GlobTest.exe
GlobTest.vshost.exe

The docs state that there are some caveats with matching extensions. It also states that 8.3 file names are matched (which may be generated automatically behind the scenes), which can result in "duplicate" matches in given some patterns.

If you can't use version 4 in your (or your clients') environments, you probably have to use Regexes.

The methods that support this are GetFiles(), GetDirectories(), and GetFileSystemEntries(). The Enumerate variants also support this.

The Danner