简体   繁体   English

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

[英]Best way to extract substring from directory path

I have below strings 我有下面的字符串

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"

I need to extract string till V1.2 or V3 or V3.6 like below, 我需要提取字符串直到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\"

What should be the best way, regex? 正则表达式应该是最好的方法是什么?

Regex.Split(str1, @"(?<=\\)(v|V)\d+(\.\d+)?\\")[0]
  • (<?=\\\\) is look behind for \\ , making sure version is a directory name. (<?=\\\\)\\后面,确保版本是目录名。
  • (v|V) case-intensive (v|V)区分大小写
  • \\d+ a number \\d+一个数字
  • (\\.\\d+)? may not have minor version 可能没有次要版本
  • \\\\ ending path splitor. \\\\结束路径分隔符。

If you don't want to deal with manual path parsing, you can use .NET to do the heavy lifting: 如果您不想处理手动路径解析,则可以使用.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;
}

In English, take the deepest folder in the path, verify if it's in the version string format, if not, repeat with the parent folder. 用英语,在路径中找到最深的文件夹,验证其是否为版本字符串格式,如果不是,请与父文件夹重复。 If it is a version string, take the full path of the parent folder. 如果是版本字符串,请使用父文件夹的完整路径。 If we reach the root folder, return null (no version string in path). 如果到达根文件夹,则返回null (路径中没有版本字符串)。

You can tweak VersionRegex to accept exactly the kinds of version strings you want to consider. 您可以调整VersionRegex以完全接受您要考虑的版本字符串。 Of course, the whole algorithm is only as reliable as your assumption that there's only one folder that fits the version string format between the full path and the root you're trying to find. 当然,整个算法的可靠性仅与您假设在整个路径和要查找的根目录之间只有一个适合版本字符串格式的文件夹一样可靠。

There's probably simpler code that fits your actual requirements. 可能有更简单的代码可以满足您的实际需求。 For the strings you've actually posted, simply going two directories up in the structure would also suffice. 对于您实际发布的字符串,只需在结构中上移两个目录就足够了。 But as it is often said, if you can precisely formulate your requirements, you probably also have the solution already :) Given that you've given no reasoning behind what you're trying to do, it's quite possible this is an XY problem. 但是正如人们常说的那样,如果您可以精确地提出自己的要求,那么您可能也已经有了解决方案:)鉴于您没有给出要做什么背后的理由,很可能这是一个XY问题。

You can split by '\\' then use a regex to find the exact match. 您可以用'\\'分隔,然后使用正则表达式查找完全匹配。

Test the version regex ^v[0-9]*(\\.[0-9]{1,2})?$ here . 此处测试版本regex ^v[0-9]*(\\.[0-9]{1,2})?$ I have assumed that your version will have upto two decimal places. 我假设您的版本最多可以保留两位小数。

You can try like this: 您可以这样尝试:


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));
    }
}

Outputting: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM