person1 bob
person2 george
person3 tom
这是一个关于VB的项目。我试图读取如上所述的文本文件,并将每行的第二个字分配给一个数组。例如,array(1)
为"bob"
,array(2)
为"george"
,array(3)
为"tom"
。我目前在分配数组时遇到问题,因为array(1)
的当前输出是:
bob
george
tom
我目前的尝试是:
Dim FileName As String = "*snip*"
Dim FileReader As StreamReader = File.OpenText(FileName)
Dim FileLine As String = FileReader.ReadLine()
For x = 1 To 18
Dim players() As String = FileLine.Split(New Char() {" "c})
FileLine = FileReader.ReadLine()
Console.WriteLine(players(1))
count = count + 1
Next
我是一个总菜鸟,请好好对待我。
答案 0 :(得分:1)
我可以使用LINQ为您提供更简单的方法吗?
Dim resultArray = File.ReadLines(FileName).
Select(Function(l) l.Split({" "c}, StringSplitOptions.RemoveEmptyEntries).Last().Trim()).
ToArray()
如果某行可以包含两个以上的“单词”,则可以使用ElementAtOrDefault(1)
代替Last
来访问第二个(如果可用,否则为Nothing
)。
答案 1 :(得分:0)
Sub GetPeople()
' use List instead of Array as you won't have to know
' the length of the array before declaring it.
Dim personList As List(Of String) = New List(Of String)
' this holds the path to your file
Dim fname As String
' will hold the name of the person
Dim personName As String
fname = "[your file path here]"
Dim reader As System.IO.StreamReader
reader = New IO.StreamReader(fname)
Dim line As String
While (Not reader.EndOfStream)
line = reader.ReadLine()
' after you read a line, you call the GetPersonName function
personName = GetPersonName(line)
personList.Add(personName)
End While
reader.Close()
' the names you are interested in are in personList now:
dim i as long
for i = 0 to personList.Count - 1
Console.WriteLine(personList(i))
next i
End Sub
Function GetPersonName(lineText As String) As String
Dim Result As String
Dim stringLength As Long
Dim spaceIndex As Long
spaceIndex = lineText.IndexOf(" ")
stringLength = (lineText.Count - spaceIndex) - 1
Result = lineText.Substring((spaceIndex + 1), stringLength)
Return Result
End Function
我希望这会有所帮助。
答案 2 :(得分:0)
我最终使用了这一切,一切正常。谢谢你们的贡献。
Dim resultArray = File.ReadLines(FileName).
Select(Function(l) l.Split({" "c}, StringSplitOptions.RemoveEmptyEntries).Last().Trim()).
ToArray()
答案 3 :(得分:0)
正确的是,正则表达式是一个先进的概念,所以你可能想要继续学习它,直到你获得更多的经验,但是,只要你知道它,它就是你需要做的一个强大的选择字符串解析,替换和验证。以下是使用Regex完成此操作的示例:
Dim result() As String = Regex.
Matches(File.ReadAllText(FileName), "^\s*\w+\s+(\w+)\s*$", RegexOptions.Multiline).
Cast(Of Match).Select(Function(match) match.Groups(1).Value).ToArray()
这里的真正力量是正在执行的额外验证。仅处理与正则表达式模式完全匹配的行。此外,通过指定模式,将来更容易调整或改进模式。这是对模式(^\s*\w+\s+(\w+)\s*$
)的解释:
^
- 只有从行首开始的字符串才会匹配\s*
- 允许在行的开头添加任意数量的空白字符
\s
- 这是一个匹配任何空白字符的特殊字符类*
- 字符类将连续匹配零个或多个字符\w+
- 匹配的字符串必须包含一个单词
\w
- 一个匹配任何单词字符的特殊字符类+
- 字符类将匹配一行中的一个或多个字符\s+
- 第一个单词必须后跟一个或多个空格字符(\w+)
- 必须有第二个字。括号创建一个捕获组。在这种情况下,捕获组表示我们想要抓取的匹配部分(即我们不关心匹配线的其余部分,只关注第二个单词)。\s*
- 第二个单词后面可能跟有任意数量的空白字符$
- 表示该行的结尾。通过将其置于模式中,它使得匹配必须填满整行。换句话说,只会处理包含两个单词的行。正则表达式是您在许多语言,软件开发工具和IDE中看到的常用工具(例如Visual Studio搜索/替换,SSMS搜索/替换,Notepad ++,grep),因此它值得一旦你准备冒险,就该知道它。
关于您的原始问题,每个回答的人似乎都避免实际上帮助您了解如何填充数组。真正的答案是,它不是那么简单,因为数组固有的固定长度。你可以在技术上"调整大小"他们在VB中(使用ReDim
),但它效率低,老派,丑陋。如果您需要一次添加一个未知数量的项目,最好使用List(Of T)
对象。例如:
Dim result As New List(Of String)()
Dim line As String = Nothing
Do
line = reader.ReadLine()
If line IsNot Nothing Then
Dim fields() As String = line.Split({" "c})
result.Add(fields(1))
End If
Loop While line IsNot Nothing
如果您需要将列表转换为固定长度数组,则可以执行以下操作:
Dim arr() As String = result.ToArray()
但是,如果你肯定知道你拥有的物品的确切数量,那么可以提前设定阵列的大小,然后在循环中填充每个项目,这是可能的(尽管通常仍然不鼓励): / p>
Dim result(18) As String
For x = 0 To 17
Dim fields() As String = line.Split({" "c})
result(x) = fields(1)
line = reader.ReadLine()
Next
我之所以气馁,是因为它更脆弱,更难阅读,而且即使在考虑性能时也是不必要的。如果您知道大小,并且性能有问题,您仍然可以使用List
并在构造函数中指定大小以预分配内存:
Dim result As New List(Of String)(18)
但是,正如您所见,当使用LINQ以更具说明性的方式编写代码时,大多数人都会优先考虑这些命令式样式。