也许我需要一个正则表达式?

时间:2011-05-14 07:27:43

标签: c# regex

我正在为一个家庭项目制作一个简单的控制台应用程序。基本上,它监视文件夹中是否有任何文件被添加。

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“AND”(NY“OR”NewYork“或”纽约“)。如果他们这样做,我会将它们移动到\Series\CSI\NY\文件夹。

我需要AND,因为另一个系列的另一个文件示例是:

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

所以,对于这个,我需要一些NOT。所以,我需要检查文件名是否有CSI,但不是(“纽约”或“纽约”或“纽约”)

有人可以协助我使用这些RegEx吗?或者,有更好的方法吗?

4 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:2)

我认为你有正确的想法。这种方法的好处是你可以添加/删除/编辑正则表达式到配置文件或其他方法,这意味着你不必每次想要跟踪新节目时重新编译项目。

CSI和NY的正则表达式看起来像这样。 首先,如果要检查文件名中是否存在CSI,则正则表达式只是"CSI"。请记住,默认情况下它区分大小写。 如果要检查文件名中是否存在NY,New York或NewYork,则正则表达式为"((NY)|(New York)|(NewYork))"条形表示OR,括号用于指定组。 为了将两者结合起来,你可以运行两个正则表达式,在某些情况下(可能顺序不重要)这可能更容易。但是,如果您始终期望在语法为"(CSI).*((NY)|(New York)|(NewYork))"之后显示类型,则句点表示“任何字符”,星号表示零或更多。

答案 2 :(得分:2)

这看起来并不像一个正则表达式,即使你成功将整个事情抛到了一体。匹配“没有给定单词的任何东西”的正则表达式是一种痛苦。对于每个规则,我最好坚持使用两个正则表达式:一个应匹配,另一个不匹配此规则将被触发。如果您需要“CSI”和“NY”但不喜欢修改文件名中的任何特定顺序,您也可以从一对正则表达式切换到一对正则表达式列表。通常,最好将此逻辑放入代码和配置中,并使正则表达式尽可能简单。是的,只要你保持代码足够聪明,你很可能会使用简单的子字符串搜索,不需要正则表达式。

答案 3 :(得分:2)

好吧,人们已经通过以下方式为您提供了一些建议:

  • 正则表达式
  • 完全存储并存储将对文件执行的C#代码

所以我只是给你一个不同的。

我不同意为此目的使用正则表达式。我同意@Anton S. Kraievoy:我不喜欢正则表达式来匹配任何没有给定单词的东西。检查更容易:!text.Contains(word)

如果您正在寻找快速解决方案,第二个选项看起来很完美,但是......

如果这是一个更复杂的应用程序,并且您想要正确设计它,我认为您应该:

  • 定义如何存储这些模式(在具有成员的类中,或在字符串中等)。字符串示例可能是:
    • "CSI" & ("NY" || "Las Vegas")
  • 然后编写一个与该模式匹配文件名的模块。

您正在创建一种DSL

为什么它比直接粘贴C#代码更好?

好吧,因为:

  • 您可以轻松更改模式的语义
  • 您可以使用您想要的任何语言生成验证代码,因为您以通用方式存储模式。

问题是如何将模式与文件名匹配。

你有一些选择:

  • 编写模式的语法并自己编写解析器
  • 生成(我不是100%确定是否可能,这取决于语法)写一个将你的语法转换为C#代码的正则表达式。
    例如:"A" & "B"string.Contains("A") && string.Contains("B")或类似的东西。
  • 使用工具执行此操作,例如ANTLR。