glob pattern matching in .NET

后端 未结 14 1424
遇见更好的自我
遇见更好的自我 2020-11-29 01:52

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 characte

14条回答
  •  醉梦人生
    2020-11-29 02:13

    I wrote a solution that does it. It does not depend on any library and it does not support "!" or "[]" operators. It supports the following search patterns:

    C:\Logs\*.txt

    C:\Logs\**\*P1?\**\asd*.pdf

        /// 
        /// Finds files for the given glob path. It supports ** * and ? operators. It does not support !, [] or ![] operators
        /// 
        /// the path
        /// The files that match de glob
        private ICollection FindFiles(string path)
        {
            List result = new List();
            //The name of the file can be any but the following chars '<','>',':','/','\','|','?','*','"'
            const string folderNameCharRegExp = @"[^\<\>:/\\\|\?\*" + "\"]";
            const string folderNameRegExp = folderNameCharRegExp + "+";
            //We obtain the file pattern
            string filePattern = Path.GetFileName(path);
            List pathTokens = new List(Path.GetDirectoryName(path).Split('\\', '/'));
            //We obtain the root path from where the rest of files will obtained 
            string rootPath = null;
            bool containsWildcardsInDirectories = false;
            for (int i = 0; i < pathTokens.Count; i++)
            {
                if (!pathTokens[i].Contains("*")
                    && !pathTokens[i].Contains("?"))
                {
                    if (rootPath != null)
                        rootPath += "\\" + pathTokens[i];
                    else
                        rootPath = pathTokens[i];
                    pathTokens.RemoveAt(0);
                    i--;
                }
                else
                {
                    containsWildcardsInDirectories = true;
                    break;
                }
            }
            if (Directory.Exists(rootPath))
            {
                //We build the regular expression that the folders should match
                string regularExpression = rootPath.Replace("\\", "\\\\").Replace(":", "\\:").Replace(" ", "\\s");
                foreach (string pathToken in pathTokens)
                {
                    if (pathToken == "**")
                    {
                        regularExpression += string.Format(CultureInfo.InvariantCulture, @"(\\{0})*", folderNameRegExp);
                    }
                    else
                    {
                        regularExpression += @"\\" + pathToken.Replace("*", folderNameCharRegExp + "*").Replace(" ", "\\s").Replace("?", folderNameCharRegExp);
                    }
                }
                Regex globRegEx = new Regex(regularExpression, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                string[] directories = Directory.GetDirectories(rootPath, "*", containsWildcardsInDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
                foreach (string directory in directories)
                {
                    if (globRegEx.Matches(directory).Count > 0)
                    {
                        DirectoryInfo directoryInfo = new DirectoryInfo(directory);
                        result.AddRange(directoryInfo.GetFiles(filePattern));
                    }
                }
    
            }
            return result;
        }
    

提交回复
热议问题