startIndex cannot be larger than length of string vb.net - vb.net

I get the error "startIndex cannot be larger than length of string.
Parameter name: startIndex" when I run the following code. The error occurs on this line and I think it is to do with the line.substring. The code runs smoothly when I take out line.Substring(11, 2) = "24" and run the code as If line.StartsWith("123") Then currentRecord.ID = line.
I can't seem to get rid of the error.
Dim lines = File.ReadLines(filePath)
If (line.StartsWith("123") And line.Substring(11, 2) = "24") Then currentRecord.ID = line

You need to check the line is long enough to access the substring at that position and length. AndAlso conditions will only trigger if the previous condition = true. If your version of VB.NET doesn't support AndAlso you will need to use nested ifs.
Dim lines = File.ReadLines(filePath)
If (line.StartsWith("123") AndAlso Len(line)>=14 AndAlso line.Substring(11, 2) = "24") Then currentRecord.ID = line

Related

How can I replace a string without the replace function?

I have a long string of random letters and I need to remove a couple of the front letters a few at a time. By using the replace function, if I replace a piece of string that then repeats later on, it removes the piece of string entirely from the long string instead of just the beginning.
Is there a way to remove a piece of string without using the replace function? The code below might clear up some of the confusion.
Dim protein As String
protein = "GLSDGEWQQVLNVWGKVEADIAGHGQEVLIRLFTGHPETLEKFDKFKHLKTEAEMKASEDLKKHGTVVLTALGGILKKKEGHHEAELKPLAQSHATKHKIPIKYLEFISDAIIHVLHSKHRPGDFGADAQGAMTKALELFRNDIAAKYKELGFQG"
Dim IndexPosition
For Each index In protein
If index = "K" Or index = "R" Then
IndexPosition = InStr(protein, index)
Dim NextPosition = IndexPosition + 1
Dim NextLetter = Mid(protein, NextPosition, 0)
If NextLetter <> "P" Then
Dim PortionToCutOut = Mid(protein, 1, IndexPosition)
protein = Replace(protein, PortionToCutOut, "")
Console.WriteLine(PortionToCutOut)
End If
End If
Next index
Regex might be a simpler way to solve this:
Regex.Replace(protein, "^(.*?)[KR][^P]", "$1")
It means "from the start of the string, for zero or more captured characters up to the first occurrence of K or R followed by anything other than P, replace it with (the captured string)"
GLSDGEWQQVLNVWGKVEADIAGHGQEVLIRLFTGHPETL
^^^^^^^^^^^^^^^^^
captured string||
xx
Everything underlined with ^^^ is replaced by everything apart from the xx bit
It makes a single replacement, because that's what I interpreted you required when you said:
By using the replace function, if I replace a piece of string that then repeats later on, it removes the piece of string entirely from the long string instead of just the beginning
However if you do want to replace all occurrences of "K OR R followed by not P" it gets simpler:
Regex.Replace(protein, "[KR][^P]", "")
This is "K or R followed by anything other than P", replace with "nothing"
There are several issues with your code. The first issue that is likely to throw an exception is that you're modifying a collection in a For/Each loop.
The second issue that is less severe in immediate impact, but just as important in my opinion is that you're using almost exclusively legacy Visual Basic methods.
InStr should be replaced with IndexOf: https://learn.microsoft.com/en-us/dotnet/api/system.string.indexof
Mid should be replaced with Substring: https://learn.microsoft.com/en-us/dotnet/api/system.string.substring
The third issue is that you're not using the short-circuit operator OrElse in your conditional statement. Or will evaluate the right-hand side of your condition regardles of if the left-hand side is true whereas OrElse won't bother to evaluate the right-hand side if the left-hand side is true.
In terms of wanting to remove a piece of the String without using Replace, well you'd use Substring as well.
Consider this example:
Dim protein = "GLSDGEWQQVLNVWGKVEADIAGHGQEVLIRLFTGHPETLEKFDKFKHLKTEAEMKASEDLKKHGTVVLTALGGILKKKEGHHEAELKPLAQSHATKHKIPIKYLEFISDAIIHVLHSKHRPGDFGADAQGAMTKALELFRNDIAAKYKELGFQG"
Dim counter = 0
Do While counter < protein.Length - 2
counter += 1
Dim currentLetter = protein(counter)
Dim nextLetter = protein(counter + 1)
If (currentLetter = "K"c OrElse currentLetter = "R"c) AndAlso nextLetter <> "P"c Then
protein = protein.Substring(0, counter) & protein.Substring(counter + 1)
End If
Loop
Example: https://dotnetfiddle.net/vrhRdO

Gettint text from lastline in richtextbox

I want to copy the last line of a rich textbox.
I am avoiding Dim lastLine As String = RichTextBox1.Lines(RichTextBox1.Lines.Length - 1)as
it's not working properly, as It works just if there are atleast 2 lines in it.
I'm trying with MsgBox(RichTextBox1.Lines(UBound(richtextbox1.Lines))) but the problem is that even if the richtextbox has just 1 line of text but the cursor is in the second empty line, it will give back "" as I think the software is reading the empty 2nd line.
There is a solution to that?
Thanks
This will get the last non-empty line:
RichTextBox1.Lines.Where(Function(line) line <> String.Empty).Last()
There are some potential issues with that. If there's no text at all or if there are multiple lines but they are all empty, that will throw an exception. To allow for that, you can call LastOrDefault instead, in which case it would return Nothing.
If you only want to exclude the last empty line, e.g. if you have some text followed by a line break and then another line break then you want to get the first of those two empty lines, then you can't really do it in one line:
Dim lines = RichTextBox1.Lines
Dim upperBound = lines.GetUpperBound(0)
Dim lastLine = lines(upperBound)
If lastLine = String.Empty Then
If upperBound > 0 Then
lastLine = lines(upperBound - 1)
Else
lastLine = Nothing
End If
End If
'Use lastLine here.

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()

A loop exits prematurely when using StreamReader

It's been a long time since I've programmed. I'm writing a form in VB.NET, and using StreamReader to read a text file and populate an 2D array. Here is the text file:
あかさたなはまやらわん
いきしちにひみ り
うくすつぬふむゆる
えけせてねへめ れ
おこそとのほもよろを
And here is the loop, which is within the Load event.
Dim Line As String
Dim Row As Integer = 0
Using sReader As New IO.StreamReader("KanaTable.txt")
Do
Line = sReader.ReadLine
For i = 0 To Line.Length - 1
KanaTable(Row, i) = Line(i)
Next
Row += 1
Loop Until sReader.EndOfStream
End Using
The problem is, once the i in the For Loop reaches 10, it completes the loop and skips the other lines, even when I have a breakpoint. Can you let me know what's probably going on here?
I've figured out the problem, it was very simple. The array declaration for KanaTable:
Dim KanaTable(4, 9) As Char
should have been
Dim KanaTable(4, 10) As Char
Because there was one less space in the array than there should have been, the debugger must have been throwing an IndexOutOfRange which I couldn't see, because, stupid Windows bug (thanks to Bradley Uffner for pointing out this bug.)
If you can use an array of arrays or a list of arrays (List(Of Char())), you can get this down to a single line of code:
Dim KanaTable()() As Char = IO.File.ReadLines("KanaTable.txt").Select(Function(line) line.ToCharArray()).ToArray()
If that's too complicated for you, we can at least simplify the existing code:
Dim KanaTable As New List(Of Char())
Dim Line As String
Using sReader As New IO.StreamReader("KanaTable.txt")
Line = sReader.ReadLine()
While Line IsNot Nothing
KanaTable.Add(Line.ToCharArray())
Line = sReader.ReadLine()
End While
End Using
I can't see an error immediately, but you could try to adapt your code to this:
Using reader As New IO.StreamReader("KanaTable.txt")
Do
line= reader.ReadLine()
If line = Nothing Then
Exit Do
End If
For i = 0 To Line.Length - 1
KanaTable(Row, i) = Line(i)
Next
Row += 1
Loop
End Using

How to delete a string from a RichTextBox?

I am trying to parse junk and narrow down a bunch of text. How do I delete the current line if a does not match? I would like to remove the line entirely:
For i As Integer = 0 To RichTextBox1.Lines.Length - 1
Dim a As String = RichTextBox1.Lines(i).ToString
If Not a = "SaveThisLine" Then
'delete the active line
End If
Next
Also how would I match partially? Such as if not a = "SaveThisLine" & * (to use a wildcard).
I would not touch original text and rather save valid lines into a StringBuilder, so if line is valid, AppendLine to it. In the end dump back into RichTextBox1.Text using StringBuilder.ToString.
For partial match in VB.NET you can use a native Like operator:
"aaa" Like "a*"
Returns True.
Or use regular expressions:
System.Text.RegularExpressions.Regex.Match("aaa", "^a").Success
Also returns True.
You can do it in this way to:
For i As Integer = 0 To RichTextBox1.Lines.Length - 1
If RichTextBox1.Lines(i) = "2" Then
RichTextBox1.Text = Replace(RichTextBox1.Text, RichTextBox1.Lines(i), "", , 1)
End If
Next