使用 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
自从我上次做以来在这里发布另一个问题,回答的人非常有帮助。请记住,我对 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