Эквивалент PathMatchSpec для .NET - PullRequest
1 голос
/ 05 июня 2009

Кто-нибудь знает, существует ли эквивалентная функциональность для функции Windows API PathMatchSpec() в .NET?

Ответы [ 4 ]

0 голосов
/ 05 июня 2009

Короче говоря ... не то, что я знаю ... но, может быть, это может помочь вам (заметьте, немного длиннее, чем вы могли бы хотеть, но это мне хорошо послужило):

sealed public class WildcardMatch
{
    private static Regex wildcardFinder = new Regex(@"(?<wildcards>\?+|\*+)", RegexOptions.Compiled | RegexOptions.Singleline);
    private Regex wildcardRegex;

    public WildcardMatch(string wildcardFormat) : this(wildcardFormat, false) { }

    public WildcardMatch(string wildcardFormat, bool ignoreCase)
    {
        if (wildcardFormat == null)
            throw new ArgumentNullException("wildcardFormat");

        StringBuilder patternBuilder = new StringBuilder("^");
        MatchCollection matches = this.wildcardFinder.Matches(wildcardFormat);
        string[] split = this.wildcardFinder.Split(wildcardFormat);
        for (int ix = 0; ix < split.Length; ix++)
        {
            // Even indexes are literal text, odd indexes correspond to matches
            if (ix % 2 == 0)
                patternBuilder.Append(Regex.Escape(split[ix]));
            else
            {
                // Matches must be substituted with Regex control characters
                string wildcards = matches[ix / 2].Groups["wildcards"].Value;
                if (wildcards.StartsWith("*", StringComparison.Ordinal))
                    patternBuilder.Append("(.*)");
                else
                    patternBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", wildcards.Replace('?', '.'));
            }
        }
        patternBuilder.Append("$");

        this.wildcardRegex = new Regex(
            patternBuilder.ToString(),
            RegexOptions.Singleline | (ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None));
    }

    public bool IsMatch(string value)
    {
        if (value == null)
            return false;

        return this.wildcardRegex.IsMatch(value);
    }

    public IEnumerable<string> ExtractMatches(string value)
    {
        if (value == null)
            yield break;

        Match match = this.wildcardRegex.Match(value);
        if (!match.Success)
            yield break;

        for (int ix = 1; ix < match.Groups.Count; ix++)
            yield return match.Groups[ix].Value;
    }
}
0 голосов
/ 05 июня 2009

Вы можете попробовать Как реализовать glob в C # или, конечно, есть PInvoke маршрут , если необходимо.

0 голосов
/ 05 июня 2009

Я не знаю о методе, встроенном в .NET, но дублировать его с помощью регулярных выражений тривиально:

public static bool PathMatchSpec(String path, String spec)
{
    String specAsRegex = Regex.Escape(spec).Replace("\\*", ".*").Replace("\\?", ".") + "$";
    return Regex.IsMatch(path, specAsRegex);
}

Очевидно, это предполагает, что на пространство имен System.Text.RegularExpressions есть ссылка. Если вы собираетесь делать это с той же спецификацией, вы также можете кэшировать Regex.

EDIT TO ADD: P / Invoke действительно является опцией, но подпись для PathMatchSpec указывает, что она принимает строку ANSI, поэтому вам придется выполнять преобразование набора символов для каждого вызова. Имейте это в виду, если вы идете по этому пути. В этом случае PathMatchSpecEx , вероятно, будет предпочтительным.

0 голосов
/ 05 июня 2009

Если вы не можете получить функциональность с помощью регулярных выражений (я полагаю, что это так), как насчет использования PathMatchSpec () через PInvoke?

http://www.pinvoke.net/default.aspx/shlwapi/PathMatchSpec.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...