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