How can I Parse text document in VB,Net for values? - vb.net

I'm looking to parse this text file into strings to insert them into a database.
Source Text File gets read as the following string:
Line of unwanted text
Another line of unwanted data
Timestamp: 1/1/10 12:00 PM
ID: 1
Details: All data processed. Length will vary.
I'd like to just read Timestamp, ID and Details and place them into separate strings to insert them into a data table. What is the best method of capturing everything after the : and to the end of the line?
Dim Details as String = TextFile.Substring(Message.IndexOf("Details:"), X)

If you have to use a String as input, you can use String.Split to break it up into lines, and process each line. String.Substring can be used to extract the rest of the line - I've just hardcoded the starting positions below.
Dim timestamp As String = Nothing
Dim id As String = Nothing
Dim details As String = Nothing
For Each line In input.Split({vbCrLf, vbCr, vbLf}, StringSplitOptions.None)
If line.StartsWith("timestamp:", StringComparison.OrdinalIgnoreCase) Then
timestamp = line.Substring(10).Trim()
ElseIf line.StartsWith("id:", StringComparison.OrdinalIgnoreCase) Then
id = line.Substring(3).Trim()
ElseIf line.StartsWith("details:", StringComparison.OrdinalIgnoreCase) Then
details = line.Substring(8).Trim()
End If
Next
If you can change how you read the data, then the loop could just be:
For each line In File.ReadLines("your\file\name.txt")
...
Next

Assuming your files are flawless... One way to do it :
Imports System.IO
Dim AllLines() As String = File.ReadAllLines(FilePath)
Dim DatasIndex As Int32 = -1
For i As Int32 = 0 To AllLines.Length - 1
If AllLines(i).StartsWith("T") OrElse AllLines(i).StartsWith("t") Then
If AllLines(i).ToUpper().StartsWith("TIMESTAMP: ") Then
DatasIndex = i
Exit For
End If
End If
Next
If DatasIndex > -1 Then
' Dim ReadDate As Date = Date.Parse(AllLines(DatasIndex).Substring(11))
' Dim ReadID As Int32 = Integer.Parse(AllLines(DatasIndex + 1).Substring(4))
Dim ReadDate As String = AllLines(DatasIndex).Substring(11)
Dim ReadID As String = AllLines(DatasIndex + 1).Substring(4)
Dim ReadDetails As String = AllLines(DatasIndex + 2).Substring(9)
' send to database
End If
You didn't tell if Timestamp: , ID: and Details: Strings are always in the same order and has a trailing space after each property name.

Related

Find word in a txt file and read previous line VB.NET

I am reading a txt file line by line in VB to look for the word "unable". That much works. The code is here:
Imports System
Imports System.IO
Imports PartMountCollector.HandMount_WebReference
Imports System.Threadingtime
Imports eCenter.Motor.VBConnect
Module Program
Sub Main(args As String())
Dim unUpdate As String = "Unable"
Dim time = DateTime.Now
Dim yesterday = time.AddDays(-1)
Dim format As String = "yyyyMMdd"
Dim words As String()
For Each Line As String In File.ReadLines("C:\Users\te-smtinternal\Desktop\ReStockLog\" + time.ToString(format) + ".txt")
words = Split(Line)
If Line.Contains(unUpdate) = True Then
Console.WriteLine("Exist")
'Read previous line looking for "Success"'
End If
Console.WriteLine("not found")
Next
End Sub
End Module
Now I need be able to identify this line and read the previous line, looking for the word "success".
Any help would be appreciated
Instead of trying to handle each line one at a time, you could read all the lines and then iterate through them which would give you access to the previous line, like:
Dim lines = IO.File.ReadAllLines(file_name)
dim previous_line as string = ""
for x as integer = 0 to lines.count-1
if lines(x).ToString.Contains("unable") then previous_line = lines(x-1).ToString
next
of course you would need to handle the exception of finding a hit on the first line which would throw an out of index error. So you would simply need to add a check to make sure x > 0.
You just need to declare a variable outside of the loop to store the previous line. Here I've named it previousLine...
Const unUpdate As String = "Unable"
Dim time = DateTime.Now
Const format As String = "yyyyMMdd"
Dim previousLine as String = Nothing
For Each currentLine As String In File.ReadLines("C:\Users\te-smtinternal\Desktop\ReStockLog\" + time.ToString(format) + ".txt")
If currentLine.Contains(unUpdate) Then
Console.WriteLine("Exist")
If previousLine Is Nothing Then
' The very first line of input contains unUpdate
Else If previousLine.Contains("Success")
' A line after the first line of input contains unUpdate
End If
Else
Console.WriteLine("not found")
End If
previousLine = currentLine
Next
At the end of each loop iteration the currentLine becomes the previousLine and, if there is another iteration, it will read a new value for currentLine.
Also note that in...
If Line.Contains(unUpdate) = True Then
...you don't need the = True comparison because Contains() already returns a Boolean.

VB.net Read Specific Lines From a Text File That Start With and Stop Reading When Start With

I'm looking to read lines from a text file that start with certain characters and stop when the line starts with other characters. So in my example I would like to start reading at line AB and stop at line EF however not all lines will contain the CD line. There will always be a AB line and EF line, however the number of lines in between is unknown.
Here is an example of the lines in a text file I would be reading. You can see that this will create two rows in the DataGridView however the first row is missing the CD line and should be blank.
AB-id1
EF-address1
AB-id2
CD-name1
EF-address2
Here is the code I have so far:
Dim lines() As String = File.ReadAllLines(textfile)
For i As Integer = 0 To lines.Length - 1
If lines(i).StartsWith("AB") Then
Dim nextLines As String() = lines.Skip(i + 1).ToArray
Dim info As String = nextLines.FirstOrDefault(Function(Line) Line.StartsWith("CD"))
Dim name As String = "Yes"
Dim info2 As String = nextLines.FirstOrDefault(Function(Line) Line.StartsWith("EF"))
Dim address As String = "Yes"
End If
DataGridView.Rows.Add(name,address)
Next
Now the output I currently get is:
|Yes|Yes|
|Yes|Yes|
And I should be getting:
||Yes|
|Yes|Yes|
It looks like it's reading too far down the text file and I need it to stop reading at EF. I've tried Do while and Do Until with no success. Any suggestions?
You could use the Array.FindIndex function to get the index of the next line starting with your prefix. This way you don't have to skip lines and create a new array each time.
Try this out instead:
Dim lines() As String = File.ReadAllLines(textFile)
For i As Integer = 0 To lines.Length - 1
If lines(i).StartsWith("AB") Then
Dim addressIndex As Integer = Array.FindIndex(lines, i + 1, Function(Line) Line.StartsWith("EF"))
Dim address As String = If(addressIndex <> -1, lines(addressIndex).Substring(3), "") ' Get everything past the "-"
Dim name As String = ""
If addressIndex <> -1 Then
Dim nameIndex As Integer = Array.FindIndex(lines, i + 1, addressIndex - i, Function(line) line.StartsWith("CD"))
If nameIndex <> -1 Then
name = lines(nameIndex).Substring(3) ' Get everything past the "-"
End If
End If
DataGridView.Rows.Add(name, address)
End If
Next

For Loop: changing the loop condition while it is looping

What I want to do is replace all 'A' in a string with "Bb". but it will only loop with the original string not on the new string.
for example:
AAA
BbAA
BbBbA
and it stops there because the original string only has a length of 3. it reads only up to the 3rd index and not the rest.
Dim txt As String
txt = output_text.Text
Dim a As String = a_equi.Text
Dim index As Integer = txt.Length - 1
Dim output As String = ""
For i = 0 To index
If (txt(i) = TextBox1.Text) Then
output = txt.Remove(i, 1).Insert(i, a)
txt = output
TextBox2.Text += txt + Environment.NewLine
End If
Next
End Sub
I think this leaves us looking for a String.ReplaceFirst function. Since there isn't one, we can just write that function. Then the code that calls it becomes much more readable because it's quickly apparent what it's doing (from the name of the function.)
Public Function ReplaceFirst(searched As String, target As String, replacement As String) As String
'This input validation is just for completeness.
'It's not strictly necessary.
'If the searched string is "null", throw an exception.
If (searched Is Nothing) Then Throw New ArgumentNullException("searched")
'If the target string is "null", throw an exception.
If (target Is Nothing) Then Throw New ArgumentNullException("target")
'If the searched string doesn't contain the target string at all
'then just return it - were done.
Dim foundIndex As Integer = searched.IndexOf(target)
If (foundIndex = -1) Then Return searched
'Build a new string that replaces the target with the replacement.
Return String.Concat(searched.Substring(0, foundIndex), replacement, _
searched.Substring(foundIndex + target.Length, searched.Length - (foundIndex + target.Length)))
End Function
Notice how when you read the code below, you don't even have to spend a moment trying to figure out what it's doing. It's readable. While the input string contains "A", replace the first "A" with "Bb".
Dim input as string = "AAA"
While input.IndexOf("A") > -1
input = input.ReplaceFirst(input,"A","Bb")
'If you need to capture individual values of "input" as it changes
'add them to a list.
End While
You could optimize or completely replace the function. What matters is that your code is readable, someone can tell what it's doing, and the ReplaceFirst function is testable.
Then, let's say you wanted another function that gave you all of the "versions" of your input string as the target string is replaced:
Public Function GetIterativeReplacements(searched As String, target As String, replacement As String) As List(of string)
Dim output As New List(Of String)
While searched.IndexOf(target) > -1
searched = ReplaceFirst(searched, target, replacement)
output.Add(searched)
End While
Return output
End Function
If you call
dim output as List(of string) = GetIterativeReplacments("AAAA","A","Bb")
It's going to return a list of strings containing
BbAAA, BbBbAA, BbBbBbA, BbBbBbBb
It's almost always good to keep methods short. If they start to get too long, just break them into smaller methods with clear names. That way you're not trying to read and follow and test one big, long function. That's difficult whether or not you're a new programmer. The trick isn't being able to create long, complex functions that we understand because we wrote them - it's creating small, simpler functions that anyone can understand.
Check your comments for a better solution, but for future reference you should use a while loop instead of a for loop if your condition will be changing and you're wanting to take that change into account.
I've made a simple example below to help you understand. If you tried the same with a for loop, you'd only get "one" "two" and "three" printed because the for loop doesn't 'see' that vals was changed
Dim vals As New List(Of String)
vals.Add("one")
vals.Add("two")
vals.Add("three")
Dim i As Integer = 0
While i < vals.Count
Console.WriteLine(vals(i))
If vals(i) = "two" Then
vals.Add("four")
vals.Add("five")
End If
i += 1
End While
If you do want to replace one by one instead of using the Replace function, you could use a while loop to look for the index of your search character/string, and then replace/insert at that index.
Sub Main()
Dim a As String = String.Empty
Dim b As String = String.Empty
Dim c As String = String.Empty
Dim d As Int32 = -1
Console.Write("Whole string: ")
a = Console.ReadLine()
Console.Write("Replace: ")
b = Console.ReadLine()
Console.Write("Replace with: ")
c = Console.ReadLine()
d = a.IndexOf(b)
While d > -1
a = a.Remove(d, b.Length)
a = a.Insert(d, c)
d = a.LastIndexOf(b)
End While
Console.WriteLine("Finished string: " & a)
Console.ReadLine()
End Sub
Output would look like this:
Whole string: This is A string for replAcing chArActers.
Replace: A
Replace with: Bb
Finished string: This is Bb string for replBbcing chBbrBbcters.
I was going to write a while loop to answer your question, but realized (with assistance from others) that you could just .replace(x,y)
Output.Text = Input.Text.Replace("A", "Bb")
'Input = N A T O
'Output = N Bb T O
Edit: There is probably a better alternative, but i quickly jotted this loop down, hope it helps.
You've said your new and don't fully understand while loops. So if you don't understand functions either or how to pass arguments to them, I'd suggest looking that up too.
This is your Event, It can be a Button click or Textbox text change.
'Cut & Paste into an Event (Change textboxes to whatever you have input/output)
Dim Input As String = textbox1.Text
Do While Input.Contains("A")
Input = ChangeString(Input, "A", "Bb")
' Do whatever you like with each return of ChangeString() here
Loop
textbox2.Text = Input
This is your Function, with 3 Arguments and a Return Value that can be called in your code
' Cut & Paste into Code somewhere (not inside another sub/Function)
Private Function ChangeString(Input As String, LookFor As Char, ReplaceWith As String)
Dim Output As String = Nothing
Dim cFlag As Boolean = False
For i As Integer = 0 To Input.Length - 1
Dim c As Char = Input(i)
If (c = LookFor) AndAlso (cFlag = False) Then
Output += ReplaceWith
cFlag = True
Else
Output += c
End If
Next
Console.WriteLine("Output: " & Output)
Return Output
End Function

get string between other string vb.net

I have code below. How do I get strings inside brackets? Thank you.
Dim tmpStr() As String
Dim strSplit() As String
Dim strReal As String
Dim i As Integer
strWord = "hello (string1) there how (string2) are you?"
strSplit = Split(strWord, "(")
strReal = strSplit(LBound(strSplit))
For i = 1 To UBound(strSplit)
tmpStr = Split(strSplit(i), ")")
strReal = strReal & tmpStr(UBound(tmpStr))
Next
Dim src As String = "hello (string1) there how (string2) are you?"
Dim strs As New List(Of String)
Dim start As Integer = 0
Dim [end] As Integer = 0
While start < src.Length
start = src.IndexOf("("c, start)
If start <> -1 Then
[end] = src.IndexOf(")"c, start)
If [end] <> -1 Then
Dim subStr As String = src.Substring(start + 1, [end] - start - 1)
If Not subStr.StartsWith("(") Then strs.Add(src.Substring(start + 1, [end] - start - 1))
End If
Else
Exit While
End If
start += 1 ' Increment start to skip to next (
End While
This should do it.
Dim result = Regex.Matches(src, "\(([^()]*)\)").Cast(Of Match)().Select(Function(x) x.Groups(1))
Would also work.
This is what regular expressions are for. Learn them, love them:
' Imports System.Text.RegularExpressions
Dim matches = Regex.Matches(input, "\(([^)]*)\)").Cast(of Match)()
Dim result = matches.Select(Function (x) x.Groups(1))
Two lines of code instead of more than 10.
In the words of Stephan Lavavej: “Even intricate regular expressions are easier to understand and modify than equivalent code.”
Use String.IndexOf to get the position of the first opening bracket (x).
Use IndexOf again the get the position of the first closing bracket (y).
Use String.Substring to get the text based on the positions from x and y.
Remove beginning of string up to y+1.
Loop as required
That should get you going.
This may also work:
Dim myString As String = "Hello (FooBar) World"
Dim finalString As String = myString.Substring(myString.IndexOf("("), (myString.LastIndexOf(")") - myString.IndexOf("(")) + 1)
Also 2 lines.

Extract characters from a long string and reformat the output to CSV by using keywords with VB.net

I am new to VB.Net 2008. I have a task to resolve, it is regading extracting characters from a long string to the console, the extracted text shall be reformatted and saved into a CSV file. The string comes out of a database.
It looks something like: UNH+RAM6957+ORDERS:D:96A:UN:EGC103'BGM+38G::ZEW+REQEST6957+9'DTM+Z05:0:805'DTM+137:20100930154
The values are seperated by '.
I can query the database and display the string on the console, but now I need to extract the
Keyword 'ORDERS' for example, and lets say it's following 5 Characters. So the output should look like: ORDERS:D:96A then I need to extract the keyword 'BGM' and its following five characters so the output should look like: BGM+38G:
After extracting all the keywords, the result should be comma seperated and look like:
ORDERS:D:96A,BGM+38G: it should be saved into a CSV file automatically.
I tried already:
'Lookup for containing KeyWords
Dim FoundPosition1 = p_EDI.Contains("ORDERS")
Console.WriteLine(FoundPosition1)
Which gives the starting position of the Keyword.
I tried to trim the whole thing around the keyword "DTM". The EDI variable holds the entire string from the Database:
Dim FoundPosition2 = EDI
FoundPosition2 = Trim(Mid(EDI, InStr(EDI, "DTM")))
Console.WriteLine(FoundPosition2)
Can someone help please?
Thank you in advance!
To illustrate the steps involved:
' Find the position where ORDERS is in the string.'
Dim foundPosition = EDI.IndexOf("ORDERS")
' Start at that position and extract ORDERS + 5 characters = 11 characters in total.'
Dim ordersData = EDI.SubString(foundPosition, 11)
' Find the position where BGM is in the string.'
Dim foundPosition2 = EDI.IndexOf("BGM")
' Start at that position and extract BGM + 5 characters = 8 characters in total.'
Dim bgmData = EDI.SubString(foundPosition2, 8)
' Construct the CVS data.'
Dim cvsData = ordersData & "," & bgmData
I don't have my IDE here, but something like this will work:
dim EDI as string = "UNH+RAM6957+ORDERS:D:96A:UN:EGC103'BGM+38G::ZEW+REQEST6957+9'DTM+Z05:0:805'DTM+137:20100930154"
dim result as string = KeywordPlus(EDI, "ORDER", 5) + "," _
+ KeywordPlus(EDI, "BGM", 5)
function KeywordPlus(s as string, keyword as string, length as integer) as string
dim index as integer = s.IndexOf(keyword)
if index = -1 then return ""
return s.substring(index, keyword.length + length)
end function
for the interrested people among us, I have put the code together, and created
a CSV file out of it. Maybe it can be helpful to others...
If EDI.Contains("LOC") Then
Dim foundPosition1 = EDI.IndexOf("LOC")
' Start at that position and extract ORDERS + 5 characters = 11 characters in total.'
Dim locData = EDI.Substring(foundPosition1, 11)
'Console.WriteLine(locData)
Dim FoundPosition2 = EDI.IndexOf("QTY")
Dim qtyData = EDI.Substring(FoundPosition2, 11)
'Console.WriteLine(qtyData)
' Construct the CSV data.
Dim csvData = locData & "," & qtyData
'Console.WriteLine(csvData)
' Creating the CSV File.
Dim csvFile As String = My.Application.Info.DirectoryPath & "\Test.csv"
Dim outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(csvFile, True)
outFile.WriteLine(csvData)
outFile.Close()
Console.WriteLine(My.Computer.FileSystem.ReadAllText(csvFile))
End IF
Have fun!