2

I have a folder with a lot of files, they're named based on a pattern with an iterating number in it.

I'm trying to save new files through vb.net. The aim is to name it with the highest number of the folder +1

There for I looked on internet and found a lot of things about regex and Linq which helped me to make the following code :

If tmpFileName.Contains("%num%") Then
        Dim lastFileNo As Integer = 1
        Dim tmpFName = Dir(frmMain.saveLocalTFPath & "*.docx")
        Dim numbers() As Integer = Regex.Split(tmpFName, "(?<alpha>[\w-[0-9]]+)(?<num>[\d]+)").Skip(1).Select(Function(s) Integer.Parse(s)).ToArray
        For Each element In numbers
            If element > 0 And element < 999 And element > lastFileNo Then lastFileNo = element
        Next
        Do Until tmpFName = ""
            numbers = Regex.Split(tmpFName, "(?<alpha>[\w-[0-9]]+)(?<num>[\d]+)").Skip(1).Select(Function(s) Integer.Parse(s)).ToArray
            For Each element In numbers
                If element > 0 And element < 1000 And element > lastFileNo Then lastFileNo = element
            Next
            tmpFName = Dir()
        Loop
        tmpFileName = tmpFileName.Replace("%num%", lastFileNo)
    End If

But it doesn't work as expected. Has it is my first code in Linq and in Regex and i'm not used to detect what is wrong in my code. Can someone give a hint please?

Thanks

Rave
  • 197
  • 2
  • 15
  • What actually happens? You say it doesn't work as expected - so what does it do? – doctorlove Jul 19 '13 at 08:47
  • 1
    Without looking at some sample data it would be difficult to figure out the issue. – NeverHopeless Jul 19 '13 at 09:09
  • @doctorlove : When I put a `console.Write(element)` just before the `If element...` there is nothing written meaning that he is empty. A `console.Write(tmpFName)` indicates me perfectly the first Filename of the folder. @NeverHopeless : Examples : `JCR 2013-01 data.docx` `JCR 2013-02 other data.docx` `JCR 2013-03 again.docx` `JCR 2013-04 something else.docx` – Rave Jul 19 '13 at 12:00
  • 1
    That might mean numbers is empty. What does console.Write(tmpFName) tell you? – doctorlove Jul 19 '13 at 12:02
  • It write me exactly the Filename : (for example) `JCR 2013-01 data.docx` I'm sorry to be poor in explanations but I'm not behind my computer I will give more this evening if needed. – Rave Jul 19 '13 at 12:04

3 Answers3

1

I'm pretty sure your regex is wrong. Split your code a little bit, create a function that pulls the number from a filename. Ex

Function GetNumberFromFilename(ByVal filename As String) As Integer

    ' From the filename parameter, pull the number and return it
End Function

Then it'll be easy to test it

Console.WriteLine(GetNumberFromFilename("JCR 2013-01 data.docx"))

When you got that working, just loop all the files get the highest number

Dim lastFileNo As Integer = 1
Dim files() As String = IO.Directory.GetFiles(frmMain.saveLocalTFPath, "*.docx")

For Each file As String In files
    Dim number As Integer

    number = GetNumberFromFilename(file)

    If number > 0 And number < 1000 And number > lastFileNo Then
        lastFileNo = number
    End If
Next
the_lotus
  • 12,668
  • 3
  • 36
  • 53
  • yep you're right `Console.WriteLine(GetNumberFromFilename("JCR 2013-01 data.docx"))` returns no number. This is the first time I used Regex so I guess it was likely to go wrong. But the `IO.Directory.GetFiles` function is owesome I never it and it seems very powerfull. – Rave Jul 19 '13 at 16:07
  • I don't get it because when I put the regex code in a translator as expresso it send back what i was looking for alphas in alpha and numerics in num. Is the issue maybe in `.Skip(1).Select(Function(s) Integer.Parse(s)).ToArray`? – Rave Jul 19 '13 at 16:45
  • 1
    I'm not expert in regex, I don't think the split function does what you think. try something like this: Regex.Match("JCR 2013-01 data.docx", "-[0-9]+").Value.Replace("-", "") – the_lotus Jul 19 '13 at 17:06
1

It would be one of some possible solutions.

 Dim di As New System.IO.DirectoryInfo("The Directory")
 Dim max = (From f In di.GetFiles().AsQueryable()
           Where IsNumeric(Path.GetFileNameWithoutExtension(f.Name))
           Select Path.GetFileNameWithoutExtension(f.FullName)).
           OrderBy(Function(c) c).LastOrDefault()
Abbas Amiri
  • 3,074
  • 1
  • 23
  • 23
0

Yes the_lotus you're right but with matches in my cases instead of match. I discovered it 30 minutes ago but I wanted to make it work before posting the solution.

Thanks to you I managed to assemble the peaces and this is the right code:

Dim lastFileNo As Integer = 1
Dim files() As String = Directory.GetFiles(frmMain.saveLocalTFPath, "*.docx")

For Each file As String In files
    file = Path.GetFileNameWithoutExtension(file)
    Dim numbers As MatchCollection = Regex.Matches(file, "(?<num>[\d]+)")

    For Each number In numbers
        number = CInt(number.ToString())
        If number > 0 And number < 1000 And number > lastFileNo Then lastFileNo = number
    Next
Next
Rave
  • 197
  • 2
  • 15