【问题标题】:In C# matching all files in a directory using regex在 C# 中使用正则表达式匹配目录中的所有文件
【发布时间】:2023-04-03 19:24:01
【问题描述】:

我目前正在尝试在 C# 中使用以下正则表达式

Regex reg = new Regex(@"-(FILENM01P\\.(\\d){3}\\.PGP)$");
var files = Directory.GetFiles(savePath, "*.PGP")
    .Where(path => reg.IsMatch(path))
    .ToList();
foreach (string file in files)
{
    MessageBox.Show(file);
}

在单个 to 目录中匹配具有此文件命名约定的所有文件

 FILENM01P.001.PGP

如果我只是像这样加载所有文件

var files = Directory.GetFiles(savePath, "*.PGP")
foreach (string file in files)
{
    MessageBox.Show(file);
}

我得到一个这样的字符串;等等

C:\Users\User\PGP 文件\FILENM01P.001.PGP

例如,可能有很多这样的文件

FILENM01P.001.PGP
FILENM01P.002.PGP
FILENM01P.003.PGP
FILENM01P.004.PGP

但永远不会有

FILENM01P.000.PGP
FILENM01P.1000.PGP

为了澄清,只有 3 个数字一起会改变,并且只能在 001 到 999 之间(带前导零),其余文本是静态的,永远不会改变。

对于 RegEx,我是一个完全的新手,因此我们将不胜感激。

基本上我的最终目标是找到下一个数字并创建文件,如果没有文件,那么它将从 001 开始创建一个,如果达到 999,则返回 1000,以便我知道我需要移动到新目录,因为每个目录限制为 999 个连续文件。 (不过我会处理这些东西)

【问题讨论】:

  • 使用在线正则表达式助手网站之一(谷歌“C#在线正则表达式助手”)。他们可以帮助您制作和测试正则表达式。
  • 为什么开头有破折号?此外,您不必在逐字字符串中转义反斜杠。
  • @juharr 开头出现 - 的原因是因为我正在关注在线指南,即https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx,他们有这样的模式:-\d{3}$ 其描述为 匹配必须出现在字符串的末尾或行或字符串末尾的 \n 之前。
  • MSDN 中的那条评论与尾随的$ 符号有关。在他们的样本中,- 实际上与负数匹配。
  • @user692214 几个人为您提供了解决方案。请注意它是否适合您。

标签: c# regex linq


【解决方案1】:

试试这个代码。

var reg = new Regex(@"FILENM01P\.(\d{3})\.PGP");

var matches = files.Select(f => reg.Match(f)).Where(f => f.Success).Select(x=> Convert.ToInt32(x.Value.Split('.')[1])).ToList();

var nextNumber = (matches.Max() + 1).ToString("D3"); // 3 digit with leading zeros

你可能还需要一个 if 检查下一个数字是否为 1000,如果是,则返回 0。

(matches.Max() + 1 > 999? 0:matches.Max() + 1).ToString("D3")

我的测试用例。

List<string> files = new List<string>();
files.Add(@"C:\Users\User\PGP Files\FILENM01P.001.PGP");
files.Add(@"C:\Users\User\PGP Files\FILENM01P.002.PGP");
files.Add(@"C:\Users\User\PGP Files\FILENM01P.003.PGP");
files.Add(@"C:\Users\User\PGP Files\FILENM01P.004.PGP");

输出是

nextNumber = "005";

【讨论】:

  • 很高兴听到这个消息:)
【解决方案2】:
Regex regex = new Regex(@"FILENM01P\.(\d+)\.", RegexOptions.IgnoreCase);
var fnumbers = Directory.GetFiles(src, "*.PGP", SearchOption.TopDirectoryOnly)
                .Select(f=>regex.Match(f))
                .Where(m=>m.Success)
                .Select(m=>int.Parse(m.Groups[1].Value));
int fileNum = 1 + (fnumbers.Any() ? fnumbers.Max() : 0);

【讨论】:

    【解决方案3】:

    你可以这样做:

    var reg = new Regex(@"FILENM01P\.(\d{3})\.PGP");
    
    var matches = files.Select(f => reg.Match(f)).Where(f => f.Success).ToList();
    
    var nextNumber = matches.Any()
        ? matches.Max(f => int.Parse(f.Groups[1].Value)) + 1 
        : 1;
    

    files 是要匹配的文件列表。

    【讨论】:

    • [0-9][0-9][0-9] 不只是\d{3}
    • @LeeCampbell 是的,你是对的 - 有一个心理失误(最初是 [0-9][0-9][1-9] 在我意识到我没有注意之前)。现在编辑..谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2013-10-23
    • 2014-08-30
    相关资源
    最近更新 更多