如何在文件名中的特定字符范围内搜索字符串?

how to search for a string within a specific range of characters within a file name?

如何通过DirectoryInfo搜索文件名中特定字符范围内的字符串class?

我只需要 select 字符范围为 22 到 29 的文件

这是我的代码:

Public Sub SpostaFile(sourceDirectory As String, ByVal destDirectory As String)
    Try
        Dim from_date As DateTime = DateTime.Now.AddHours(-24)
        Dim to_date As DateTime = DateTime.Now.AddHours(+24)
        Try
            Dim folder As New DirectoryInfo(sourceDirectory)
            Dim pdfList = folder.EnumerateFiles("*.PDF").Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date)
            Dim xlsList = folder.EnumerateFiles("*.XLS").Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date)
            Dim xlsxList = folder.EnumerateFiles("*.XLSX").Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date)
            Dim csvList = folder.EnumerateFiles("*.csv").Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date)
            ' Copy pdf files.
            For Each file In pdfList
                file.CopyTo(Path.Combine(destDirectory, file.Name))
            Next
            ' Copy XLS files.
            For Each file In xlsList
                file.CopyTo(Path.Combine(destDirectory, file.Name))
            Next
            ' Copy XLSX files.
            For Each file In xlsxList
                file.CopyTo(Path.Combine(destDirectory, file.Name))
            Next
            ' Copy CSV files.
            For Each file In csvList
                file.CopyTo(Path.Combine(destDirectory, file.Name))
            Next
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

使用Substring,并使用可重用谓词简化代码以减少维护

Public Sub SpostaFile(sourceDirectory As String, ByVal destDirectory As String)
    Try
        Dim from_date As DateTime = DateTime.Now.AddHours(-24)
        Dim to_date As DateTime = DateTime.Now.AddHours(+24)
        Dim searchString = "inscriz"
        Dim folder As New DirectoryInfo(sourceDirectory)
        Dim fileSearchPredicate As Func(Of FileInfo, Boolean) =
            Function(fi)
                Return fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date _
                AndAlso fi.Name.Length >= 29 AndAlso fi.Name.Substring(21, 8).Contains(searchString)
            End Function
        Dim pdfList = folder.EnumerateFiles("*.PDF").Where(fileSearchPredicate)
        Dim xlsList = folder.EnumerateFiles("*.XLS").Where(fileSearchPredicate)
        Dim xlsxList = folder.EnumerateFiles("*.XLSX").Where(fileSearchPredicate)
        Dim csvList = folder.EnumerateFiles("*.csv").Where(fileSearchPredicate)
        For Each file In pdfList ' Copy pdf files.
            file.CopyTo(Path.Combine(destDirectory, file.Name))
        Next
        For Each file In xlsList ' Copy XLS files.
            file.CopyTo(Path.Combine(destDirectory, file.Name))
        Next
        For Each file In xlsxList ' Copy XLSX files.
            file.CopyTo(Path.Combine(destDirectory, file.Name))
        Next
        For Each file In csvList ' Copy CSV files.
            file.CopyTo(Path.Combine(destDirectory, file.Name))
        Next
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

转换为:

Dim pdfList = folder.EnumerateFiles("*.PDF").Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date)

对此:

Dim pdfList = folder.EnumerateFiles("*.PDF").
    Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date AndAlso 
          fi.Name.Length >= 29 AndAlso fi.Name.Substring(22,7) = "inscriz" )

并对其他文件类型执行相同的操作。

我会添加一条注释,问题文本说要在字符 22 和 29 之间的范围内搜索,这是一个 7 个字符长的文本集,也是七个字符。那样的话,我们可以做一个简单的相等比较。如果范围更长,我们将使用 .Contains() 代替。


我可能也想这样做,以避免重复,但有一个很好的理由证明这也太过分了:

Public Sub SpostaFile(sourceDirectory As String, ByVal destDirectory As String)
    Dim from_date As DateTime = DateTime.Now.AddHours(-24)
    Dim to_date As DateTime = DateTime.Now.AddHours(+24)
    Dim folder As New DirectoryInfo(sourceDirectory)

    Dim cp As Action(Of String) = 
    Sub(fileType) 
        Dim files = folder.EnumerateFiles(fileType).
            Where(Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date AndAlso 
                fi.Name.Length >= 29 AndAlso fi.Name.Substring(22,7) = "inscriz" )

        For Each file In xlsList
            file.CopyTo(Path.Combine(destDirectory, file.Name))
        Next
    End Sub

    Try
        cp("*.PDF")
        cp("*.XLS")
        cp("*.XLSX")
        cp("*.csv")
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

正则表达式变体:

Dim R as new Regex("^.{21}inscriz")
Dim pdfList = folder.EnumerateFiles("*.PDF").Where(Function(fi) 
    fi.CreationTime >= fromDate AndAlso fi.CreationTime <= to_date AndAlso
    R.Match(fi.Name).Success)

为什么不在文件过滤器中包含此条件?

Dim pdfList = folder.EnumerateFiles("??????????????????????inscriz*.PDF") .Where(
    Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date)

通过为重复的部分创建一个Sub,可以使代码更具可读性

Public Sub SpostaFile(sourceDirectory As String, ByVal destDirectory As String)
    Try
        Dim folder As New DirectoryInfo(sourceDirectory)

        Dim from_date As DateTime = DateTime.Now.AddHours(-24)
        Dim to_date As DateTime = DateTime.Now.AddHours(+24)
        Dim datePredicate As Func(Of FileInfo, Boolean) =
            Function(fi) fi.CreationTime >= from_date AndAlso fi.CreationTime <= to_date

        CopyFiles(folder, destDirectory,
            "??????????????????????inscriz*.PDF", datePredicate)
        CopyFiles(folder, destDirectory,
            "??????????????????????inscriz*.XLS", datePredicate)
        CopyFiles(folder, destDirectory,
            "??????????????????????inscriz*.XLSX", datePredicate)
        CopyFiles(folder, destDirectory,
            "??????????????????????inscriz*.csv", datePredicate)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

Private Sub CopyFiles(source As DirectoryInfo, destDirectory As String,
                      fileFilter As String,
                      dateFilter As Func(Of FileInfo, Boolean))

    Dim fileList = source.EnumerateFiles(fileFilter).Where(dateFilter)

    For Each file In fileList
        file.CopyTo(Path.Combine(destDirectory, file.Name))
    Next
End Sub