Dylan de St Pern
Dylan de St Pern

Reputation: 469

VB.net split function with substring

I want to read a certain value in a string. each line is a new string and I want to read the 6th integer on each line..

Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles browsebtn.Click
    If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
        Dim filename As String = OpenFileDialog1.FileName
        Dim streamreader As New System.IO.StreamReader(filename)
        Dim textfile As String = streamreader.ReadToEnd
        Dim splitChar As String = vbNewLine
        Dim day As Integer = textfile.Substring(10, 2)
        Dim strLine() As String = day.Split(splitChar)
        For Each line As String In strLine

            MsgBox(day)

        Next


    End If
End Sub
End Class

But it only returns one number. If I set day as a string and not an integer it works perfect, except it reads the whole string, not the two integers that I need. Please help. What am I doing wrong?

EDIT:

The input file looks like this:

23728 121010 00004986 00 00  2 21 22 11   447 114  2   382   292   350

23730 121010 00064120 00 00 51 19 21 12  1064 110  2  4500   572  7734 

I want my output to be:

10
10

10 comes from "121010"

Upvotes: 0

Views: 3564

Answers (3)

qwr
qwr

Reputation: 3670

Some advice:

  1. always dispose resources (use using or try catch finally with resource.close)

  2. never trust user inputs.

  3. write codes that can handle enough undesired situations

Corrections based on your code:

 Try
        Dim text As String = Nothing

        Using streamreader As New System.IO.StreamReader("text.txt")
            text = streamreader.ReadToEnd()
        End Using
        If IsNothing(text) = False Then
            Dim strLine() As String = text.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
            For Each line As String In strLine

                If line.Length > 12 Then MsgBox(line.Substring(10, 2))
            Next
        End If
    Catch ex As Exception
        'filenotfound case
    End Try

Another way:

On cases where line input can be different (but second should be looked value in our case)

Then can use Regex

Here is how:

Try
    Using streamreader As New System.IO.StreamReader(file)
        Dim line As String
        While streamreader.Peek > 0
            'unreaded line from file
            line = streamreader.ReadLine()
            'split input by non digits
            Dim numberstrs As String() = Regex.Split(line, "\D+")
            'second numbers last two
            If numberstrs.Length > 1 AndAlso numberstrs(1).Length > 2 Then
                Console.WriteLine("{0}", numberstrs(1).Substring(numberstrs(1).Length - 2, 2))
            End If

        End While


    End Using
Catch ex As Exception

End Try

Upvotes: 1

Steve Pettifer
Steve Pettifer

Reputation: 2043

Steven's answer gets you most of the way there but not all the way. It's worth noting that you actually don't want the 6th integer because that could be 1 or 2 or pretty much anything depending on how you slice it. Also, given in your example you say you want to get 10 from 121010, that could be wither the second group of two numbers or the third group of two numbers from that section of the string.

I note that in your example strings you have some double spaces: You need to sort that out for a kickoff otherwise using String.Split will give you empty elements in the array. In fact, using parts(5) as Steven has used above gives you an empty element thanks to the double space, and that's not what you want anyway. You would want parts(2) and then you would need to SubString that to get the number you want.

Another, and I think more elegant, way to do it is to use a RegEx to get the number. Let's say you want the second 10 in that string (shown in bold): 12*10*10. If you know that that string will always be 6 characters, will always be the second field in the input line and you always want the third and fourth numbers then this would do you:

Imports System.Text.RegularExpressions
Imports System.IO

Private Sub ReadFile
    Dim rx As New Regex("^[^\s]+\s{1}\d{2}(\d{2}?)", RegexOptions.Compiled Or RegexOptions.CultureInvariant)
    Dim streamReader As New StreamReader(fileName)
    Dim line As String = String.Empty

    Do While streamReader.Peek >= 0
        line = streamReader.ReadLine()
        MessageBox.Show(rx.Matches(line)(0).Groups(1).Value)
    Loop 
End Sub

I'm not saying that's the only (or most elegant) RegEx but it will work and means you don't have to use SubString and it doesn't care how long the first field is. It also assumes a single space between fields but that can also be changed to suit. So long as you can work out a rule to get to the bit you want, you can RegEx it. Use Expresso (free and very powerful utility) to help you construct a suitable expression.

Upvotes: 1

Steven Doggart
Steven Doggart

Reputation: 43743

All of that code that you wrote could be done in much fewer lines, like this:

For Each line As String In File.ReadAllLines(fileName)
    MessageBox.Show(line)
Next

Like your example, though, that loads the entire file into memory all at once, which could be problematic if it's a large file. If the size of the file is a concern, it would be better to just read one line at a time, like this:

Dim streamReader As New StreamReader(fileName)
Dim line As String = Nothing
Do
    line = streamReader.ReadLine()
    MessageBox.Show(line)
Loop Until line Is Nothing

However, the problem still remains, how do you split the line up into its individual values. If, as it appears in your question, the values are separated by spaces, then you can just use line.Split to separate the line into an array of all of its values. Then to get the last two characters of one of those values, you can just use String.SubString, like this:

Dim streamReader As New StreamReader(fileName)
Dim line As String = Nothing
Do
    line = streamReader.ReadLine()
    Dim parts() As String = line.Split()
    Dim wholeNumber As String = parts(1)
    Dim lastTwo As String = wholeNumber.SubString(wholeNumber.Length - 2)
    MessageBox.Show(lastTwo)
Loop Until line Is Nothing

Upvotes: 2

Related Questions