Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何检查文件名是否与通配符模式匹配_Regex_.net - Fatal编程技术网

Regex 如何检查文件名是否与通配符模式匹配

Regex 如何检查文件名是否与通配符模式匹配,regex,.net,Regex,.net,我有一个通配符模式,可能是“*.txt”或“POS???.dat” 我在内存中还有一个文件名列表,需要与该模式进行比较 请记住,我需要与IO.DirectoryInfo.GetFiles(模式)使用的语义完全相同的语义,我将如何做到这一点 编辑:盲目地将其转换为正则表达式是行不通的。您可以将通配符转换为正则表达式: *.txt -> ^.+\.txt$ POS??.dat _> ^POS..\.dat$ 使用Regex.Escape方法将非通配符的字符转义为模式的文字字符串(例如

我有一个通配符模式,可能是“*.txt”或“POS???.dat”

我在内存中还有一个文件名列表,需要与该模式进行比较

请记住,我需要与IO.DirectoryInfo.GetFiles(模式)使用的语义完全相同的语义,我将如何做到这一点


编辑:盲目地将其转换为正则表达式是行不通的。

您可以将通配符转换为正则表达式:

*.txt -> ^.+\.txt$

POS??.dat _> ^POS..\.dat$
使用
Regex.Escape
方法将非通配符的字符转义为模式的文字字符串(例如,将
“.txt”
转换为
“\.txt”

通配符
*
转换为
+
转换为

将^放在模式的开头以匹配字符串的开头,将$放在结尾以匹配字符串的结尾


现在,您可以使用
Regex.IsMatch
方法来检查文件名是否与模式匹配。

某种类型的Regex/glob是可行的,但有一些微妙之处;您的问题表明您希望与
IO.DirectoryInfo.GetFiles
具有相同的语义。这可能是一个挑战,因为涉及8.3与长文件名等特殊情况。整个故事正在上演

如果您不需要精确的行为匹配,那么有几个好问题:



请尝试下面的代码

static void Main(string[] args)
    {
        string _wildCardPattern = "*.txt";

        List<string> _fileNames = new List<string>();
        _fileNames.Add("text_file.txt");
        _fileNames.Add("csv_file.csv");

        Console.WriteLine("\nFilenames that matches [{0}] pattern are : ", _wildCardPattern);
        foreach (string _fileName in _fileNames)
        {
            CustomWildCardPattern _patetrn = new CustomWildCardPattern(_wildCardPattern);
            if (_patetrn.IsMatch(_fileName))
            {
                Console.WriteLine("{0}", _fileName);
            }
        }

    }

public class CustomWildCardPattern : Regex
{
    public CustomWildCardPattern(string wildCardPattern)
        : base(WildcardPatternToRegex(wildCardPattern))
    {
    }

    public CustomWildCardPattern(string wildcardPattern, RegexOptions regexOptions)
        : base(WildcardPatternToRegex(wildcardPattern), regexOptions)
    {
    }

    private static string WildcardPatternToRegex(string wildcardPattern)
    {
        string patternWithWildcards = "^" + Regex.Escape(wildcardPattern).Replace("\\*", ".*");
        patternWithWildcards = patternWithWildcards.Replace("\\?", ".") + "$";
        return patternWithWildcards;
    }
}
static void Main(字符串[]args)
{
字符串_wildCardPattern=“*.txt”;
列表_fileNames=新列表();
_添加(“text_file.txt”);
_添加(“csv_file.csv”);
WriteLine(“\n匹配[{0}]模式的文件名为:”,\u wildCardPattern);
foreach(文件名中的字符串文件名)
{
CustomWildCardPattern\u patetrn=新的CustomWildCardPattern(\u wildCardPattern);
if(_patetrn.IsMatch(_fileName))
{
WriteLine(“{0}”,_文件名);
}
}
}
公共类CustomWildCardPattern:Regex
{
公共CustomWildCardPattern(字符串wildCardPattern)
:base(WildcardPatternToRegex(wildCardPattern))
{
}
公共CustomWildCardPattern(字符串wildcardPattern、RegexOptions和RegexOptions)
:base(WildcardPatternToRegex(wildcardPattern),regexOptions)
{
}
私有静态字符串WildcardPatternToRegex(字符串wildcardPattern)
{
string patternWithWildcards=“^”+Regex.Escape(wildcardPattern).替换(“\\*”,“*”);
patternWithWildcards=patternWithWildcards。替换(“\\?”,“)+“$”;
返回带有通配符的模式;
}
}

我为您提供了一个完整的代码答案,95%类似于
FindFiles(string)

在该函数文档的第二个注释中,没有的5%是短名称/长名称行为

如果仍希望获得该行为,则必须完成对输入数组中每个字符串的短名称的计算,然后如果长名称或短名称与模式匹配,则将长名称添加到匹配集合中

代码如下:

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;
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Text.RegularExpressions;
命名空间findFileRegex
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串[]名称={“hello.t”、“hello.tx”、“hello.txt”、“hello.txtsjfhs”、“hello.tx.sdj”、“hAlLo20984.txt”};
字符串[]匹配;
matches=findfilesimulator(“hello.tx”,name);
matches=FindFileEmulator(“H*o*?”,名称);
matches=findfilesimulator(“hello.txt”,name);
matches=findFileEmulator(“lskfjd30”,名称);
}
公共字符串[]FindFileEmulator(字符串模式,字符串[]名称)
{
列表匹配项=新列表();
Regex Regex=FindFilesPatternToRegex.Convert(pattern);
foreach(名称中的字符串s)
{
if(regex.IsMatch(s))
{
匹配项。添加(s);
}
}
返回匹配项。ToArray();
}
内部静态类FindFilePatternToRegex
{
私有静态正则表达式HasQuestionMarkRegEx=新正则表达式(@“\?”,RegexOptions.Compiled);
私有静态正则表达式IllegalCharactersRegex=新正则表达式(“[“+@”\/:\ \”+“+“\”]”,RegexOptions.Compiled);
私有静态正则表达式catchExtensionRegex=新正则表达式(@“^\s*+\([^\.]+)\s*$”,RegexOptions.Compiled);
私有静态字符串NonDotCharacters=@“[^.]*”;
公共静态正则表达式转换(字符串模式)
{
if(pattern==null)
{
抛出新ArgumentNullException();
}
pattern=pattern.Trim();
if(pattern.Length==0)
{
抛出新ArgumentException(“模式为空”);
}
if(非法字符regex.IsMatch(模式))
{
抛出新ArgumentException(“模式包含非法字符”);
}
bool hasExtension=catchExtensionRegex.IsMatch(模式);
布尔匹配精确=假;
if(HasQuestionMarkRegEx.IsMatch(模式))
{
匹配精确=真;
}
else if(扩展名)
{
matchExact=catchExtensionRegex.Match(pattern).Groups[1]。长度!=3;
}
string regexString=Regex.Escape(模式);
regexString=“^”+Regex.Replace(regexString,@“\\\\*”,“*”);
regexString=Regex.Replace(regexString,@“\\\?”,“);
if(!matchExact&&hasExtension)
{
public class WildcardPattern : Regex {
    public WildcardPattern(string wildCardPattern)
        : base(ConvertPatternToRegex(wildCardPattern), RegexOptions.IgnoreCase) {
    }

    public WildcardPattern(string wildcardPattern, RegexOptions regexOptions)
        : base(ConvertPatternToRegex(wildcardPattern), regexOptions) {
    }

    private static string ConvertPatternToRegex(string wildcardPattern) {
        string patternWithWildcards = Regex.Escape(wildcardPattern).Replace("\\*", ".*");
        patternWithWildcards = string.Concat("^", patternWithWildcards.Replace("\\?", "."), "$");
        return patternWithWildcards;
    }
}
Directory.GetFiles(string path, string searchPattern)
using Microsoft.VisualBasic.CompilerServices;

if (Operators.LikeString("pos123.txt", "pos?23.*", CompareMethod.Text))
{
  Console.WriteLine("Filename matches pattern");
}
[Flags]
public enum MatchPatternFlags : uint
{
    Normal          = 0x00000000,   // PMSF_NORMAL
    Multiple        = 0x00000001,   // PMSF_MULTIPLE
    DontStripSpaces = 0x00010000    // PMSF_DONT_STRIP_SPACES
}

class FileName
{
    [DllImport("Shlwapi.dll", SetLastError = false)]
    static extern int PathMatchSpecExW([MarshalAs(UnmanagedType.LPWStr)] string file,
                                       [MarshalAs(UnmanagedType.LPWStr)] string spec,
                                       MatchPatternFlags flags);

    /*******************************************************************************
    * Function:     MatchPattern
    *
    * Description:  Matches a file name against one or more file name patterns.
    *
    * Arguments:    file - File name to check
    *               spec - Name pattern(s) to search foe
    *               flags - Flags to modify search condition (MatchPatternFlags)
    *
    * Return value: Returns true if name matches the pattern.
    *******************************************************************************/

    public static bool MatchPattern(string file, string spec, MatchPatternFlags flags)
    {
        if (String.IsNullOrEmpty(file))
            return false;

        if (String.IsNullOrEmpty(spec))
            return true;

        int result = PathMatchSpecExW(file, spec, flags);

        return (result == 0);
    }
}