How do I remove multiple empty lines in a text file - vb.net

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),"")

Related

Visual Basic - StreamWriter - How to skip to next line IF said line isn't empty

Hey so I'm trying to do a simple StreamWriter for adding staff information to a text file (I already have a working StreamReader log in page) , the text file has some sample data but also must be able to have new data written to it.
My problem is that ONLY upon initial start up and my initial writing of data the information is written on the same line as the last line of sample data in the text file, not on the next blank line.
Here is how the text file looks after the first attempt to write data after start up.
Jon,Jones
Harry,Potter
James,Gunn
Kieran,Kieranson
Me,TooGreg,
"Me,Too" being my last line of sample data and "Grey,Hardy" being my first data written via StreamWriter
I've done some research on here and found examples of how to write a blank line which you could make the StreamWriter do every time to put spacing in between etc. but that doesn't work here as this problem only occurs the first time on any given start up and if it left a blank line every single time then if I made two attempts to use the StreamWriter it would look like
Jon,Jones
Harry,Potter
James,Gunn
Kieran,Kieranson
Me,Too
Greg,Hardy
BLANK LINE
Tom,Hardy
Which would then enable a blank log in to work.
Here is my code for the StreamWriter
'StreamReader to check if a line is empty or not
Dim StaffReader As StreamReader = File.OpenText("StaffInfo.txt")
strLine = StaffReader.ReadLine()
StaffReader.Close()
'Streamwriter for adding staff log in to textfile
Dim FileCheck As StreamWriter = File.AppendText("StaffInfo.txt")
FileCheck.WriteLine(strStaffUsername2 & "," & strStaffPass2)
FileCheck.Close(``)
MessageBox.Show(strStaffUsername2 & " added to the file. ", "Data Added")
txtUser2.Clear()
txtUser2.Focus()
txtPass2.Clear()
I just want it to skip to the next blank line if the line it is going to write on has any characters on it.
what you are looking for is the point, if the last line in your file contains a carriage return or not. If it does contain a carriage return, then you can append your text with your written code. But if it does not contain a carriage return, you have to prefix your first line with a carriage return.
Thus, first you have to check if your last line has a carriage return. You can do that by a function like this:
Private Function DoesLastLineHasCarriagReturn(Filename As String) As Boolean
Dim s as String = ""
using stream = New StreamReader(Filename)
' we have to read the last two characters
stream.BaseStream.Seek(-2,SeekOrigin.End)
dim c_beforeLast as Integer = stream.Read()
Dim c_Last As Integer = stream.Read()
' if the last character is 10 -> we have a carriage return. Windows and Linux just use different encodings
if (c_Last =10)
If(c_beforeLast = 13)
Console.WriteLine("Ends with carriage return CRLF (Windows)")
Else
Console.WriteLine("Ends with carriage return LF (UNIX, OSX )")
End If
return true
Else
Console.WriteLine("Does not end with Carriage return")
End If
End Using
return false
End Function
Then when beginning to write in the file, first you have to call the function. Here how your code could look like:
If DoesLastLineHasCarriagReturn("StaffInfo.txt")
Dim FileCheck As StreamWriter = File.AppendText("StaffInfo.txt")
FileCheck.WriteLine("Greg" & "," & "Hardy")
FileCheck.Close()
Else
Dim FileCheck As StreamWriter = File.AppendText("StaffInfo.txt")
FileCheck.WriteLine(vbCrLf + "Greg" & "," & "Hardy")
FileCheck.Close()
End If
By the way, I would recommend you to use the using statement to close the stream automatically:
If DoesLastLineHasCarriagReturn("StaffInfo.txt")
Using writer As New StreamWriter("StaffInfo.txt", True)
writer.WriteLine("Greg" & "," & "Hardy")
End Using
Else
Using writer As New StreamWriter("StaffInfo.txt", True)
writer.WriteLine(vbCrLf +"Greg" & "," & "Hardy")
End Using
End If
Since we are dealing with a text file and not doing anything fancy, we can just use the File class in System.IO.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FilePath = "TestFiles/File1.txt"
'Dump contents of file
Dim fileContents As String = File.ReadAllText(FilePath)
'Extract the last 2 characters in the contents
Dim NextToLast As String = fileContents(fileContents.Length - 2)
Dim LastCharacter As String = fileContents(fileContents.Length - 1)
'Check if we have a CrLf an if not add a new line
If Not NextToLast = Chr(13) AndAlso Not LastCharacter = Chr(10) Then
File.WriteAllText(FilePath, Environment.NewLine)
End If
'Write to the file
File.AppendAllLines(FilePath, {TextBox1.Text})
End Sub
To display your text file, add a ListBox to your form.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
'Put the contents of the file into a string array of lines
Dim staff() As String = File.ReadAllLines("TestFiles/File1.txt")
ListBox1.DataSource = staff
End Sub

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

replace a line in richtextbox vb.net

I have this code but it have errors , what should i do ?
Dim lines As New List(Of String)
lines = RichTextBox1.Lines.ToList
'Dim FilterText = "#"
For i As Integer = lines.Count - 1 To 0 Step -1
'If (lines(i).Contains(FilterText)) Then
RichTextBox1.Lines(i) = RichTextBox1.Lines(i).Replace("#", "#sometext")
'End If
Next
RichTextBox1.Lines = lines.ToArray
Update: while the following "works" it does only modify the array which was returned from the Lines-property. If you change that array you don't change the text of the TextBox. So you need to re-assign the whole array to the Lines-property if you want to change the text(as shown below). So i keep the first part of my answer only because it fixes the syntax not the real issue.
It's not
RichTextBox1.Lines(i).Replace = "#sometext"
but
RichTextBox1.Lines(i) = "#sometext"
You can loop the Lines forward, the reverse loop is not needed here.
Maybe you want to replace all "#" with "#sometext" instead:
RichTextBox1.Lines(i) = RichTextBox1.Lines(i).Replace("#","#sometext")
So here the full code necessary (since it still seems to be a problem):
Dim newLines As New List(Of String)
For i As Integer = 0 To RichTextBox1.Lines.Length - 1
newLines.Add(RichTextBox1.Lines(i).Replace("#", "#sometext"))
Next
RichTextBox1.Lines = newLines.ToArray()
But maybe you could even use:
RichTextBox1.Text = RichTextBox1.Text.Replace("#","#sometext")`
because if we have # abcd this code change it to # sometextabcd ! I
Want a code to replace for example line 1 completely to # sometext
Please provide all relevant informations in the first place next time:
Dim newLines As New List(Of String)
For Each line As String In RichTextBox1.Lines
Dim newLine = If(line.Contains("#"), "#sometext", line)
newLines.Add(newLine)
Next
RichTextBox1.Lines = newLines.ToArray()

Replacing string at certain index of Split

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

Get only the line of text that contains the given word VB2010.net

I have a text file on my website and I download the whole string via webclient.downloadstring.
The text file contains this :
cookies,dishes,candy,(new line)
back,forward,refresh,(new line)
mail,media,mute,
This is just an example it's not the actual string , but it will do for help purposes.
What I want is I want to download the whole string , find the line that contains the word that was entered by the user in a textbox, get that line into a string, then I want to use the string.split with as delimiter the "," and output each word that is in the string into an richtextbox.
Now here is the code that I have used (some fields are removed for privacy reasons).
If TextBox1.TextLength > 0 Then
words = web.DownloadString("webadress here")
If words.Contains(TextBox1.Text) Then
'retrieval code here
Dim length As Integer = TextBox1.TextLength
Dim word As String
word = words.Substring(length + 1) // the plus 1 is for the ","
Dim cred() As String
cred = word.Split(",")
RichTextBox1.Text = "Your word: " + cred(0) + vbCr + "Your other word: " + cred(1)
Else
MsgBox("Sorry, but we could not find the word you have entered", MsgBoxStyle.Critical)
End If
Else
MsgBox("Please fill in an word", MsgBoxStyle.Critical)
End If
Now it works and no errors , but it only works for line 1 and not on line 2 or 3
what am I doing wrong ?
It's because the string words also contains the new line characters that you seem to be omitting in your code. You should first split words with the delimiter \n (or \r\n, depending on the platform), like this:
Dim lines() As String = words.Split("\n")
After that, you have an array of strings, each element representing a single line. Loop it through like this:
For Each line As String In lines
If line.Contains(TextBox1.Text) Then
'retrieval code here
End If
Next
Smi's answer is correct, but since you're using VB you need to split on vbNewLine. \n and \r are for use in C#. I get tripped up by that a lot.
Another way to do this is to use regular expressions. A regular expression match can both find the word you want and return the line that contains it in a single step.
Barely tested sample below. I couldn't quite figure out if your code was doing what you said it should be doing so I improvised based on your description.
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub ButtonFind_Click(sender As System.Object, e As System.EventArgs) Handles ButtonFind.Click
Dim downloadedString As String
downloadedString = "cookies,dishes,candy," _
& vbNewLine & "back,forward,refresh," _
& vbNewLine & "mail,media,mute,"
'Use the regular expression anchor characters (^$) to match a line that contains the given text.
Dim wordToFind As String = TextBox1.Text & "," 'Include the comma that comes after each word to avoid partial matches.
Dim pattern As String = "^.*" & wordToFind & ".*$"
Dim rx As Regex = New Regex(pattern, RegexOptions.Multiline + RegexOptions.IgnoreCase)
Dim M As Match = rx.Match(downloadedString)
'M will either be Match.Empty (no matching word was found),
'or it will be the matching line.
If M IsNot Match.Empty Then
Dim words() As String = M.Value.Split(","c)
RichTextBox1.Clear()
For Each word As String In words
If Not String.IsNullOrEmpty(word) Then
RichTextBox1.AppendText(word & vbNewLine)
End If
Next
Else
RichTextBox1.Text = "No match found."
End If
End Sub
End Class