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

本文关键字:一个 正则表达式 也许 | 更新日期: 2023-09-27 17:56:20

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

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"被调用,然后我可以开始工作。

我需要做的是检查文件名的模式。在现实生活中,我将视频文件放入此文件夹。根据文件名,我将有规则,将文件移动到特定目录中。所以现在,我将有一个键值对的列表...拿着一个正则表达式(我想?)和一个文件夹。因此,如果文件名与正则表达式匹配,则会将其移动到相关文件夹中。

文件名的一个示例是:

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

所以,我的正则表达式需要查看它,看看CSI"和"(NY"或"New York "OR"New York)是否存在。如果他们这样做,我会将它们移动到'Series'CSI'NY'文件夹中。

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

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

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

有人可以帮助我处理这些正则表达式吗?或者,也许,有更好的方法?

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

您可以尝试将条件存储在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;
    }
}

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

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

这看起来不像一个正则表达式,即使您成功地将整个内容扔进一个正则表达式中。匹配"没有给定单词的任何内容"的正则表达式是一种痛苦。我最好为每个规则坚持使用两个正则表达式:一个应该匹配,另一个不应该匹配以触发此规则。如果您需要"CSI"和"NY",但不喜欢在文件名中固定任何特定顺序,您也可以从一对正则表达式切换到一对正则表达式列表。通常,最好将此逻辑放入代码和配置中,并使正则表达式尽可能简单。是的,你很可能摆脱简单的子字符串搜索,只要你保持代码足够智能,就不需要正则表达式。

好吧,人们已经给了你一些关于使用以下命令执行此操作的建议:

  • 正则表达式
  • 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。
相关文章: