【问题标题】:Regex - C# - Get non matching part of string正则表达式 - C# - 获取字符串的不匹配部分
【发布时间】:2017-11-19 17:58:25
【问题描述】:

我在下面写的正则表达式模式匹配“FinalFolder”之前的字符串。 如何在匹配正则表达式的字符串之后获取文件夹名称(在本例中为“FinalFolder”)?

编辑:很确定我的正则表达式错了。我的意图是匹配“C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF”,然后找到该文件夹​​。所以,在这种情况下,我正在寻找的文件夹是“FinalFolder”

    [TestMethod]
    public void TestRegex()
    {
        string pattern = @"[A-Za-z:]\\[A-Za-z]{1,}\\[A-Za-z]{1,}\\[A-Za-z0-9]{1,}\\[A-Za-z0-9]{1,}\\[A-Za-z0-9._s]{1,}\\[A-Za-z]{1,}\\[A-Za-z]{1,}";
        string textToMatch = @"C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF\FinalFolder\Subfolder\Test.txt";
        string[] matches = Regex.Split(textToMatch, pattern);
        Console.WriteLine(matches[0]);
    }

【问题讨论】:

  • 您的正则表达式似乎匹配整个字符串,而不仅仅是“FinalFolder”之前的字符串。
  • 模式与字符串不匹配。你找到匹配了吗?
  • 我会使用子字符串。像textToMatch.Substring(textToMatch.IndexOf(matches[0]) + matches[0].Length) 这样的东西。一旦你有了那个子字符串,你就可以匹配其中的第一个斜杠。
  • 总的来说,我认为 Regex 不适合这项工作,但无论如何。
  • 您可以根据对路径的了解有几种方法。如果级别是固定的^(?:[^\\]*\\){level}(.*)$,如果名称是固定的^(?:[^\\]*\\)*FolderF\\(.*)$,我想这是唯一的办法。

标签: c# regex


【解决方案1】:

还有许多其他提示和建议可以引导您获得所需的文件夹,我建议您考虑一下。但是,由于看起来您仍然可以从学习更多正则表达式技能中受益,所以这是您要求的答案:Getting non-matching part of string

让我们假设您的正则表达式实际上匹配给定的路径,例如:[A-Za-z]:\\[A-Za-z]+\\[A-Za-z]+\\[A-Za-z0-9]+\\[A-Za-z0-9]+\\[A-Za-z0-9._\s]+\\[A-Za-z]+\\[A-Za-z]+

您可以获取匹配的字符串、其位置和长度,然后确定下一个文件夹名称在原始源字符串中的哪个位置开始。但是您还需要确定下一个文件夹名称的结束位置。

MatchCollection matches = Regex.Matches(textToMatch, pattern);
if (matches.Count > 0 ) {
    Match m = matches[0];
    var remaining = textToMatch.Substring(m.Index + m.Length);
    //Now find the next backslash and grab the leftmost part...
}

这回答了您最普遍的问题,但这种方法破坏了使用正则表达式的整个实用程序。相反,只需扩展您的模式以匹配下一个文件夹!

正则表达式模式已经提供了捕获匹配的某些部分的能力。用于捕获文本的默认正则表达式构造是一组括号。更好的是,.Net 正则表达式支持使用(?<name>) 命名的捕获

//using System.Text.RegularExpressions;

string pattern = @"(?<start>"  
        + @"[A-Za-z]:\\[A-Za-z]+\\[A-Za-z]+\\[A-Za-z0-9]+\\[A-Za-z0-9]+\\[A-Za-z0-9._\s]+\\[A-Za-z]+\\[A-Za-z]+" 
        + @")\\(?<next>[A-Za-z0-9._\s]+)(\\|$)";
string textToMatch = @"C:\FolderA\FolderB\FolderC\FolderD\Test 1.0\FolderE\FolderF\FinalFolder\Subfolder\Test.txt";

MatchCollection matches = Regex.Matches(textToMatch, pattern);
if (matches.Count > 0 ) {
    var nextFolderName = matches[0].Groups["next"];
    Console.WriteLine(nextFolderName);
}

【讨论】:

    【解决方案2】:

    正如评论中所发布的,您的正则表达式似乎与整个字符串匹配。但在这种特殊情况下,由于您正在处理文件名,我会使用 FileInfo。

    FileInfo fi = new FileInfo(textToMatch);
    Console.WriteLine(fi.DirectoryName);
    Console.WriteLine(fi.Directory.Name);
    

    DirectoryName 将是完整路径,而Directory.Name 将只是相关子文件夹。

    【讨论】:

    • 抱歉 - 我正在寻找匹配字符串之后的文件夹。不是文件的父文件夹。再次抱歉,我更新了问题。
    【解决方案3】:

    那么,使用FileInfo,是这样的吗?

    (new FileInfo(textToMatch)).Directory.Parent.Name
    

    【讨论】:

      猜你喜欢
      • 2021-02-09
      • 2014-12-30
      • 1970-01-01
      • 2020-04-01
      • 2010-09-15
      • 1970-01-01
      • 2011-12-21
      • 2012-11-25
      • 2015-10-25
      相关资源
      最近更新 更多