[英]c# Nested quantifier - multiple “?” in the pattern
我試圖查找目錄中是否至少有一個文件與模式匹配(僅使用“?”和“ *”通配符),但是某些組合會不斷拋出嵌套的限定符錯誤。 例如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次。
https://msdn.microsoft.com/zh-CN/library/az24scfc(v=vs.110).aspx
? 匹配上一個元素零或一次。 “ rai?n”,“ ran”,“ rain”
如果您使用Directory.GetFiles
內置的通配符(如@Ed Plunkett所述),則其工作方式應與您要查找的類似。
如果您仍想將當前方法與RegEx一起使用,請執行以下操作:
.*
-任意數量的字符 .{n}
-用期望的字符數替換n
.{m,n}
-用最少的預期字符數替換m
用最多的預期字符數替換n。 如果你需要 ”??” 要恰好匹配任何兩個字符,那么您是對的,您將必須使用正則表達式。 文件系統通配符對待“?” 為“零或任何字符之一”。
但是您無法按照您嘗試的方式進行操作,因為您是在向用戶詢問文件系統通配符-您只是在稍微改變一下語義。 您必須將用戶的字符串轉換為所需的正則表達式:
a???.*
必須成為
a.?.?.?\..*
對file
字符串執行此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()
是正確的:
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();
}
更新
在評論中,@ spender提供了一種更好,更干凈的方法來執行相同的操作:
var reStr = Regex.Escape(someWildcardThing).Replace(@"\?", ".").Replace(@"\*", ".*")
這些年來,除了自己仍然是一名正在恢復的C程序員之外,我沒有一個很好的借口不要自己這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.