Replacing string at certain index of Split - vb.net

Using streamreader to read line by line of a text file. When I get to a certain line (i.e., 123|abc|99999||ded||789), I want to replace ONLY the first empty area with text.
So far, I've been toying with
If sLine.Split("|")(3) = "" Then
'This is where I'm stuck, I want to replace that index with mmm
End If
I want the output to look like this: 123|abc|99999|mmm|ded||789

Considering you already have code determining if the "mmm" string needs to be added or not, you could use the following:
Dim index As Integer = sLine.IndexOf("||")
sLine = sLine.Insert(index + 1, "mmm")

You could split the string, modify the array and rejoin it to recreate the string:
Dim sLine = "123|abc|99999||ded||789"
Dim parts = sLine.Split("|")
If parts(3) = "" Then
parts(3) = "mmm"
sLine = String.Join("|", parts)
End If

I gather that if you find one or more empty elements, you want to replace the first empty element with data and leave the rest blank. You can accomplish this by splitting on the pipe to get an array of strings, iterate through the array and replace the first empty element you come across and exit the loop, and then rejoin your array.
Sub Main()
Dim data As String = "123||abc|99999||ded||789"
Dim parts = data.Split("|")
For index = 0 To parts.Length - 1
If String.IsNullOrEmpty(parts(index)) Then
parts(index) = "mmm"
Exit For
End If
Next
data = String.Join("|", parts)
Console.WriteLine(data)
End Sub
Results:
123|mmm|abc|99999||ded||789

Related

How do I remove multiple empty lines in a text file

I wonder if someone is able to help. I have a m3u file with multiple lines of formatted text.
#EXTM3U
#RADIOBROWSERUUID:963194ef-0601-11e8-ae97-52543be04c81
#EXTINF:1,80s80s Christmas
http://streams.80s80s.de/christmas/mp3-192/streams.80s80s.de/
#RADIOBROWSERUUID:9638cfa5-0601-11e8-ae97-52543be04c81
#EXTINF:1,181.FM - Christmas Kountry
http://www.181.fm/stream/pls/181-xkkountry.pls
Whilst I have managed to extract the data into a format that I can need... I am left with multiple blank lines. A sample bit of code I used to Extract the data is...
If line.StartsWith("#EXTM3U") Then 'Remove
lines(i) = ""
End If
If line.StartsWith("#RADIOBROWSERUUID:") Then 'Remove
lines(i) = ""
End If
If line.StartsWith("#EXTINF:1,") Then 'Add # at beginning of line
lines(i) = line.Replace("#EXTINF:1,", "#")
End If
Which then leaves me with the following...
#80s80s Christmas
#http://streams.80s80s.de/christmas/mp3-192/streams.80s80s.de/
#181.FM - Christmas Kountry
#http://www.181.fm/stream/pls/181-xkkountry.pls
I just dont seem to be able to remove the empty/blank lines. I have used google as well as here and non of the answers seem to work for me. Here is the code that I am using...
Dim Newlines As String() = File.ReadAllLines(ofd.FileName)
For t As Integer = 0 To Newlines.Length - 1
Dim line2 As String = Newlines(t)
If line2.StartsWith("") Then ' Remove blank lines
Beep()
Newlines(t) = line2.Replace(Environment.NewLine, String.Empty)
End If
Next
File.WriteAllLines("NewTextm3u.txt", lines)
Can any body see where I am going wrong? Thank you very much.
You can do this:
Dim sFile As String = "c:\test2\test2.txt"
Dim Fdata As New List(Of String)
Fdata = File.ReadAllLines("c:\test2\test.txt").ToList
For i = Fdata.Count - 1 To 0 Step -1
If Fdata(i) = "" Then
Fdata.RemoveAt(i)
End If
Next
For Each sLine As String In Fdata
Debug.Print(sLine)
Next
File.WriteAllLines(sFile)
The above would remove all blank lines
In place of that loop, you could also use lamda expression like this:
Fdata.RemoveAll(Function(MyOneRow) MyOneRow = "")
I used the StrignSplitOptions.RemoveEmptyEntries to get rid of blank lines.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim FileContents = File.ReadAllText("SomeFile.txt")
Dim lines = FileContents.Split(Environment.NewLine.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
End Sub
As you can see in the above image, there is what we can call an "enter" at the end of the sentence and another one between.
So let's just remove the one between the sentences and because it's just a line you can do it like this:
If line(i) = CHR(13) & CHR(10) then line(i)=""
but if you want to get a little paranoid and just want to remove all the "enters" or "line breaks" just do it like this:
line(i)=Replace(line(i),CHR(13) & CHR(10),"")

What is the simplest way to get the second item of each row in a string file

I have a String file with 8 items (separated by commas) in each row, e.g., CA,23456,aName,aType,anotherName,aWord,secondword,number. I want to create a new string of items consisting of the 2nd item (an Integer) of each row of the original file. I know there are many ways to do this but someone out there knows how to do it with very few lines of code, which is what I am looking for. I prefer not to use a parser.
The way to show what I have tried is to look at the code below.
Dim sn2 As String = ""
Dim sn2S As String = ""
Using readFile As New StreamReader(newFile1)
Do While readFile.Peek() <> -1
sn2S = readFile.ReadLine(1)
sn2 = sn2 & sn2S & ","
Loop
End Using
The code returns the second character of each row not the second item. What I hope to get is a string that looks like: 123,1345,4325,3321,3456,3211 etc. Where each number is the second item in each row of the original file.
You could split it up by cells
Dim row As String = "CA,23456,aName,aType,anotherName,aWord,secondword,number"
Dim cells() As String = row.Split(",")
Dim cellValue As String = cells(1)
But in your case, I would just do a search and Substring by the index of the delimiter.
Dim startPosition As Integer = row.IndexOf(",") + 1
Dim endPosition As Integer = row.IndexOf(",", startPosition)
Dim cellValue As String = row.Substring(startPosition, endPosition - startPosition)
If you have the whole file in memory, there could be some regex that could do the job with one pass.
As for this line
sn2 = sn2 & sn2S & ","
You might want to check at doing a join or using stringbuilder.
You could try
Dim sn2 As String = ""
Dim sn2S(7) As String = ""
Using readFile As New StreamReader(newFile1)
Do While readFile.Peek() <> -1
Array.Clear(sn25,0,sn25.Length)
sn2S = readFile.ReadLine(1).Split(",")
sn2 = sn2 & sn2S(1) & ","
Loop
End Using
In one line
Dim sn2 = String.Join(",", File.ReadAllLines(newFile1).Select(Function(s) s.Split(","c)(1)))
From the inside-out:
File.ReadAllLines(newFile1) splits the file into lines and results in a string array holding those lines, which is fed into...
...Select(Function(s) s.Split(","c)(1)) which operates on each line by splitting the line by comma s.Split(","c) and then indexing the resulting array (1) to return the second (zero-based) element. This is fed into...
String.Join(",", ... ) which takes those second elements and joins then together with comma.

visual basic search text for string, display results with propercase

...databox.text (from example code below) contains a large list of combined words(domain names) previously populated in the program. There is 1 per each line. In this example, it initially looks like:
thepeople.com
truehistory.com
workhorse.com
whatever.com
neverchange.com
...
The following code below saves the text inside databox to tlistfiltered.txt and then searches tlistfiltered.txt to retrieve all lines that contain any of the items in the list "arr()", and then populates listview(lv) with the results. This works just fine, but the results look like:
thepeople.com
truehistory.com
neverchange.com
...
but what I need is the "found string" (from arr()list to be Proper case so the result would be:
thePeople.com
trueHistory.com
neverChange.com
Here is the code....
Dim s As String = databox.Text
File.WriteAllText(dloc & "tlistfiltered.txt", s)
databox.Clear()
Dim text2() As String = System.IO.File.ReadAllLines(dloc & "tlistfiltered.txt")
Dim arr() As String = {"people", "history", "change"}
For index1 = 0 To arr.GetUpperBound(0)
Dim YesLines() As String = Array.FindAll(text2, Function(str As String)
Return str.Contains(arr(index1))
End Function).ToArray
databox.Visible = True
For index2 = 0 To YesLines.GetUpperBound(0)
Dim match As String = (YesLines(index2)) & vbCrLf
databox.AppendText(match)
Next
Next
s = databox.Text
File.WriteAllText(dloc & "tlistfilteredfinal.txt", s)
databox.Clear()
domains = (From line In File.ReadAllLines(dloc & "tlistfilteredfinal.txt") Select New ListViewItem(line.Split)).ToArray
lv.Items.Clear()
My.Computer.FileSystem.DeleteFile(dloc & "tlistfiltered.txt")
My.Computer.FileSystem.DeleteFile(dloc & "tlistfilteredfinal.txt")
BackgroundWorker1.RunWorkerAsync()
End Sub
Is there a way to do this on the fly? I have tried StrConv etc, but it will only convert the entire line to proper case. I only want the "found" word contained within the line to be converted....
edit:
after seeing #soohoonigan 's answer, i edited
databox.Visible = True
For index2 = 0 To YesLines.GetUpperBound(0)
Dim match As String = (YesLines(index2)) & vbCrLf
databox.AppendText(match)
Next
Next
to this:
databox.Visible = True
For index2 = 0 To YesLines.GetUpperBound(0)
Dim match As String = (YesLines(index2)) & vbCrLf
Dim myTI As System.Globalization.TextInfo = New System.Globalization.CultureInfo("en-US", False).TextInfo
If match.Contains(arr(index1)) Then
match = match.Replace(arr(index1), myTI.ToTitleCase(arr(index1)))
'StrConv(match, vbProperCase)
databox.AppendText(match)
End If
Next
and got the desired result!
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim test As String = "thepeople.com"
Dim search As String = "people"
Dim myTI As System.Globalization.TextInfo = New System.Globalization.CultureInfo("en-US", False).TextInfo
If test.Contains(search) Then
test = test.Replace(search, myTI.ToTitleCase(search))
MsgBox(test)
End If
Me.Close()
End Sub
End Class
I'm not sure to understand the need for using files for intermediate steps and deleting them at the end for example.
First step: getting the lines of the input
That can be done by using the Lines property of databox (which I suspect to be a TextBox or RichTextBox ; if it's not the case we can still use a Split on the Text property)
Dim lines = databox.Lines ' or databox.Text.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Second step: we want to filter those lines to keep only the ones containing the searched texts
For this there are several way, a simple one would be to use a Linq query to get the job done
Third step: transforming the result of the filter replacing the searched text by it's capitalized form
So we continue the started query and add a projection (or mapping) to do the transformation.
We need to use TextInfo.ToTitleCase for that.
' See soohoonigan answer if you need a different culture than the current one
Dim textInfo = System.Globalization.CultureInfo.CurrentCulture.TextInfo
Dim query = From word in arr
From line in lines
Where line.Contains(word)
Let transformed = line.Replace(word, textInfo.ToTitleCase(word))
select transformed
' We could omit the Let and do the Replace directly in the Select Clause

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

How do I manipulate the last string of a Richtextbox in Visual Basic

I am trying to take a string in a rich text box and replace them with a different string.
Now how this should work is that if two same characters are entered into the text box
e.g tt the "tt" will be replaced with "Ǿt" , it adds back one of the t's to the replaced string. Only the most recently entered string is manipulated if two same characters are entered .
I read the LAST string that is in the RichTextBox by using this method
Dim laststring As String = RichTextBox1.Text.Split(" ").Last
'hitting space bar breaks the operation so if i enter t t there will be no replacement
this is the replacement method which I use , it works correctly .
if laststring = "tt"
RichTextBox1 .Text = RichTextBox1 .Text.Replace("tt", "Ǿt")
This method is inefficient because i need to check id there are double letters for all letters and if i was to use this method it would tavke up a lot of code .
how can I accomplish this using a shorter method??
You need to put the if then section in a loop.
Dim holdstring As String
Dim doubleinstance() As String = {"bb", "tt", "uu"} ' array
Dim curstring As String = RichTextBox1.Text.Split(" ").Last
For Each item As String In doubleinstance
If RichTextBox1.Text.EndsWith(item) Then
holdstring = RichTextBox1.Text.Split(" ").Last.Length - 1 ' change to subtract 1 character from doubleinstance
RichTextBox1.Text = RichTextBox1.Text.Replace(curstring, "Ǿt" & holdstring)
MsgBox(curstring)
End If
Next item
Here's a bit of code to get you in the right direction...
There are a couple of variations of .Find, but you probably want to look at the .Select method.
With RichTextBox1
.Find("Don")
.SelectedText = "Mr. Awesome"
End With
Here is a way I came up with
Dim holdstring As String
Dim doubleinstance() As String = {"bb", "tt", "uu"} ' array
Dim curstring As String = RichTextBox1.Text.Split(" ").Last
If curstring = doubleinstance(0) And RichTextBox1.Text.EndsWith(doubleinstance(0)) Then
holdstring = RichTextBox1.Text.Split(" ").Last.Length - 1 ' change to subtract 1 character from doubleinstance
RichTextBox1.Text = RichTextBox1.Text.Replace(curstring, "Ǿt" + holdstring)
MsgBox(curstring)
End If
where i have doubleinstance(0) how do i get the if statement to not only check a single index but all of the index from 0 to 2 in this example ?