我有一个路径问题,假设我有一个看起来像这样的路径:
示例 1 : C:\AAA\BBB\FolderOfInterest\CCC ile.txt
但也可以是这样的:
示例 2:C:\AAA\BBB\CCC\FolderOfInterest\DDD\EEE ile.txt
基本上“FolderOfInterest”前后的目录数是可变的。我知道感兴趣的文件夹的名称。
我想在感兴趣的文件夹中拆分路径并只获取它的结尾,结果将是:
我一直在尝试多种路径拆分和重组与字符串比较以获得正确文件夹的名称。但这一切看起来很乱。
谢谢
我建议在DirectoryInfo类的帮助下进行目录操作:让我们一个接一个地检查子文件夹,直到我们有
folderOfInterest
。如果你想要最右边的folderOfInterest
:
c:\A\FolderOfInterest\NotfolderOfInterest\B\folderOfInterest\C\data.txt
^ ^
leftmost rightmost
然后
using System.IO;
...
string path = @"C:\FolderOfInterest\DDD\EEE\file.txt";
string folderOfInterest = "FolderOfInterest";
// Assign the default value here (if folderOfInterest is not found)
string? result = path;
for (DirectoryInfo? di = new DirectoryInfo(path); di != null; di = di.Parent)
if (string.Equals(di.Name, folderOfInterest, StringComparison.OrdinalIgnoreCase)) {
result = Path.DirectorySeparatorChar +
Path.GetRelativePath(di.Parent.FullName, path);
break;
}
对于最左边的只是下降
break
:
using System.IO;
...
string path = @"C:\FolderOfInterest\DDD\EEE\file.txt";
string folderOfInterest = "FolderOfInterest";
// Assign the default value here (if folderOfInterest is not found)
string? result = path;
for (DirectoryInfo? di = new DirectoryInfo(path); di != null; di = di.Parent)
if (string.Equals(di.Name, folderOfInterest, StringComparison.OrdinalIgnoreCase)) {
result = Path.DirectorySeparatorChar +
Path.GetRelativePath(di.Parent.FullName, path);
}
对于一个强大而简单的解决方案,您可以按目录分隔符进行拆分:
string path = @"C:\AAA\BBB\FolderOfInterest\CCC\file.txt";
string folderOfInterest = "FolderOfInterest";
var directories = path.Split('\\')
.SkipWhile(x => x != folderOfInterest);
var result = string.Join('\\', directories);
//If you need a initial \ add it:
//var result = @"\" + string.Join('\\', directories);
注意:这可能会使用更多内存并且比其他解决方案更慢,但在大多数应用程序中它不会产生巨大差异。
另一个想法是使用
Uri
。这将找到第一次出现:
string GetSubdirectoryPath(string path, string dirName)
{
if (path == null) throw new ArgumentNullException(nameof(path));
if (dirName == null) throw new ArgumentNullException(nameof(dirName));
if (path.IndexOf(dirName, StringComparison.InvariantCultureIgnoreCase) >= 0)
{
var segments = new Uri(path).Segments;
var matchingSegments = segments
.SkipWhile(p => !string.Equals(p, $"{dirName}/", StringComparison.InvariantCultureIgnoreCase))
.Select(p => p.Replace('/', Path.DirectorySeparatorChar));
string result = Path.DirectorySeparatorChar + string.Join("", matchingSegments);
return result;
}
return path;
}
用法:
string path = "C:\\AAA\\BBB\\FolderOfInterest\\CCC\\file.txt";
string dirName = "FolderOfInterest";
string result = GetSubdirectoryPath(path,dirName);
Substring()
方法。这并不完全可靠,因为如果目标文件夹名称在路径中出现不止一次,您需要另外确定在这种情况下如何搜索最终路径。
首先,您需要使用
IndexOf
方法在路径中找到感兴趣的文件夹的索引。然后,您可以使用 Substring
方法创建一个从感兴趣的文件夹的索引开始到路径末尾的子字符串。
string path = "C:\\AAA\\BBB\\FolderOfInterest\\CCC\\file.txt";
string folderOfInterest = "FolderOfInterest";
int index = path.IndexOf(folderOfInterest);
string result = path.Substring(index);
以下所有代码添加都将与下一个特殊情况的处理相关:
C:\AAA\BBB\NotTheFolderOfInterest\FolderOfInterest\CCC\file.txt
C:\AAA\BBB\FolderOfInterestNotReally\CCC\FolderOfInterest\DDD\EEE\file.txt
C:\AAA\BBB\FolderOfInterest\NotTheFolderOfInterest\CCC\file.txt
C:\AAA\BBB\FolderOfInterest\CCC\FolderOfInterestNotReally\DDD\EEE\file.txt
要正确处理这种情况,代码必须更复杂。您可以遍历路径段并查找感兴趣的文件夹。找到感兴趣的文件夹后,您可以通过连接路径的其余部分来构建新路径。
string folderOfInterest = "FolderOfInterest";
string path = @"C:\AAA\BBB\NotTheFolderOfInterest\FolderOfInterest\CCC\file.txt";
// Split the path into array of segments
var segments = path.Split('\\');
// Find the index of the folder of interest
var folderIndex = Array.IndexOf(segments, folderOfInterest);
// If the folder of interest is found then join the string back from the array but skip unnecessary items
if (folderIndex != -1)
{
var newPath = string.Join("\\", segments.Skip(folderIndex));
}
您可以使用
IndexOf
检查感兴趣的文件夹名称的第一个实例,然后使用 SubString
返回您想要的结果。请注意,为了以这种方式可靠地检查“FolderOfInterest”名称,我使用了目录分隔符\
。这避免了诸如“MyFolderOfInterest”或“FolderOfInterestButNotReally”之类的冲突问题,但是如果文件夹名称位于字符串的开头或结尾而没有前后分隔符,它将不起作用。在这种情况下这可能没问题,因为您的示例路径是完全限定的并且指向文件而不是目录。
var path = @"C:\AAA\BBB\FolderOfInterest\CCC\file.txt";
var result = path.Substring(path.IndexOf(@"\FolderOfInterest\"));
上面的例子没有考虑文件夹名称不存在的情况,所以你可能想先检查它是否存在:
var path = @"C:\AAA\BBB\FolderOfInterest\CCC\file.txt";
var folderToFind = @"\FolderOfInterest\";
if (path.Contains(folderToFind)) {
var result = path.Substring(path.IndexOf(folderToFind));
}
另一种解决方案是
Split
文件夹并使用 SkipWhile (System.Linq)
更直接地识别“FolderOfInterest”的第一个实例之后的所有文件夹。即使命名文件夹位于字符串的开头或结尾而没有前后分隔符,此解决方案也将起作用:
var path = @"C:\AAA\BBB\FolderOfInterest\CCC\file.txt";
var folderToFind = "FolderOfInterest";
var folders = path.Split('\\');
var values = folders.SkipWhile(folder => folder != folderToFind);
var result = @"\" + string.Join(@"\", values);