将文本文件中的单词分配给数组

时间:2017-06-06 15:03:20

标签: arrays vb.net

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

我是一个总菜鸟,请好好对待我。

4 个答案:

答案 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以更具说明性的方式编写代码时,大多数人都会优先考虑这些命令式样式。