一种使用RegEx在字符串中查找一组文件名路径的方法

时间:2010-09-25 10:18:53

标签: c# regex filenames

早上好的家伙

是否有一种在C#中使用正则表达式的好方法,以便在string变量中找到所有文件名及其路径?

例如,如果你有这个字符串:

string s = @"Hello John

these are the files you have to send us today: <file>C:\Development\Projects 2010\Accounting\file20101130.csv</file>, <file>C:\Development\Projects 2010\Accounting\orders20101130.docx</file>

also we would like you to send <file>C:\Development\Projects 2010\Accounting\customersupdated.xls</file>

thank you";

结果将是:

C:\Development\Projects 2010\Accounting\file20101130.csv
C:\Development\Projects 2010\Accounting\orders20101130.docx
C:\Development\Projects 2010\Accounting\customersupdated.xls

编辑: 考虑到@Jim的内容,我编辑了字符串添加标签,以便更容易从字符串中提取所需的文件名!

3 个答案:

答案 0 :(得分:5)

这是我想出的:

using System;
using System.Text.RegularExpressions;

public class Test
{

    public static void Main()
    {
        string s = @"Hello John these are the files you have to send us today: 
            C:\projects\orders20101130.docx also we would like you to send 
            C:\some\file.txt, C:\someother.file and d:\some file\with spaces.ext  

            Thank you";

        Extract(s);

    }

    private static readonly Regex rx = new Regex
        (@"[a-z]:\\(?:[^\\:]+\\)*((?:[^:\\]+)\.\w+)", RegexOptions.IgnoreCase);

    static void Extract(string text)
    {
        MatchCollection matches = rx.Matches(text);

        foreach (Match match in matches)
        {
            Console.WriteLine("'{0}'", match.Value);
        }
    }

}

制作:(见ideone

'C:\projects\orders20101130.docx', file: 'orders20101130.docx'
'C:\some\file.txt', file: 'file.txt'
'C:\someother.file', file: 'someother.file'
'd:\some file\with spaces.ext', file: 'with spaces.ext'

正则表达式不是非常强大(它做了一些假设)但它也适用于你的例子。


如果您使用<file>标签,则是此程序的一个版本。将正则表达式和Extract更改为:

private static readonly Regex rx = new Regex
    (@"<file>(.+?)</file>", RegexOptions.IgnoreCase);

static void Extract(string text)
{
    MatchCollection matches = rx.Matches(text);

    foreach (Match match in matches)
    {
        Console.WriteLine("'{0}'", match.Groups[1]);
    }
}

也可在ideone上找到。

答案 1 :(得分:4)

如果您对文件名要求设置了一些限制,则可以使用与此类似的代码:

string s = @"Hello John

these are the files you have to send us today: C:\Development\Projects 2010\Accounting\file20101130.csv, C:\Development\Projects 2010\Accounting\orders20101130.docx

also we would like you to send C:\Development\Projects 2010\Accounting\customersupdated.xls

thank you";

Regex regexObj = new Regex(@"\b[a-z]:\\(?:[^<>:""/\\|?*\n\r\0-\37]+\\)*[^<>:""/\\|?*\n\r\0-\37]+\.[a-z0-9\.]{1,5}", RegexOptions.IgnorePatternWhitespace|RegexOptions.IgnoreCase);
MatchCollection fileNameMatchCollection = regexObj.Matches(s);
foreach (Match fileNameMatch in fileNameMatchCollection)
{
    MessageBox.Show(fileNameMatch.Value);
}

在这种情况下,我将扩展名限制为1-5个字符。您显然可以使用其他值或进一步限制文件扩展名中允许的字符。有效字符列表取自MSDN文章Naming Files, Paths, and Namespaces

答案 2 :(得分:-1)

如果使用<file>标签,最终文本可以表示为格式良好的xml文档(就内部xml而言,即没有根标签的文本),您可以这样做:

var doc = new XmlDocument();
doc.LoadXml(String.Concat("<root>", input, "</root>"));

var files = doc.SelectNodes("//file"):

var doc = new XmlDocument();

doc.AppendChild(doc.CreateElement("root"));
doc.DocumentElement.InnerXml = input;

var nodes = doc.SelectNodes("//file");

这两种方法都很有效,并且是高度面向对象的,尤其是第二种方法。

并且会带来更多的表现。

另见 - Don't parse (X)HTML using RegEx

相关问题