Vb.net 如何按文件名和编号排列文件列表?

Vb.net 如何按文件名和编号排列文件列表?,vb.net,linq,sorting,Vb.net,Linq,Sorting,我在一个目录中有一堆文件,我正试图根据它们的类型获取这些文件。一旦我有了它们,我想按文件名排序(其中有一个数字,我想按这种方式排序) 我返回的文件是: file-1.txt file-2.txt ... file-10.txt file-11.txt ... file-20.txt 但是我把它们放进去的顺序看起来更接近这个: file-1.txt file-10.txt file-11.txt ... file-2.txt file-20.txt 现在我正在使用Directory.GetFi

我在一个目录中有一堆文件,我正试图根据它们的类型获取这些文件。一旦我有了它们,我想按文件名排序(其中有一个数字,我想按这种方式排序)

我返回的文件是:

file-1.txt
file-2.txt
...
file-10.txt
file-11.txt
...
file-20.txt
但是我把它们放进去的顺序看起来更接近这个:

file-1.txt
file-10.txt
file-11.txt
...
file-2.txt
file-20.txt
现在我正在使用
Directory.GetFiles()
并尝试使用
linq OrderBy
属性。然而,我在按照上面第一个列表的顺序排列文件列表时,遇到了严重的问题

Directory.GetFiles()
似乎正在返回字符串列表,因此我无法获取文件属性列表,例如
filename
name

这是我目前的代码:

documentPages = Directory.GetFiles(documentPath, "*.txt").OrderBy(Function(p) p).ToList()

有人有什么想法吗?

我假设
文件
.txt
部分是可变的,并且在这里作为文件名和类型的占位符,可以变化

我不经常使用正则表达式,因此这可能还需要一些工作,但这肯定是您需要走的方向:

Dim exp As String = "-([0-9]+)[.][^.]*$"
documentPages = Directory.GetFiles(documentPath, "*.txt").OrderBy(Function(p) Integer.Parse(Regex.Matches(p, exp)(0).Groups(1).Value)).ToList()

再次查看,我发现我没有注意到您正在通过
*.txt
文件进行过滤,这可以帮助我们缩小表达式的范围:

Dim exp As String = "-([0-9]+)[.]txt$"
包含测试数据的另一个答案带来的另一个可能的改进是允许
-
和数字之间存在空格:

Dim exp As String = "-[ ]*([0-9]+)[.]txt$"

进一步值得注意的是,如果有不遵循该模式的文本文件,上述操作将失败。如果需要,我们可以考虑:

Dim exp As String = "-[ ]*([0-9]+)[.][^.]*$"
Dim docs = Directory.GetFiles(documentPath, "*.txt")
documentPages = docs.OrderBy(
     Function(p) 
            Dim matches As MatchCollection = Regex.Matches(p, exp)
            If matches.Count = 0 OrElse matches(0).Groups.Count < 2 Then Return 0
            Return Integer.Parse(matches(0).Groups(1).Value)
     End Function).ToList()
Dim exp As String=“-[]*([0-9]+)[.][^.]*$”
Dim docs=Directory.GetFiles(documentPath,*.txt)
documentPages=docs.OrderBy(
功能(p)
Dim matches As MatchCollection=Regex.matches(p,exp)
如果matches.Count=0或lse matches(0).Groups.Count<2,则返回0
返回整数.Parse(匹配项(0).Groups(1).Value)
结束函数)

您还可以使用
Integer.MaxValue
作为默认选项,这取决于您希望这些选项显示在列表的开头还是结尾。

我假设
文件和
部分是可变的,并且在这里作为文件名和类型的占位符,可以变化

我不经常使用正则表达式,因此这可能还需要一些工作,但这肯定是您需要走的方向:

Dim exp As String = "-([0-9]+)[.][^.]*$"
documentPages = Directory.GetFiles(documentPath, "*.txt").OrderBy(Function(p) Integer.Parse(Regex.Matches(p, exp)(0).Groups(1).Value)).ToList()

再次查看,我发现我没有注意到您正在通过
*.txt
文件进行过滤,这可以帮助我们缩小表达式的范围:

Dim exp As String = "-([0-9]+)[.]txt$"
包含测试数据的另一个答案带来的另一个可能的改进是允许
-
和数字之间存在空格:

Dim exp As String = "-[ ]*([0-9]+)[.]txt$"

进一步值得注意的是,如果有不遵循该模式的文本文件,上述操作将失败。如果需要,我们可以考虑:

Dim exp As String = "-[ ]*([0-9]+)[.][^.]*$"
Dim docs = Directory.GetFiles(documentPath, "*.txt")
documentPages = docs.OrderBy(
     Function(p) 
            Dim matches As MatchCollection = Regex.Matches(p, exp)
            If matches.Count = 0 OrElse matches(0).Groups.Count < 2 Then Return 0
            Return Integer.Parse(matches(0).Groups(1).Value)
     End Function).ToList()
Dim exp As String=“-[]*([0-9]+)[.][^.]*$”
Dim docs=Directory.GetFiles(documentPath,*.txt)
documentPages=docs.OrderBy(
功能(p)
Dim matches As MatchCollection=Regex.matches(p,exp)
如果matches.Count=0或lse matches(0).Groups.Count<2,则返回0
返回整数.Parse(匹配项(0).Groups(1).Value)
结束函数)

您还可以使用
Integer.MaxValue
作为默认选项,具体取决于您希望这些选项显示在列表的开头还是结尾。

听起来您可能在寻找“自然排序”(NaturalSort)——显示文件资源管理器用于排序包含数字的文件名的类型。为此,您需要一个自定义比较器:

Imports System.Runtime.InteropServices

Partial Class NativeMethods
    <DllImport("shlwapi.dll", CharSet:=CharSet.Unicode)>
    Private Shared Function StrCmpLogicalW(s1 As String, s2 As String) As Int32
    End Function

    Friend Shared Function NaturalStringCompare(str1 As String, str2 As String) As Int32
        Return StrCmpLogicalW(str1, str2)
    End Function
End Class

Public Class NaturalStringComparer
    Implements IComparer(Of String)

    Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare
        Return NativeMethods.NaturalStringCompare(x, y)
    End Function
End Class
结果(一行以节省空间):

之前:file-1.txt、file-10.txt、file-11.txt、file-19.txt、file-2.txt、file-20.txt、file-3.txt、file-9.txt、file-99.txt
之后:file-1.txt、file-2.txt、file-3.txt、file-9.txt、file-10.txt、file-11.txt、file-19.txt、file-20.txt、file-99.txt

这样做的优点之一是它不依赖于特定的模式或编码。它更通用,可以处理文本中的多组数字:

《权力的游戏》\4-乌鸦的盛宴\1-开场白。mp3
权力的游戏\4-乌鸦的盛宴\2-先知。mp3

权力的游戏\4-乌鸦的盛宴\10-布莱恩II.mp3
权力的游戏\4-乌鸦的盛宴\11-Sansa.mp3


自然字符串排序
非常方便,我个人不介意通过创建扩展来污染Intellisense:

' List<string> version
<Extension>
Function ToNaturalSort(l As List(Of String)) As List(Of String)
    l.Sort(New NaturalStringComparer())
    Return l
End Function

' array version
<Extension>
Function ToNaturalSort(a As String()) As String()
    Array.Sort(a, New NaturalStringComparer())
    Return a
End Function

听起来您可能在寻找“NaturalSort”——一种显示文件资源管理器用来排序包含数字的文件名的类型。为此,您需要一个自定义比较器:

Imports System.Runtime.InteropServices

Partial Class NativeMethods
    <DllImport("shlwapi.dll", CharSet:=CharSet.Unicode)>
    Private Shared Function StrCmpLogicalW(s1 As String, s2 As String) As Int32
    End Function

    Friend Shared Function NaturalStringCompare(str1 As String, str2 As String) As Int32
        Return StrCmpLogicalW(str1, str2)
    End Function
End Class

Public Class NaturalStringComparer
    Implements IComparer(Of String)

    Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare
        Return NativeMethods.NaturalStringCompare(x, y)
    End Function
End Class
结果(一行以节省空间):

之前:file-1.txt、file-10.txt、file-11.txt、file-19.txt、file-2.txt、file-20.txt、file-3.txt、file-9.txt、file-99.txt
之后:file-1.txt、file-2.txt、file-3.txt、file-9.txt、file-10.txt、file-11.txt、file-19.txt、file-20.txt、file-99.txt

这样做的优点之一是它不依赖于特定的模式或编码。它更通用,可以处理文本中的多组数字:

《权力的游戏》\4-乌鸦的盛宴\1-开场白。mp3
权力的游戏\4-乌鸦的盛宴\2-先知。mp3

权力的游戏\4-乌鸦的盛宴\10-布莱恩II.mp3
权力的游戏\4-乌鸦的盛宴\11-Sansa.mp3


自然字符串排序
非常方便,我个人不介意通过创建扩展来污染Intellisense:

' List<string> version
<Extension>
Function ToNaturalSort(l As List(Of String)) As List(Of String)
    l.Sort(New NaturalStringComparer())
    Return l
End Function

' array version
<Extension>
Function ToNaturalSort(a As String()) As String()
    Array.Sort(a, New NaturalStringComparer())
    Return a
End Function

我猜您的比较函数必须测试两个文件名是否在第一个(?)点之前有一个数字部分,如果是,则比较数字之前的前缀:如果它们相同(不区分大小写?),则按数字进行解析和排序。在所有其他情况下,使用正常的字符串排序。我想您的比较函数必须测试两个文件名是否都有数字