【问题标题】:Equivalent of PathMatchSpec for .NET.NET 的 PathMatchSpec 等价物
【发布时间】:2010-10-31 13:34:02
【问题描述】:

有谁知道 .NET 中是否有与 Windows API 函数 PathMatchSpec() 等效的功能?

【问题讨论】:

    标签: .net search


    【解决方案1】:

    我不知道 .NET 内置的方法,但是用正则表达式复制是微不足道的:

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

    显然,这假定引用了 System.Text.RegularExpressions 命名空间。如果您要使用相同的规范执行此操作,您也可以缓存正则表达式。

    编辑添加:P/Invoke 确实是一个选项,但 PathMatchSpec 的签名表明它需要一个 ANSI 字符串,因此每次调用都会发生字符集转换。如果你走那条路,请记住这一点。在那种情况下,PathMatchSpecEx 可能会更好。

    【讨论】:

    • 酷...自己不知道 Escape() 方法;肯定会简化我的部分解决方案;)
    【解决方案2】:

    如果您无法使用正则表达式获得功能(我相信是这种情况),如何通过 PInvoke 使用 PathMatchSpec()?

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

    【讨论】:

      【解决方案3】:

      您可以尝试 How to implement glob in C# ,如果需要,当然还有PInvoke route

      【讨论】:

        【解决方案4】:

        简而言之...我不知道...但也许这可以帮助您(注意,比您想要的要长一点,但它对我很有帮助):

        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;
            }
        }
        

        【讨论】:

        • 请注意,使用 anelsons 'Regex.Escape()' 转义代码绝对可以简化。
        猜你喜欢
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-28
        • 2011-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多