BoKu
BoKu

Reputation: 67

In C# matching all files in a directory using regex

I am currently trying to use the below regular expression in 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 match all files that have this file naming convention in a single to directory

 FILENM01P.001.PGP

If I just load up all files like this

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

The I get a string like this; etc.

C:\Users\User\PGP Files\FILENM01P.001.PGP

There could be many of these files for example

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

But there will never be

FILENM01P.000.PGP
FILENM01P.1000.PGP

To clarify, only the 3 numbers together will change and can only be between 001 to 999 (with leading zeros) the rest of the text is static and will never change.

I'm a complete novice when it comes to RegEx so any help would be greatly appreciated.

Essentially my end goal is to find the next number and create the file and if there are no files then it will create one starting at 001 and if it gets to 999 then it returns 1000 so that I know I need to move to a new directory as each directory is limited to 999 sequential files. (I'll deal with this stuff though)

Upvotes: 1

Views: 2984

Answers (3)

Rajshekar Reddy
Rajshekar Reddy

Reputation: 18987

Try this code.

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

Also you might need a if check to see if the next number is 1000 if so then return 0.

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

My test case.

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");

The output is

nextNumber = "005";

Upvotes: 3

Rob
Rob

Reputation: 27357

You can do something like this:

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;

Where files is a list of the files to match.

Upvotes: 1

Mitchell Chu
Mitchell Chu

Reputation: 137

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);

Upvotes: 3

Related Questions