String range in VB.NET with multiple occurrences - vb.net

I'm trying to accomplish something fairly simple in VB that I do everyday in JavaScript.
I need to parse text between two strings (HTML tags mainly) that have multiple occurrences.
Sample Data:
<tag>test</tag>
<tag>test2</tag>
<tag>test3</tag>
If I wanted to grab the data in the 2nd <tag> in JavaScript I would simply do this:
var result = string.split('<tag>')[2].split('</tag>')[0];
And the only way I seem to get that to work in VB looks like this...
Dim from = string.IndexOf("<tag>")
Dim [to] = string.IndexOf("</tag>", from)
Dim result = string.Substring(from + "<tag>".Length, [to] - from - "<tag>".Length)
Mind you that is only the first occurrence in VB and already the code looks ridiculous in comparison... I didn't even want to figure out the 2nd occurrence until I find out this is my only solution. Thanks

You can do about the same thing in VB using the 'Split' method on the String.
Dim sx As String = "<tag>test</tag> <tag>test2</tag> <tag>test3</tag> "
Dim sp As String = sx.Split(New [String]() {"<tag>"}, StringSplitOptions.RemoveEmptyEntries)(1).Split(New [String]() {"</tag>"}, StringSplitOptions.RemoveEmptyEntries)(0)

Related

for each loop only grabbing the last value of the string array

Note: I'm not posting all code due to it's over 500 lines, I'll show a summary of what I'm trying to accomplish and the issue:
I have a string array that looks like this:
New_BMWM3889;New_LEXIS600;789858;Used_VOL9998
I need to call a routine (the same routine) that will add formatting to the value. I've tried a for each loop, but it's only grabbing the last value of the string array.
I've tried something like this:
dim cars as String = "New_BMWM3889;New_LEXIS600;789858;Used_VOL9998"
dim tmp as String() = cars.Split(";")
dim vin as String
For Each c in tmp
If p.Conatains("New") Then
vin = FormatVin("New", "#", newFormat('0000'))
Else
vin = FormatVin("No Model", "&", newFormat('####'),
End If
Next
so, I have to call the same routine and pass different parameters to the FormatVin routine, however, when I run this I'm only getting the last value of the string array. The formatVin does format validation and will change the format if needed, but that's not the issue, how can I call that same routine but pass different parameters based on if the string in the string array has a prefix or not? Then once the formatting is completed, all of the new formatted values will be passed into a String builder to be used to pass to SQL,
so,
Need to grab all values from the string array
call the routine with the correct parameters based off of the string value.
take all the new formatted strings and passed as one string into a new routine that builds a SQL statement. I know it's a mess, and I'm not sure if it can really be done cleanly if at all. So at the end I should have so I can pass this into my where clause
New_BMWM3889000;New_LEXIS600000;000000789858;Used_VOL9998000
It's hard to say exactly but I think that you should be using something along these lines:
Dim cars = "New_BMWM3889;New_LEXIS600;789858;Used_VOL9998"
Dim tmp = cars.Split(";"c)
For i = 0 To tmp.GetUpperBound(0)
Dim vin = tmp(i)
If vin.Conatains("New") Then
vin = FormatVin("New", vin, newFormat('0000'))
Else
vin = FormatVin("No Model", vin, newFormat('####'),
End If
tmp(i) = vin
Next
cars = String.Join(";", tmp)
It seems like you need to get data out of and into that array. You haven't told us what FormatVin does but I would also assume that you have to pass in the data from the array and get back out a modified version to put back into the array. I might be off on some of the detail, given your vague explanation, but I think this is the basic structure you need.

How to extract URLs from HTML source in vb.net

My question is: I have a program that fetches the whole source code of a specified URL. The source code will be saved in a variable.
Part of the source code looks like this:
"thumbnail_src":"https:\/\/scontent-fra3-1.blablabla.com\/t51.2885-15\/s640x640\/sh0.08\/e35\/1234567_984778981596410_1107218704_n.jpg","is_video":false,
The code is has quite a bunch of those URLs. I want my code to look for the part "thumbnail_src":" as a marker for beginning the extraction process and stop the extraction at ","is_video":
This should be obviously done in a loop until all URLs are being extracted and saved into a listing variable.
How can I achieve that?
I am trying to get that Regexp into my sourcecode. The one that codexer wrote, which is correct but I am getting eerrors in visual basic net.
Dim regex As Regex = New Regex("thumbnail_src""": """(.*)""","""is_video")
Dim match As Match = regex.Match(sourceString)
If match.Success Then
Console.WriteLine(match.Value)
End If
I tried it this way..and also that way:
Dim regex As Regex = New Regex("thumbnail_src":"(.*)","is_video")
Something is wrong the way I am entering the regex code.
Here is the correct one I need to implement:
https://regex101.com/r/hK0xH8/4
thumbnail_src":"(.*)","is_video
In light of your recent edit I am going to redo this answer.
Since it looks like everything is coming in on one line of text here is how I would handle it.
Dim LargetxtLine as String = TheVeryLargylineofText
Dim CommaSplit as String() = LargetxtLine.split(","c)
Dim URLList as New List(of String)
Dim RG as New Regex("\"":\""(.*)\""")
For Each str as String in CommaSplit
If str.contains("thumbnail_src") Then
URLList.Add(RG.Match(str).value)
End If
Next
This will break up the long line of text into managable chunks and then it uses regex to add it to a list of URL's (URLList)
From there you can do just about anything with a list(of String).
There is another way of doing it without splitting on the ,'s
if you use this Regex
"thumbnail_src\"":\""(.*?)\"",\""is_video"
Adding the "?" in there turns it into a greedy statement meaning that it will stop at the first occurance.
After that you could create a URLList like this
DIM RG as New Regex("thumbnail_src\"":\""(.*?)\"",\""is_video")
Dim URLList as MatchCollection = RG.Matches(reallybigString)
It's really personal preference

CSV Data handling - vb.net

I've been asked at work to create a project to open a CSV and then use a set of conditions to change and save the data using Visual Basic.net (2010)
Although I am comfortable creating files in vb and opening them again into vb, I don't know how to declare the fields so I can query them. For example:
if field1 = "Yes" and field2 = "Blue" then textbox1.text = "abcd"
Then at a later stage I want to export a file which I'm happy doing where it writes lines to create a new CSV which could be Field1, textbox1.text, Field3 and so on
Also, would I have to declare line1.field1 and line2.field1 or could I declare line2.field1 as field25 for example or whatever the next sequential number may be?
Thanks
How are you going to read from the file?
If you do File.ReadAllLines
what does it return? A string array.
Does a string array have properties like line1? No, but they do have indexers.
How do you access an element in a string array? With a indexer,
e.g. array(0).
Does an string have properties like field1? Nope.
Can you use String.Split to split on the commas and separate the fields? Yes.
Could you write a class that has specific properties defined for each field that has a constructor that'd take a string that represents a row and put the value into the correct fields? Yes.
Could the same class know how to convert itself into a single CSV style line? Yup.
Are there other library that could help you do this? Probably.
All that being said, you can probably get away with doing something simple like this (warning: naive code sample):
Dim fileName = "C:\testFile.csv"
Dim lines = File.ReadAllLines(fileName)
Dim output As New List(Of String)
For Each line In lines
Dim fields = line.Split(","c)
fields(0) = "000" 'Blank out number
If fields(3) = "Y" Then 'Change Y to True
fields(3) = "True"
End If
output.Add(String.Join(","c, fields))
Next
File.WriteAllLines(fileName, output)
I gave it input that looked like this:
123,abc,Y,Y,N
456,def,Y,N,Y
789,ghi,N,Y,Y
012,jkl,N,N,N
and it changed the file to this:
000,abc,Y,True,N
000,def,Y,N,Y
000,ghi,N,True,Y
000,jkl,N,N,N
Utilities for working with CSV will do a better job than this. There are various ways this won't work (doesn't handle any escape sequences, etc.) but this could be sufficient if you're just wanting to do something quick and dirty and don't need to worry about some things. At the very least hopefully it'll give you a better understanding of how you'd go about solving a problem like this.
I'd recommend writing the output to a different file to test.

Parse String to Array or DataTable

I'm trying to parse a long boring text document and parse and format it.
"7/29/2012 1:25:20 PM","Summary Plan/Second Floor /Master_VAV_2-24","Source :OEnd"
"7/29/2012 11:25:23 AM","Summary Plan/Second Floor /Master_VAV_2-24","Source :OStart"
I'd like to parse each value between the quotes but I cant find anything online to help me, I believe it's a matter of knowing what to call it and search for.
"date", "location", "type" would be the 3 values I want to parse it into, then I could run a loop for each item in datatable and format it as required.
ANY HELP would be great, thank you!
I'm thinking of using RegEx to get the rows and add them manually to an array, something like this.
Dim rx As New Regex(",", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
Dim matches As MatchCollection = rx.Matches(strSource)
For Each match As Match In matches
Dim matchValue As String = match.Value
If Not list.Contains(matchValue) Then
list.Add(matchValue)
End If
Next
This format appears to be CSV - use one of the many free and open source CSV parsers (google ".NET CSV parser" will return many results.
There is one that comes built in, in the Microsoft.VisualBasic.FileIO namespece - the TextFieldParser.

How can I read individual lines of a CSV file into a string array, to then be selectively displayed via combobox input?

I need your help, guys! :|
I've got myself a CSV file with the following contents:
1,The Compact,1.8GHz,1024MB,160GB,440
2,The Medium,2.4GHz,1024MB,180GB,500
3,The Workhorse,2.4GHz,2048MB,220GB,650
It's a list of computer systems, basically, that the user can purchase.
I need to read this file, line-by-line, into an array. Let's call this array csvline().
The first line of the text file would stored in csvline(0). Line two would be stored in csvline(1). And so on. (I've started with zero because that's where VB starts its arrays). A drop-down list would then enable the user to select 1, 2 or 3 (or however many lines/systems are stored in the file). Upon selecting a number - say, 1 - csvline(0) would be displayed inside a textbox (textbox1, let's say). If 2 was selected, csvline(1) would be displayed, and so on.
It's not the formatting I need help with, though; that's the easy part. I just need someone to help teach me how to read a CSV file line-by-line, putting each line into a string array - csvlines(count) - then increment count by one so that the next line is read into another slot.
So far, I've been able to paste the numbers of each system into an combobox:
Using csvfileparser As New Microsoft.VisualBasic.FileIO.TextFieldParser _
("F:\folder\programname\programname\bin\Debug\systems.csv")
Dim csvalue As String()
csvfileparser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
csvfileparser.Delimiters = New String() {","}
While Not csvfileparser.EndOfData
csvalue = csvfileparser.ReadFields()
combobox1.Items.Add(String.Format("{1}{0}", _
Environment.NewLine, _
csvalue(0)))
End While
End Using
But this only selects individual values. I need to figure out how selecting one of these numbers in the combobox can trigger textbox1 to be appended with just that line (I can handle the formatting, using the string.format stuff). If I try to do this using csvalue = csvtranslator.ReadLine , I get the following error message:
"Error 1 Value of type 'String' cannot be converted to '1-dimensional array of String'."
If I then put it as an array, ie: csvalue() = csvtranslator.ReadLine , I then get a different error message:
"Error 1 Number of indices is less than the number of dimensions of the indexed array."
What's the knack, guys? I've spent hours trying to figure this out.
Please go easy on me - and keep any responses ultra-simple for my newbie brain - I'm very new to all this programming malarkey and just starting out! :)
Structure systemstructure
Dim number As Byte
Dim name As String
Dim procspeed As String
Dim ram As String
Dim harddrive As String
Dim price As Integer
End Structure
Private Sub csvmanagement()
Dim systemspecs As New systemstructure
Using csvparser As New FileIO.TextFieldParser _
("F:\folder\programname\programname\bin\Debug\systems.csv")
Dim csvalue As String()
csvparser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
csvparser.Delimiters = New String() {","}
csvalue = csvparser.ReadFields()
systemspecs.number = csvalue(0)
systemspecs.name = csvalue(1)
systemspecs.procspeed = csvalue(2)
systemspecs.ram = csvalue(3)
systemspecs.harddrive = csvalue(4)
systemspecs.optical = csvalue(5)
systemspecs.graphics = csvalue(6)
systemspecs.audio = csvalue(7)
systemspecs.monitor = csvalue(8)
systemspecs.software = csvalue(9)
systemspecs.price = csvalue(10)
While Not csvparser.EndOfData
csvalue = csvparser.ReadFields()
systemlist.Items.Add(systemspecs)
End While
End Using
End Sub
Edit:
Thanks for your help guys, I've managed to solve the problem now.
It was merely a matter calling loops at the right point in time.
I would recommend using FileHelpers to do the reading.
The binding shouldn't be an issue after that.
Here is the Quickstart for Delimited Records:
Dim engine As New FileHelperEngine(GetType( Customer))
// To Read Use:
Dim res As Customer() = DirectCast(engine.ReadFile("FileIn.txt"), Customer())
// To Write Use:
engine.WriteFile("FileOut.txt", res)
When you get the file read, put it into a normal class and just bind to the class or use the list of items you have to do custom stuff with the combobox. Basically, get it out of the file and into a real class asap, then things will be easier.
At least take a look at the library. After using it, we use a lot more simple flat files since it is so easy, and we haven't written a file access routine since (for that kinda stuff).
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx
I think your main problem is understanding how arrays work (hence the error message).
You can use split and join functions to convert strings into and out of arrays
dim s() as string = split("1,2,3",",") gives and array of strings with 3 elements
dim ss as string = join(s,",") gives you the string back
Firstly, it's actually really good that you are using the TextFieldParser for reading CSV files - most don't but you won't have to worry about extra commas and quoted text etc...
The Readline method only gives you the raw string, hence the "Error 1 Value of type 'String' cannot be converted to '1-dimensional array of String'."
What you may find easier with combo boxes etc is to use an object (e.g. 'systemspecs') rather than strings. Assign the CSV data to the objects and override the "ToString" method of the 'systemspecs' class to display in the combo box how you want with formatting etc. That way when you handle the SelectedIndexChanged event (or similar) you get the "SelectedItem" from the combo box (which can be Nothing so check) and cast it as the 'systemspecs' to use it. The advantage is that you are not restricted to display the exact data in the combo etc.
' in "systemspecs"...
Public Overrides Function ToString() As String
Return Name ' or whatever...
End Function ' ToString
e.g.
dim item as new systemspecs
item.ID = csvalue(1)
item.Name = csvalue(2)
' etc...
combobox1.Items.Add(item)
Let me know if that makes sense!
PK :-)