VB.Net Parse/Replace a substring in a line - vb.net

I know this should be simple yet I am a little stuck. I am reading in a text file line by line. Each line is formated the same based off an ICD. I need to take the data at a specific location and replace it with x's.
For Example:
Line = "First Name Last Name Street Address State ZIP Other Data"
This is a fixed length ICD so address always starts at lets say position 100 and goes through 150
I need to replace everything position 100 to 150 with x's.
From there I am writing the line out to a new file and that part is working fine.
Thank you so much for your help.

Use this:
Dim newLine As String = Line.Substring(0, 100) & New String("x"c, 50) & line.Substring(150)

You can create a function that takes in the string, start index, and length and returns the string with the replaced characters. This will also handle error cases where the length is greater than string length (in which case the rest of the string is replaced with the char you've chosen).
Private Shared Function ReplaceCharsWithChar(input As String, firstIndex As Integer, length As Integer, replaceChar As Char) As String
Dim sb As New StringBuilder(input)
For i As Integer = firstIndex To Math.Min(firstIndex + length, input.Length) - 1
sb(i) = replaceChar
Next
Return sb.ToString()
End Function
And call it like this
Dim input As String = "First Name Last Name Street Address State ZIP Other Data"
Dim result As String = ReplaceCharsWithChar(input, 10, 5, "x"C)
'output would be First Namexxxxx Name Street Address State ZIP Other Data

There is no built-in method to do that, so you'll need to implement it yourself. The simplest way would be to use the String.Substring method to extract the parts you want (the beginning and ending of the string), and then concatenate them back together with the replacement value. For instance:
Dim newValue As String = line.Substring(0, 99) & New String("X"c, 50) & line.Substring(150)
However, if you need to replace more than one section of the string, it may be easier and more efficient to use the StringBuilder, which allows you to manipulate each character in place:
Dim builder As New StringBuilder(line)
For i As Integer = 100 to 149
builder.Chars(i) = "X"c
Next
line = builder.ToString()

Related

Is it possible to use String.Split() when NewLine is the delimiter?

I have a question which asks me to calculate something from an input file. The problem is, the lines in the file don't use any special character as delimiter, like , or |. I will show it down below.
Data Communication
20
Visual Basic
40
The output I need to write to another file should look like this:
Data communication 20
Visual Basic 40
Total Books : 60
The problem is, how can I specify the delimiter? Like when there is a symbol as in strArray = strLine.Split(","). Since there is nothing I can use as delimiter, how can I split the file content?
There's no real need to split the text in the input file, when you can read a file line by line using standard methods.
You can use, e.g., a StreamReader to read the lines from the source file, check whether the current line is just text or it can be converted to a number, using Integer.TryParse and excluding empty lines.
Here, when the line read is not numeric, it's added as a Key in a Dictionary(Of String, Integer), unless it already exists (to handle duplicate categories in the source file).
If the line represents a number, it's added to the Value corresponding to the category Key previously read, stored in a variable named previousLine.
This setup can handle initial empty lines, empty lines in the text body and duplicate categories, e.g.,
Data Communication
20
Visual Basic
40
C#
100
Visual Basic
10
Other stuff
2
C++
10000
Other stuff
1
If a number is instead found in the first line, it's treated as a category.
Add any other check to handle a different structure of the input file.
Imports System.IO
Imports System.Linq
Dim basePath = "[Path where the input file is stored]"
Dim booksDict = New Dictionary(Of String, Integer)
Dim currentValue As Integer = 0
Dim previousLine As String = String.Empty
Using sr As New StreamReader(Path.Combine(basePath, "Books.txt"))
While sr.Peek > -1
Dim line = sr.ReadLine().Trim()
If Not String.IsNullOrEmpty(line) Then
If Integer.TryParse(line, currentValue) AndAlso (Not String.IsNullOrEmpty(previousLine)) Then
booksDict(previousLine) += currentValue
Else
If Not booksDict.ContainsKey(line) Then
booksDict.Add(line, 0)
End If
End If
End If
previousLine = line
End While
End Using
Now, you have a Dictionary where the Keys represent categories and the related Value is the sum of all books in that category.
You can Select() each KeyValuePair of the Dictionary and transform it into a string that represents the Key and its Value (Category:Number).
Here, also OrderBy() is used, to order the categories alphabetically, in ascending order; it may be useful.
File.WriteAllLines is then called to store the strings generated.
In the end, a new string is appended to the file, using File.AppendAllText, to write the sum of all books in all categories. The Sum() method sums all the Values in the Dictionary.
Dim newFilePath = Path.Combine(basePath, "BooksNew.txt")
File.WriteAllLines(newFilePath, booksDict.
Select(Function(kvp) $"{kvp.Key}:{kvp.Value}").OrderBy(Function(s) s))
File.AppendAllText(newFilePath, vbCrLf & "Total Books: " & booksDict.Sum(Function(kvp) kvp.Value).ToString())
The output is:
C#:100
C++:10000
Data Communication:20
Other stuff:3
Visual Basic:50
Total Books: 10173
Sure.. System.IO.File.ReadAllLines() will read the whole file and split into an array based on newlines, so you'll get an array of 4 elements. You can process it with a flipflop boolean to get alternate lines, or you can try and parse the line to a number and if it works, then its a number and if not, it's a string. If it's a number take the string you remembered (using a variable) from the previous loop
Dim arr = File.ReadALlLines(...)
Dim isStr = True
Dim prevString = ""
For Each s as String in arr
If isStr Then
prevString = s
Else
Console.WriteLine($"The string is {prevString} and the number is {s}")
End If
'flip the boolean
isStr = Not isStr
Next s
I used File.ReadAllLines to get an array containing each line in the file. Since the size of the file could be larger than the sample shown, I am using a StringBuilder. This save having to throw away and create a new string on each iteration of the loop.
I am using interpolated strings indicated by the $ preceding the quotes. This allows you to insert variables into the string surrounded by braces.
Note the Step 2 in the For loop. i will increment by 2 instead of the default 1.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lines = File.ReadAllLines("input.txt")
Dim sb As New StringBuilder
Dim total As Integer
For i = 0 To lines.Length - 2 Step 2
sb.AppendLine($"{lines(i)} {lines(i + 1)}")
total += CInt(lines(i + 1))
Next
sb.AppendLine($"Total Books: {total}")
TextBox1.Text = sb.ToString
End Sub

search for phrase in line of text box vb.net

I'm using VB.NET and I've got a text box which contains the following information (that changes depending on the video file selected in a list box):-
type: ffmpeg-producer
filename: C:\caspar\Server\media\\adi.divx
width: 640
height: 360
progressive: false
fps: 25
loop: false
frame-number: 0
nb-frames: 4626
file-frame-number: 0
file-nb-frames: 4626
When I click a button, I need to add the data to a variable. So for example, I would need to take 4626 from the line
nb-frames: 4626
and 25 from the
line fps:25
and put them both in variables to then calculate the actual duration.
Public Function GetValue(ByVal varName As String) As String
Dim lines() As String = Split(TextBox1.Text, Delimiter:=Environment.NewLine)
For Each line As String In lines
Dim words() As String = Split(line, Delimiter:=": ", Limit:=2)
If words(0) = varName And words.Length = 2 Then
Return words(1)
End If
Next
Return Nothing
End Function
You could also use a regular expression approach. If you you are not familiar with regular expressions I strongly encourage you to into it.
Here is what you would do (where txtMyTextbbox is the textbox, that holds your data:
Dim strRegex as String = "([\w-]*):\s*(.*)"
Dim myRegex As New Regex(strRegex, RegexOptions.None)
Dim strTargetString As String = txtMyTextbox.Text
For Each myMatch As Match In myRegex.Matches(strTargetString)
If myMatch.Success Then
dim category = myMatch.Groups(1).Value
dim value = myMatch.Groups(2).Value
End If
Next
This code loops through all matches in your textbox text and looks for a text followed by a colon followed by spaces and the rest of the line. Each match is captured in the myMatch variable where you can access the part before the colon through myMatch.Groups(1).value and the part after the colon (excluding the space) through the second group.
Leave a comment if you have further questions.

Lowercase the first word

Does anybody know how to lowercase the first word for each line in a textbox?
Not the first letter, the first word.
I tried like this but it doesn't work:
For Each iz As String In txtCode.Text.Substring(0, txtCode.Text.IndexOf(" "))
iz = LCase(iz)
Next
When you call Substring, it is making a copy of that portion of the string and returning it as a new string object. So, even if you were successfully changing the value of that returned sub-string, it still would not change the original string in the Text property.
However, strings in .NET are immutable reference-types, so when you set iz = ... all you are doing is re-assigning the iz variable to point to yet another new string object. When you set iz, you aren't even touching the value of that copied sub-string to which it previously pointed.
In order to change the value of the text box, you must actually assign a new string value to its Text property, like this:
txtCode.Text = "the new value"
Since that is the case, I would recommend building a new string, using a StringBuilder object, and then, once the modified string is complete, then set the text box's Text property to that new string, for instance:
Dim builder As New StringBuilder()
For Each line As String In txtCode.Text.Split({Environment.NewLine}, StringSplitOptions.None)
' Fix case and append line to builder
Next
txtCode.Text = builder.ToString()
The solutions here are interesting but they are ignoring a fundamental tool of .NET: regular expressions. The solution can be written in one expression:
Dim result = Regex.Replace(txtCode.Text, "^\w+",
Function (match) match.Value.ToLower(), RegexOptions.Multiline)
(This requires the import System.Text.RegularExpressions.)
This solution is likely more efficient than all the other solutions here (It’s definitely more efficient than most), and it’s less code, thus less chance of a bug and easier to understand and to maintain.
The problem with your code is that you are running the loop only on each character of the first word in the whole TextBox text.
This code is looping over each line and takes the first word:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
line = line.Trim().ToLower()
If line.IndexOf(" ") > 0 Then
line = line.Substring(0, line.IndexOf(" ")).Trim()
End If
// do something with 'line' here
Next
Loop through each of the lines of the textbox, splitting all of the words in the line, making sure to .ToLower() the first word:
Dim strResults As String = String.Empty
For Each strLine As String In IO.File.ReadAllText("C:\Test\StackFlow.txt").Split(ControlChars.NewLine)
Dim lstWords As List(Of String) = strLine.Split(" ").ToList()
If Not lstWords Is Nothing Then
strResults += lstWords(0).ToLower()
If lstWords.Count > 1 Then
For intCursor As Integer = 1 To (lstWords.Count - 1)
strResults += " " & lstWords(intCursor)
Next
End If
End If
Next
I used your ideas guys and i made it up to it like this:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
Dim abc() As String = line.Split(" ")
txtCode.Text = txtCode.Text.Replace(abc(0), LCase(abc(0)))
Next
It works like this. Thank you all.

String Manipulation To Get An Item In The Middle Of A CSV File

I have a csv file I need to parse and get an item out of the middle of it. I have chose string manipulation to do this.
sample input file data would be..
Nick,frog,snake,1234
I can get the last entry "1234" with this code..
line.Substring(line.LastIndexOf(",") + 1)
How would I get the 3rd entry, "snake", with substrings? (what the OP means is: how can I get the third element in the comma-separated string, which happens to be "snake")
If you've stored the text of your file in myInputText, and you want to access the third item, the following will work:
resultString = Strings.Split(myInputText, ",")(2)
You can access any string in the file this way.
How would I get the 3rd entry "snake" with substrings?
The easiest way would obviously be with split:
Dim teststr As String = "Nick,frog,snake,1234"
Dim teststr2 As String = teststr.Split(","c)(2)
A simple function like this, using substring, will do the same thing:
Dim teststr3 As String = GetStr(teststr, 2)
Private Function GetStr(input As String, index As Integer) As String
input += ","
Dim counter As Integer = 0
If index <> 0 Then
Do
input = input.Substring(input.IndexOf(","c)).TrimStart(","c)
counter += 1
Loop Until counter = index
End If
GetStr = input.Substring(0, input.IndexOf(","c))
End Function

compare a string and trim in vb.net

I have this string that shall come in from another file. The string has maximum length of 102 digits. I need to compare the string with numbers in a pair and delete those from that string.
e.g - 6125223659587412563265... till 102
numbers that compare with this string-
first set - 61
new string = 25223659587412563265
second set - 36
new string = 252259587412563265
and so on. the set of numbers shall go to maximum of 51 pairs = 102, which shall give an end result of string = ""
How can i achieve this in a loop?
this is not answer, this is editing the question. i dont know why but the edit button just vaniashed so i have to edit question here.
No duplicates will ever be in this string. and in the end when compares are done, i want to see what numbers are left in pairs.
Dim input As String = "6125223659587412563265"
Dim targets As String() = {"61", "36"}
For Each target As String In targets
input = input.Replace(target, "")
Next
Debug.Assert(input = "252259587412563265")
Here is a simple solution. You will need to add your pairs to the List(Of String) and also initialize input to the string you want to alter.
Dim pairs As New List(Of String)()
Dim input As String = String.Empty
For Each pair As String In pairs
input = input.Replace(pair, String.Empty)
Next