使用C#正则表达式从完整路径中解析文件名

21

如何使用C#中的正则表达式从完整路径中提取文件名?

假设我有完整路径 C:\CoolDirectory\CoolSubdirectory\CoolFile.txt

如何使用.NET风格的正则表达式获取CoolFile.txt?我对正则表达式不是很熟练,我和我的RegEx小伙伴都无法解决这个问题。

另外,在尝试解决这个问题的过程中,我意识到我可以使用System.IO.Path.GetFileName,但我无法找出正则表达式的答案,这让我感到不满意,直到我知道答案之前,这件事会一直困扰着我。


17
你想知道如何使用正则表达式来解决问题也没关系,但为了让这个世界变得更美好,请保证你会使用 Path.* 吧 :) - OregonGhost
如果您正在使用长路径,则GetFileName可能不是一个选项。 - Ufuk Hacıoğulları
正则表达式有其优点和缺点:http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html - benPearce
6个回答

40

为什么必须使用正则表达式?.NET具有内置的Path.GetFileName()方法,专门用于跨平台和文件系统的处理。


你没有仔细阅读问题。他知道GetFileName(),但想知道如何使用正则表达式来实现。 - Kon
5
当我发表我的答案时,那个句子还没有出现。 - Dour High Arch
3
那就随意忽略我吧。 :) - Kon

21
//  using System.Text.RegularExpressions;

/// <summary>
///  Regular expression built for C# on: Tue, Oct 21, 2008, 02:34:30 PM
///  Using Expresso Version: 3.0.2766, http://www.ultrapico.com
///  
///  A description of the regular expression:
///  
///  Any character that is NOT in this class: [\\], any number of repetitions
///  End of line or string
///  
///
/// </summary>
public static Regex regex = new Regex(
      @"[^\\]*$",
    RegexOptions.IgnoreCase
    | RegexOptions.CultureInvariant
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );

更新:移除了斜杠


1
你意识到这将会得到"\CoolFile.txt"。 - dlamblin
好的,很棒,我没有想到当我测试它时斜杠不应该在那里。 - bdukes

7

下面是一种方法:

string filename = Regex.Match(filename, @".*\\([^\\]+$)").Groups[1].Value;

基本上,它匹配的是最后一个反斜杠和字符串结尾之间的所有内容。当然,如你所提到的,使用Path.GetFileName()会更容易,并且可以处理很多麻烦的边缘情况,这些情况使用正则表达式很难处理。


+1,因为我用它解决了一个Perl正则表达式问题。谢谢。 - Joe Internet

7

更简短:

string filename = Regex.Match(fullpath, @"[^\\]*$").Value;

或者:

string filename = Regex.Match(fullpath, "[^\\"+System.IO.Path.PathSeparator+"]*$").Value;

没有 正则表达式:

string[] pathparts = fullpath.Split(new []{System.IO.Path.PathSeparator});
string file = pathparts[pathparts.Length-1];

你提到的官方库支持:

string file = System.IO.Path.GetFileName(fullpath);

1
\w+:\\(\w+\\)*(?<file>\w*\.\w*)

显然,这需要扩展以涵盖所有路径字符,但命名组“file”包含示例路径的文件名。


只是好奇,下一个组是做什么的? (?<file>\w.\w). 它应该是(?:)吗? - Artur A
@Artu:(?<file>\w*\.\w*) 是一个命名捕获组。 - Jeff Yates

0
你应该使用System.Path类。这意味着如果你决定支持Mono/Linux,你将不必担心太多(dlamblin的示例考虑了路径分隔符,但你可能会遇到一些奇怪的OS,有奇怪的路径)。System.Path类还可以将两个路径合并为一个。例如:
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My App Stuff");

将解析为:

  • Windows:C:\Documents and Settings\[User]\My Documents\My App Stuff
  • Linux:/[User]/My App Stuff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接