从目录路径提取子字符串的最佳方法

时间:2019-03-21 11:36:41

标签: c#

我下面有字符串

str1 = "C:\Program Files (x86)\Server\Client\v1.2\Service\test.exe"
str1 = "C:\Program Files (x86)\Server\v1.2\Service\test.exe"
str1 = "C:\Program Files (x86)\Server\v3\Service\test.exe"
str1 = "C:\Program Files (x86)\Client\v3.6\Service\test.exe"

我需要提取字符串直到V1.2V3V3.6,如下所示,

str1 = "C:\Program Files (x86)\Server\Client\"
str1 = "C:\Program Files (x86)\Server\"
str1 = "C:\Program Files (x86)\Server\"
str1 = "C:\Program Files (x86)\Client\"

正则表达式是最好的方法是什么?

3 个答案:

答案 0 :(得分:3)

cert_store_stats
  • Regex.Split(str1, @"(?<=\\)(v|V)\d+(\.\d+)?\\")[0] (<?=\\)后面,确保版本是目录名。
  • \区分大小写
  • (v|V)一个数字
  • \d+可能没有次要版本
  • (\.\d+)?结束路径分割符。

答案 1 :(得分:1)

如果不想处理手动路径解析,则可以使用.NET进行繁重的工作:

static readonly Regex VersionRegex = new Regex(@"^v\d+(\.\d+)?$", 
                                               RegexOptions.Compiled | RegexOptions.IgnoreCase);

public static string SkipToApplicationRoot(string path)
{
  var di = new DirectoryInfo(path);

  while (di.Parent != null)
  {
    // If the current directory is a version string, return the path to the parent directory
    if (VersionRegex.IsMatch(di.Name)) return di.Parent.FullName;

    di = di.Parent;
  }

  // No version string in the path
  return null;
}

用英语,在路径中找到最深的文件夹,确认它是否为版本字符串格式,如果不是,请与父文件夹重复。如果是版本字符串,请使用父文件夹的完整路径。如果我们到达根文件夹,则返回null(路径中没有版本字符串)。

您可以调整VersionRegex以完全接受您要考虑的版本字符串。当然,整个算法的可靠性仅与您假设在整个路径和要查找的根目录之间只有一个适合版本字符串格式的文件夹一样可靠。

可能有更简单的代码可以满足您的实际需求。对于您实际发布的字符串,只需在结构中上移两个目录就足够了。但是正如人们常说的那样,如果您可以精确地提出自己的要求,那么您可能也已经有了解决方案:)鉴于您没有给出要做什么背后的理由,很可能这是一个XY问题。

答案 2 :(得分:0)

您可以用'\'分隔,然后使用正则表达式查找完全匹配。

测试版本正则表达式^v[0-9]*(\.[0-9]{1,2})?$ here。 我以为您的版本最多可以保留两位小数。

您可以尝试以下操作:


static void Main(string[] args)
{
    string str1 = @"C:\Program Files (x86)\Server\Client\v1.2\Service\test.exe";
    string str2 = @"C:\Program Files (x86)\Server\v1.2\Service\test.exe";
    string str3 = @"C:\Program Files (x86)\Server\v3\Service\test.exe";
    string str4 = @"C:\Program Files (x86)\Client\v3.6\Service\test.exe";

    List<string> versions = FetchVersionPaths(str1, str2, str3, str4).ToList();

    versions.ForEach(Console.WriteLine);
}

public static IEnumerable<string> FetchVersionPaths(params string[] DirectoryPaths)
{
    foreach (string directoryPath in DirectoryPaths)
    {
        // Version regex to check upto two decimal places
        Regex versionRegex = new Regex(@"^v[0-9]*(\.[0-9]{1,2})?$");

        List<string> destructuredPaths = directoryPath.Split(Path.DirectorySeparatorChar).ToList();

        // Find the index upto version
        int versionSplitIndex = destructuredPaths.FindIndex(versionRegex.IsMatch);

        // Now get the range of the destructured paths and join them by '\'
        yield return string.Join(new string(Path.DirectorySeparatorChar, 1), destructuredPaths.GetRange(0, versionSplitIndex));
    }
}

输出:

C:\Program Files (x86)\Server\Client
C:\Program Files (x86)\Server
C:\Program Files (x86)\Server
C:\Program Files (x86)\Client