使用 Regex Split 的索引越界错误

Index out of bounds error using Regex Split

自从我上次做以来在这里发布另一个问题,回答的人非常有帮助。请记住,我对 VB.net 比较陌生。

所以我正在开发一个程序,该程序使用 Regex.Split 从文本文件中提取第一列和第三列,以消除文件中字母数字字符之间的多个空格。

文本文件的高级示例如下:

VARIABLE1                MEAS1           STORAGE1
VARIABLE2                MEAS2           STORAGE2
VARIABLE3                MEAS3           STORAGE3
VARIABLE4                MEAS4           STORAGE4
VARIABLE5                MEAS5           STORAGE5
VARIABLE6                MEAS6           STORAGE6
                                           
#VARIABLE7         MEAS7           STORAGE7
VARIABLE8              MEAS8           STORAGE8
VARIABLE9            MEAS9           STORAGE9
VARIABLE10            MEAS10           STORAGE10
VARIABLE11            MEAS11           STORAGE11
VARIABLE12            MEAS12           STORAGE12
VARIABLE13            MEAS13           STORAGE13
VARIABLE14            MEAS14           STORAGE14

该文件使用“#”表示文件中的注释,因此在我的代码中我告诉 System.IO 忽略该字符。 然而,当创建一个测试函数来尝试这个时,我不断地得到一个索引越界错误,(仅在某些文件上。出于某种原因,这种格式的一些工作正常) 查看执行输出时,我在写入“STORAGE6”行后收到错误,因此从 STORAGE6 遍历到 VARIABLE7 时一定有错误,我不太明白。对此有任何见解将不胜感激!

我写的测试函数如下:

    Public Function Testing()
        OpenFileDialog1.ShowDialog()
        Dim file = System.IO.File.ReadAllLines(OpenFileDialog1.FileName)
        For Each line In file
            Dim arrWords() As String = System.Text.RegularExpressions.Regex.Split(line, "\s+")
            Dim upBound = arrWords.GetUpperBound(0)
            If upBound <> 0 Then

                If line.Contains("#") Or line.Length = 0 Then

                Else
                    Console.WriteLine(arrWords(0) + " " + arrWords(2))

                End If


            End If
        Next
    End Function

我在调用“arrWords(2)”时遇到了越界错误,我确信这很明显,但我只是想尽可能详细地回答这个问题。

简单的修复方法是更改​​这两行:

If upBound <> 0 Then
    If line.Contains("#") Or line.Length = 0 Then

像这样:

If upBound > 0 Then
    If line.TrimStart().StartsWith("#") OrElse String.IsNullOrWhitespace(line) Then

但我真的会做更像这样的事情:

Public Class DataItem
    Public Property Variable As String
    Public Property Measure As String
    Public Property Storage As String
End Class

Public Function ReadDataFile(fileName As String) As IEnumerable(Of DataItem)
     Return File.ReadLines(fileName).
               Where(Function(line) Not line.TrimStart().StartsWith("#") AndAlso Not String.IsNullorWhitespace(line)).
               Select(Function(line) System.Text.RegularExpressions.Regex.Split(line, "\s+")).
               Where(Function(fields) fields.Length = 3).
               Select(Function(fields) 
                    Return New DataItem With {
                     .Variable = fields(0), 
                     .Measure = fields(1),
                     .Storage = fields(2)}
               End Function)
End Function

Public Function Testing()
    If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
        Dim records = ReadDataFile(OpenFileDialog1.FileName)
        For Each record in records
            Console.WriteLine($"{record.Variable} {record.Storage}") 
        Next
    End If
End Function