2011-05-14 34 views
3

我正在爲家庭項目製作一個簡單的控制檯應用程序。基本上,它監視一個文件夾是否添加了任何文件。也許我需要一個正則表達式?

FileSystemWatcher fsw = new FileSystemWatcher(@"c:\temp"); 
fsw.Created += new FileSystemEventHandler(fsw_Created); 

bool monitor = true; 

while (monitor) 
{ 
    fsw.WaitForChanged(WatcherChangeTypes.Created, 1000); 
    if(Console.KeyAvailable) 
    { 
     monitor = false; 
    } 
} 

Show("User has quit the process...", ConsoleColor.Yellow); 

當一個新的文件到達時,「WaitForChanges」被調用,然後我就可以開始工作。

我需要做的是檢查模式的文件名。在現實生活中,我將視頻文件放入此文件夾中。基於文件名,我將有規則,將文件移動到特定的目錄中。所以現在,我將有一個KeyValue對的列表...持有RegEx(我認爲?)和一個文件夾。所以,如果文件名與正則表達式匹配,它會將它移動到相關的文件夾中。

文件名的一個例子是:

CSI- NY.S07E01.The 34th Floor.avi 

所以,我的正則表達式需要看它,看看的話CSI「和」(NY「或」紐約「或」紐約)存在。如果他們這樣做,我會將它們移動到\Series\CSI\NY\文件夾。

我所需要的,並且由於不同系列的另一個文件的例子是:

CSI- Crime Scene Investigation.S11E16.Turn On, Tune In, Drop Dead 

所以,這一個,我需要有若干註記。所以,我需要檢查文件名是否有CSI,但不是(「紐約」或「NY」或「紐約」)

有人可以幫助我使用這些RegEx嗎?或者,也許有更好的方法?

回答

2

我認爲你有正確的想法。這種方法的好處在於,您可以將正則表達式添加/刪除/編輯到配置文件或其他方法,這意味着您不必每次重新編譯項目時都需要跟蹤新的演出。

CSI和NY的正則表達式看起來像這樣。 首先,如果你想檢查CSI是否存在於文件名中,那麼正則表達式只不過是"CSI"。請記住它默認情況下區分大小寫。 如果要檢查文件名中是否存在NY,New York或NewYork,則正則表達式爲"((NY)|(New York)|(NewYork))"條形圖指示OR,括號用於指定組。 爲了將兩者結合起來,你可以運行兩個正則表達式,並且在某些情況下(可能順序不重要),這可能會更容易。但是,如果您總是希望顯示類型出現在語法後面,那麼該句號表示「任何字符」,星號表示零或更多。

+0

嗯。在我看來,我真的不認爲正則表達式是在這種情況下最好的選擇:(在數 – 2011-05-14 07:42:33

+0

採取順序相匹配,我的意思是,你會如何表達'str.Contains(「A」)&& str.Contains(「B」)'與正則表達式? – 2011-05-14 08:09:05

+0

@Oscar - 我不確定它是否也是。但是正則表達式很有用,OP至少在考慮它們時是正確的 – 2011-05-14 09:08:28

3

你可以嘗試儲存條件Func<string,bool>

Dictionary<Func<string,bool>,string> dic = new Dictionary<Func<string, bool>, string>(); 
Func<string, bool> f1 = x => x.Contains("CSI") && ((x.Contains("NY") || x.Contains("New York")); 

dic.Add(f1,"C://CSI/"); 

foreach (var pair in dic) 
{ 
    if(pair.Key.Invoke("CSI- NY.S07E01.The 34th Floor.avi")) 
    { 
     // copy 
     return; 
    } 
} 
+0

打我吧:) – 2011-05-14 07:41:21

2

這看起來並不是一個正則表達式,即使你把整個事情整合到一起也能成功。匹配「沒有給定單詞的任何東西」的正則表達式是一種痛苦。對於每個規則,我最好堅持兩個正則表達式:一個應該匹配,另一個不應匹配此規則觸發。如果你需要你的「CSI」和「NY」,但不喜歡在文件名中修改任何特定的順序,你也可以從一對正則表達式切換到一對正則表達式列表。一般來說,最好將這個邏輯放入代碼和配置中,並儘可能簡化regexes。是的,只要你的代碼足夠聰明,你很可能會用簡單的子字符串搜索,而不需要明確的正則表達式。

2

嘛,人家已經給你一些建議有關執行此操作使用:

  • 正則表達式
  • Func鍵和存儲正是將針對該文件執行

所以C#代碼我我只是給你一個不同的。

我不同意爲此使用正則表達式。我同意@Anton S. Kraievoy:我不喜歡正則表達式來匹配任何沒有給定單詞的東西。這是比較容易檢查:!text.Contains(word)

第二個選項看起來完美的,如果你正在尋找一個快速的解決方案,但是......

如果是更復雜的應用程序,並且要正確地設計它,我認爲你應該:

  • 定義你將如何存儲這些模式(在一個類的成員,或在一個字符串等)。一個字符串,例如可能是:
    • "CSI" & ("NY" || "Las Vegas")
  • 然後寫一個模塊,將匹配該模式的文件名。

您正在創建一種DSL

爲什麼比直接粘貼C#代碼更好?

嗯,因爲:

  • 你可以很容易地改變語義的你的模式
  • 您可以生成你想要的任何語言的驗證代碼,因爲你存儲在通用方式模式。

問題是如何將模式與文件名匹配。

你有一些選擇:

  • 寫你的模式的語法和自己
  • 寫一個解析器生成(我不是100%肯定,如果有可能,這取決於語法)編寫一個將您的語法轉換爲C#代碼的正則表達式。
    贊:"A" & "B"string.Contains("A") && string.Contains("B")或類似的東西。
  • 使用一個工具來做到這一點,就像ANTLR。
+0

謝謝奧斯卡·梅德羅斯 - 這真的很不錯...手工做這似乎很容易...謝謝。 – Craig 2011-05-14 22:07:15