Extracting text from a textfile starting with one word and ending on a different line with a different word - vb.net

I need to extract text from a text file starting with the order number(eg. Order1) and ending with an empty line with all other lines between the order number and the empty line extracted as well for a query. Really have no idea how to go about this so any help is greatly appreciated!
so the file name is "CustomerDetails.txt" and I'd imagine the code would look something like this
If IO.File.Exists("CustomerDetails.txt") Then
Dim inFile As IO.StreamReader = IO.File.OpenText(“CustomerDetails.txt")
End If
and then taking for example "order1" in that text file until the blank space and displaying that is a list box

"Really have no idea how to go about this "
The thinking could go like this...
A text file has a string in it.
I could look up the String class in .net and see if there are any methods that could help me.
Search for "String class in .net"
Looks like we can use a combination of String.IndexOf(String, Int32) and String.Substring(Int32, Int32)
Find the IndexOf your order. The string will be the order "Order1" and we will start looking at index 0 so the Int32 will be 0. Then find the end index. Start looking at the index we just found and stop at the first blank line. We can get the length required by the `.Substring method by subtracting the start index from the end index. Now we can extract the text of Order 1 with the substring method.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim OrderText As String = "Order 1" 'this could be set with TextBox1.Text
'Get the string out of the file
Dim s As String = File.ReadAllText("CustomerDetails.txt")
'Find the index of the order, this overload assumes start index is 0
Dim startIndex As Integer = s.IndexOf(OrderText) 'starts lookint at beginning
'Find the index of the first blank line after the startIndex
'2 new lines make a bland line
Dim endIndex As Integer = s.IndexOf(Environment.NewLine & Environment.NewLine, startIndex)
'Return the string that stars at startIndex with a length of end minus start
Dim Order As String = s.Substring(startIndex, endIndex - startIndex)
'I am going to guess that the details of the order are on separate lines
Dim lines() As String = Order.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
For Each line As String In lines
ListBox1.Items.Add(line)
Next
End Sub

Related

Get a specific value from the line in brackets (Visual Studio 2019)

I would like to ask for your help regarding my problem. I want to create a module for my program where it would read .txt file, find a specific value and insert it to the text box.
As an example I have a text file called system.txt which contains single line text. The text is something like this:
[Name=John][Last Name=xxx_xxx][Address=xxxx][Age=22][Phone Number=8454845]
What i want to do is to get only the last name value "xxx_xxx" which every time can be different and insert it to my form's text box
Im totally new in programming, was looking for the other examples but couldnt find anything what would fit exactly to my situation.
Here is what i could write so far but i dont have any idea if there is any logic in my code:
Dim field As New List(Of String)
Private Sub readcrnFile()
For Each line In File.ReadAllLines(C:\test\test_1\db\update\network\system.txt)
For i = 1 To 3
If line.Contains("Last Name=" & i) Then
field.Add(line.Substring(line.IndexOf("=") + 2))
End If
Next
Next
End Sub
Im
You can get this down to a function with a single line of code:
Private Function readcrnFile(fileName As String) As IEnumerable(Of String)
Return File.ReadLines(fileName).Where(Function(line) RegEx.IsMatch(line, "[[[]Last Name=(?<LastName>[^]]+)]").Select(Function(line) RegEx.Match(line, exp).Groups("LastName").Value)
End Function
But for readability/maintainability and to avoid repeating the expression evaluation on each line I'd spread it out a bit:
Private Function readcrnFile(fileName As String) As IEnumerable(Of String)
Dim exp As New RegEx("[[[]Last Name=(?<LastName>[^]]+)]")
Return File.ReadLines(fileName).
Select(Function(line) exp.Match(line)).
Where(Function(m) m.Success).
Select(Function(m) m.Groups("LastName").Value)
End Function
See a simple example of the expression here:
https://dotnetfiddle.net/gJf3su
Dim strval As String = " [Name=John][Last Name=xxx_xxx][Address=xxxx][Age=22][Phone Number=8454845]"
Dim strline() As String = strval.Split(New String() {"[", "]"}, StringSplitOptions.RemoveEmptyEntries) _
.Where(Function(s) Not String.IsNullOrWhiteSpace(s)) _
.ToArray()
Dim lastnameArray() = strline(1).Split("=")
Dim lastname = lastnameArray(1).ToString()
Using your sample data...
I read the file and trim off the first and last bracket symbol. The small c following the the 2 strings tell the compiler that this is a Char. The braces enclosed an array of Char which is what the Trim method expects.
Next we split the file text into an array of strings with the .Split method. We need to use the overload that accepts a String. Although the docs show Split(String, StringSplitOptions), I could only get it to work with a string array with a single element. Split(String(), StringSplitOptions)
Then I looped through the string array called splits, checking for and element that starts with "Last Name=". As soon as we find it we return a substring that starts at position 10 (starts at zero).
If no match is found, an empty string is returned.
Private Function readcrnFile() As String
Dim LineInput = File.ReadAllText("system.txt").Trim({"["c, "]"c})
Dim splits = LineInput.Split({"]["}, StringSplitOptions.None)
For Each s In splits
If s.StartsWith("Last Name=") Then
Return s.Substring(10)
End If
Next
Return ""
End Function
Usage...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = readcrnFile()
End Sub
You can easily split that line in an array of strings using as separators the [ and ] brackets and removing any empty string from the result.
Dim input As String = "[Name=John][Last Name=xxx_xxx][Address=xxxx][Age=22][Phone Number=8454845]"
Dim parts = input.Split(New Char() {"["c, "]"c}, StringSplitOptions.RemoveEmptyEntries)
At this point you have an array of strings and you can loop over it to find the entry that starts with the last name key, when you find it you can split at the = character and get the second element of the array
For Each p As String In parts
If p.StartsWith("Last Name") Then
Dim data = p.Split("="c)
field.Add(data(1))
Exit For
End If
Next
Of course, if you are sure that the second entry in each line is the Last Name entry then you can remove the loop and go directly for the entry
Dim data = parts(1).Split("="c)
A more sophisticated way to remove the for each loop with a single line is using some of the IEnumerable extensions available in the Linq namespace.
So, for example, the loop above could be replaced with
field.Add((parts.FirstOrDefault(Function(x) x.StartsWith("Last Name"))).Split("="c)(1))
As you can see, it is a lot more obscure and probably not a good way to do it anyway because there is no check on the eventuality that if the Last Name key is missing in the input string
You should first know the difference between ReadAllLines() and ReadLines().
Then, here's an example using only two simple string manipulation functions, String.IndexOf() and String.Substring():
Sub Main(args As String())
Dim entryMarker As String = "[Last Name="
Dim closingMarker As String = "]"
Dim FileName As String = "C:\test\test_1\db\update\network\system.txt"
Dim value As String = readcrnFile(entryMarker, closingMarker, FileName)
If Not IsNothing(value) Then
Console.WriteLine("value = " & value)
Else
Console.WriteLine("Entry not found")
End If
Console.Write("Press Enter to Quit...")
Console.ReadKey()
End Sub
Private Function readcrnFile(ByVal entry As String, ByVal closingMarker As String, ByVal fileName As String) As String
Dim entryIndex As Integer
Dim closingIndex As Integer
For Each line In File.ReadLines(fileName)
entryIndex = line.IndexOf(entry) ' see if the marker is in our line
If entryIndex <> -1 Then
closingIndex = line.IndexOf(closingMarker, entryIndex + entry.Length) ' find first "]" AFTER our entry marker
If closingIndex <> -1 Then
' calculate the starting position and length of the value after the entry marker
Dim startAt As Integer = entryIndex + entry.Length
Dim length As Integer = closingIndex - startAt
Return line.Substring(startAt, length)
End If
End If
Next
Return Nothing
End Function

VB.NET - It keep replacing itself

I have in a text file lines of this format:
word1|word2|word3
anotherword1|anotherword2
I'm trying to split each word one by one per every line of that file and once program detect if the richtextbox has one of these words will replace that word with the unsplitted line. Example: From word1 to word1|word2|word3
Here is what I have so far:
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
For Each line As String In File.ReadLines("C:\text.txt")
Dim input As String = line
Dim result As String() = line.Split(New String() {"|"}, StringSplitOptions.None)
For Each s As String In result
Try
Dim linex As String = line
RichTextBox1.Text = RichTextBox1.Text.Replace(s, " " & linex)
Catch exxx As Exception
End Try
Next
Next
End Sub
It works great, but after the replacement, the replaced text still have the detected word and it keep replacing itself with word1|word2|word3 forever. And I want do do the process just once.
Like this: Click to see
Due to the format the words are stored in, it will be much easier to achieve what you want using Regular Expressions:
Dim lines = File.ReadLines("C:\text.txt")
For Each line As String In lines
Dim pat = String.Format("\b({0})\b", line)
RichTextBox1.Text = Regex.Replace(RichTextBox1.Text, pat, line)
Next
This should do pretty much what you want.
Check it here.

How to find indexes for certain character in a string VB.NET

I'm beginner with VB.net.
How do I read indexes for certain character in a string? I read an barcode and I get string like this one:
3XXX123456-C-AA123456TY-667
From that code I should read indexes for character "-" so I can cut the string in parts later in the code.
For example code above:
3456-C
6TY-667
The length of the string can change (+/- 3 characters). Also the places and count of the hyphens may vary.
So, I'm looking for code which gives me count and position of the hyphens.
Thanks in advance!
Use the String.Splt method.
'a test string
Dim BCstring As String = "3XXX123456-C-AA123456TY-667"
'split the string, removing the hyphens
Dim BCflds() As String = BCstring.Split({"-"c}, StringSplitOptions.None)
'number of hyphens in the string
Dim hyphCT As Integer = BCflds.Length - 1
'look in the debuggers immediate window
Debug.WriteLine(BCstring)
'show each field
For Each s As String In BCflds
Debug.WriteLine(String.Format("{0,5} {1}", s.Length, s))
Next
'or
Debug.WriteLine(BCstring)
For idx As Integer = 0 To hyphCT
Debug.WriteLine(String.Format("{0,5} {1}", BCflds(idx).Length, BCflds(idx)))
Next
If all you need are the parts between hyphens then as suggested by dbasnett use the split method for strings. If by chance you need to know the index positions of the hyphens you can use the first example using Lambda to get the positions which in turn the count give you how many hyphens were located in the string.
When first starting out with .NET it's a good idea to explore the various classes for strings and numerics as there are so many things that some might not expect to find that makes coding easier.
Dim barCode As String = "3XXX123456-C-AA123456TY-667"
Dim items = barCode _
.Select(Function(c, i) New With {.Character = c, .Index = i}) _
.Where(Function(item) item.Character = "-"c) _
.ToList
Dim hyphenCount As Integer = items.Count
Console.WriteLine("hyphen count is {0}", hyphenCount)
Console.WriteLine("Indices")
For Each item In items
Console.WriteLine(" {0}", item.Index)
Next
Console.WriteLine()
Console.WriteLine("Using split")
Dim barCodeParts As String() = barCode.Split("-"c)
For Each code As String In barCodeParts
Console.WriteLine(code)
Next
Here is an example that'll split your string and allow you to parse through the values.
Private Sub TestSplits2Button_Click(sender As Object, e As EventArgs) Handles TestSplits2Button.Click
Try
Dim testString As String = "3XXX123456-C-AA123456TY-667"
Dim vals() As String = testString.Split(Convert.ToChar("-"))
Dim numberOfValues As Integer = vals.GetUpperBound(0)
For Each testVal As String In vals
Debug.Print(testVal)
Next
Catch ex As Exception
MessageBox.Show(String.Concat("An error occurred: ", ex.Message))
End Try
End Sub

loop - reading text after a certain string up until a certain string

start=AKS-RHzlSXSftLGYdBNk.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1&
For every instance of the word 'start' I need to be able to get the text after the first full stop, right up until the & symbol. E.g. 'eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1'.
There will be more than one instance of this. They will need to be appended to a listbox.
What is the simplest/quickest way to do this? (Using possibly streamreader - text file)
The simplest and quickest way will be to read each line, and check if it .StartsWith("start="). If so, then get the .IndexOf(".") and the .IndexOf("&", <whereever the first indexOf was>). Get the .SubString which encompasses those two values. I'm sure you can write the code yourself from that ;)
I tested this function with a button click, output text each line on a textbox. I am sure you can adapt this to your code.
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
txtResults.Text = ""
Dim ParseString As String
ParseString = "start=123341.23124&kjdshfkjsdaksdstart=1231.2321312&kadhskjashdkjastart=1231.23126789898&skjdfhkjsd"
Dim Delimiters() As String = New String() {"start="}
Dim Words() As String
Words = ParseString.Split(Delimiters, CompareMethod.Text)
For Each Part In Words
Dim Middle As String
Middle = Part.Split(".").Skip(1).Take(1).FirstOrDefault()
Dim Good As String
Good = Middle.Split("&").FirstOrDefault()
txtResults.Text += Good + vbNewLine
Next
End Sub
Output was
23124
2321312
23126789898
Added 31104 lines to a string and ran, took about 11 seconds to run on my laptop. Might be too slow for your app?

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"
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
Some advice:
always dispose resources (use using or try catch finally with
resource.close)
never trust user inputs.
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
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.