【问题标题】:C# Regex to Get file name without extension?C#正则表达式获取没有扩展名的文件名?
【发布时间】:2017-04-19 01:20:57
【问题描述】:

我想使用正则表达式来获取不带扩展名的文件名。我无法让正则表达式返回一个值。我有这个:

string path = @"C:\PERSONAL\TEST\TESTFILE.PDF";
var name = Regex.Match(path, @"(.+?)(\.[^\.]+$|$)").Value;

在这种情况下,name 总是返回为C:\PERSONAL\TEST\TESTFILE.PDF。我做错了什么,我认为我的搜索模式是正确的?

(我知道我可以使用Path.GetFileNameWithoutExtension(path);但我特别想尝试使用正则表达式)

【问题讨论】:

  • 当存在完美的框架方法时,为什么要为此使用正则表达式?你可以使用正则表达式,但你手上会有一个额外的问题。
  • 但是为什么呢?寻找trouble
  • 如果这只是为了学习正则表达式,那很好,但绝对没有充分的理由为此使用正则表达式。事实上,我认为正则表达式应该是解决大多数问题时的最后手段。
  • 你做错的是调用一个方法而不先在 MSDN 上查找它,得到一个你不期望的结果,然后 仍然 不费心去阅读文档。你不知道Regex.Match() 返回了什么,显然不是你猜到的,所以你来这里请人大声朗读 MSDN 页面给你听。
  • 如果 MSDN 太吓人,运行它并在它后面添加一个断点:var result = Regex.Match(path, @"(.+?)(\.[^\.]+$|$)"); 将鼠标悬停在result 上,看看方法返回了什么。这就是编程。

标签: c# regex


【解决方案1】:

你需要Group[1].Value

string path = @"C:\PERSONAL\TEST\TESTFILE.PDF";
var match = Regex.Match(path, @"(.+?)(\.[^\.]+$|$)");
if(match.Success)
{
    var name = match.Groups[1].Value;
}

match.Value 返回 Captures.Value,这是整个匹配项

match.Group[0] 始终与match.Value 具有相同的值

match.Group[1]返回第一个捕获值

例如:

string path = @"C:\PERSONAL\TEST\TESTFILE.PDF";
var match = Regex.Match(path, @"(.+?)(\.[^\.]+$|$)");
if(match.Success)
{
    Console.WriteLine(match.Value);
    // return the substring of the matching part
    //Output: C:\\PERSONAL\\TEST\\TESTFILE.PDF 
    Console.WriteLine(match.Groups[0].Value)
    // always the same as match.Value
    //Output: C:\\PERSONAL\\TEST\\TESTFILE.PDF 
    Console.WriteLine(match.Groups[1].Value)
    // return the first capture group which is (.+?) in this case
    //Output: C:\\PERSONAL\\TEST\\TESTFILE 
    Console.WriteLine(match.Groups[2].Value)
    // return the second capture group which is (\.[^\.]+$|$) in this case
    //Output: .PDF 

}

【讨论】:

  • 你能解释一下原因吗?
  • 这是Groups[2].Value,而不是10 是整个输入字符串(因为两个捕获组一起匹配整个事物),1 是(不必要的)第一个捕获组,2 是第二个。
  • @Stefan 哎呀,我把你误认为 OP。对不起!
【解决方案2】:

由于数据位于字符串的右侧,请使用选项RightToLeft 告诉正则表达式解析器从字符串的末尾到开头工作。这将显着减少处理时间并减少所需的实际图案。

下面的模式从左到右读取并说,给我所有不是\ 字符的东西(消耗/匹配斜线而不继续前进)并开始消耗一段时间。

Regex.Match(@"C:\PERSONAL\TEST\TESTFILE.PDF", 
            @"([^\\]+)\.", 
            RegexOptions.RightToLeft)
      .Groups[1].Value

打印出来

测试文件

【讨论】:

    【解决方案3】:

    试试这个:

    .*(?=[.][^OS_FORBIDDEN_CHARACTERS]+$)
    

    对于 Windows:

    OS_FORBIDDEN_CHARACTERS = :\/\\\?"><\|
    

    这是对以下内容的巧妙修改: Regular expression get filename without extention from full filepath

    如果您可以匹配禁用字符,那么最简单的正则表达式将是:

    .*(?=[.].*$)
    

    【讨论】:

      【解决方案4】:

      可以更短更贪婪:

      var name = Regex.Replace(@"C:\PERS.ONAL\TEST\TEST.FILE.PDF", @".*\\(.*)\..*", "$1"); // "TEST.FILE"
      

      【讨论】:

        猜你喜欢
        • 2013-03-18
        • 2010-10-12
        • 2011-04-09
        • 2022-11-19
        • 2010-09-19
        • 1970-01-01
        • 2015-06-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多