我试图查找目录中是否至少有一个文件匹配模式(仅使用“?”和“*”通配符),但某些组合会继续抛出嵌套限定符错误。例如 - TestCashFile_10_12-25-2016????????.c??
不起作用。
模式来自非技术用户(他们受过这两个通配符的基本用法教育)所以“?”并且“*”可以在文件名中的任何位置进行,我没有太多控制权。
这些模式有什么问题?
这是运行此正则表达式的C#代码段 -
string fileName = C:\TestFiles\TestCashFile_10_12-25-2016????????.c??'
string directory = Path.GetDirectoryName(fileName);
string[] temp = fileName.Split('\\');
string file = temp[temp.Length - 1];
var found = Directory.GetFiles(directory).Any(p => Regex.Match(p, file).Success);
更新 - 这个问题已经解决,但是如果它帮助其他人寻找类似的东西,只是为了澄清 - 在这种情况下,我想要“?”意味着必须只有一个元素(而不是零或一个元素)。
答案 0 :(得分:1)
?
运算符指定前一个元素可以出现0或1次。
https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx
?匹配前一个元素零次或一次。 " RAI N'#34?; "跑","下雨"
如果您使用Directory.GetFiles
内置的通配符,如@Ed Plunkett所说,它应该与您要查找的内容类似。
如果您仍想在RegEx中使用当前方法,请执行以下操作:
.*
- 任意数量的字符.{n}
- 将n
替换为预期字符数.{m,n}
- 将m
替换为最小预期字符数,将n替换为最大预期字符数。答案 1 :(得分:1)
如果你需要“??”要匹配任何一个字符中的两个然后你是对的,你将不得不使用正则表达式。文件系统通配符对待“?”作为“零或任何一个角色”。
但是你不能按照你想要的方式去做,因为你要求你的用户使用文件系统通配符 - 你只是稍微改变了语义。你必须将用户的字符串转换为你想要的正则表达式:
int startIndex = 0;
for (int i = 0; i < 10; i++)
{
foreach (DataRow rows in selectedDataRow.Skip(startIndex).Take(20))
{
smsRecordId += rows["activityid"].ToString() + ",";
smsSubject = rows["subject"].ToString();
mobileNum += rows["telephone1"].ToString() + ",";
}
startIndex += 20;
}
必须成为
a???.*
对a.?.?.?\..*
字符串执行此操作,file
应该有效。
如果事情在运行时变得有点慢,你可能想要编译正则表达式:
.Any(p => Regex.Match(p, file).Success);
我认为这适用于file = TranslateWildcardsToRegex(file);
var re = new Regex(file);
var found = Directory.GetFiles("").Any(p => re.IsMatch(p));
:
TranslateWildcardsToRegex()
<强>更新强>
在评论中@spender提供了一种更好,更清晰的方法来做同样的事情:
public static String TranslateWildcardsToRegex(String s)
{
StringBuilder sb = new StringBuilder();
foreach (var ch in s)
{
switch (ch)
{
case '?':
sb.Append(".");
break;
case '*':
sb.Append(".*");
break;
// Escape a variety of characters that
// mean something special in a regex
case '(':
case ')':
case '{':
case '}':
case '[':
case ']':
case '.':
sb.Append("\\" + ch);
break;
default:
sb.Append(ch);
break;
}
}
return sb.ToString();
}
在这些年之后,除了仍然是一名正在恢复的C程序员之外,我没有任何理由不这样做。