I am trying to read all of the integers in a list box line.
Dim scores As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(line, "\d+")
I have saved the scores in a format like this
Name 00 00 00
Could I have the regular expression for reading 3 integers with a space in between each number? The file the integers are stored in is a notepad file.
Approach without regex:
Const SEPARATOR As String = " "c
Dim line As String 'Here reading line from the file
Dim numbers As New List(Of Int32)()
Dim values As String() = line.Split(SEPARATOR) 'Split values to array
For Each value As String in values
Dim tempnumber As Int32
If Int32.TryParse(value, tempnumber) = True Then
'Accept only numbers
numbers.Add(tempnumber)
End If
Next
Use Matches instead of Match and store the results of the Regex into a MatchCollection
Sub Main()
Dim scores As String = "00 13 00"
Dim score As System.Text.RegularExpressions.MatchCollection = System.Text.RegularExpressions.Regex.Matches(scores, "\d+")
For i As Integer = 0 To score.Count - 1
Console.WriteLine(score.Item(i))
Next
Console.ReadLine()
End Sub
Results:
Related
I'm looking to read lines from a text file that start with certain characters and stop when the line starts with other characters. So in my example I would like to start reading at line AB and stop at line EF however not all lines will contain the CD line. There will always be a AB line and EF line, however the number of lines in between is unknown.
Here is an example of the lines in a text file I would be reading. You can see that this will create two rows in the DataGridView however the first row is missing the CD line and should be blank.
AB-id1
EF-address1
AB-id2
CD-name1
EF-address2
Here is the code I have so far:
Dim lines() As String = File.ReadAllLines(textfile)
For i As Integer = 0 To lines.Length - 1
If lines(i).StartsWith("AB") Then
Dim nextLines As String() = lines.Skip(i + 1).ToArray
Dim info As String = nextLines.FirstOrDefault(Function(Line) Line.StartsWith("CD"))
Dim name As String = "Yes"
Dim info2 As String = nextLines.FirstOrDefault(Function(Line) Line.StartsWith("EF"))
Dim address As String = "Yes"
End If
DataGridView.Rows.Add(name,address)
Next
Now the output I currently get is:
|Yes|Yes|
|Yes|Yes|
And I should be getting:
||Yes|
|Yes|Yes|
It looks like it's reading too far down the text file and I need it to stop reading at EF. I've tried Do while and Do Until with no success. Any suggestions?
You could use the Array.FindIndex function to get the index of the next line starting with your prefix. This way you don't have to skip lines and create a new array each time.
Try this out instead:
Dim lines() As String = File.ReadAllLines(textFile)
For i As Integer = 0 To lines.Length - 1
If lines(i).StartsWith("AB") Then
Dim addressIndex As Integer = Array.FindIndex(lines, i + 1, Function(Line) Line.StartsWith("EF"))
Dim address As String = If(addressIndex <> -1, lines(addressIndex).Substring(3), "") ' Get everything past the "-"
Dim name As String = ""
If addressIndex <> -1 Then
Dim nameIndex As Integer = Array.FindIndex(lines, i + 1, addressIndex - i, Function(line) line.StartsWith("CD"))
If nameIndex <> -1 Then
name = lines(nameIndex).Substring(3) ' Get everything past the "-"
End If
End If
DataGridView.Rows.Add(name, address)
End If
Next
I need to separate following strings into Name and Number: e.g.
evil333 into evil and 333
bili454 into bili and 454
elvis04 into elvis and 04
Split(String, "#") ' don't work here because numbers are unknown
similarly
Mid(String, 1, String - #) ' don't work because Numbers length is unknown
so what should be the best way to start? Just want to keep it simple as possible
Update:
For further info follow - https://youtu.be/zjF7oLLgtms
Two more ways for solving this:
Sub test()
Dim sInputString As String
Dim i As Integer
Dim lFirstNumberPos As Long
sInputString = "evil333"
'loop through text in input string
'if value IsNumeric (digit), stop looping
For i = 1 To Len(sInputString)
If IsNumeric(Mid(sInputString, i, 1)) Then
lFirstNumberPos = i
Exit For
End If
Next i
Dim Name As String
Dim Number As String
'return result
Name = Left$(sInputString, lFirstNumberPos - 1)
Number = Mid$(sInputString, lFirstNumberPos)
End Sub
Or another method:
Sub test2()
'if you are going to have too long string it would maybe better to use "instr" method
Dim sInputString As String
Dim lFirstNumberPos As Long
Dim i As Integer
sInputString = "evil333"
Dim lLoopedNumber as Long
LoopedNumber = 0
lFirstNumberPos = Len(sInputString) + 1
'loop through digits 0-9 and stop when any of the digits will be found
For i = 0 To 9
LoopedNumber = InStr(1, sInputString, cstr(i), vbTextCompare)
If LoopedNumber > 0 Then
lFirstNumberPos = Application.Min(LoopedNumber,lFirstNumberPos)
End If
Next i
Dim Name As String
Dim Number As String
'return result
Name = Left$(sInputString, lFirstNumberPos - 1)
Number = Mid$(sInputString, lFirstNumberPos)
End Sub
You should regular expressions (regex) to match the two parts of your strings. The following regex describes how to match the two parts:
/([a-z]+)([0-9]+)/
Their use in VBA is thorougly explained in Portland Runner's answer to How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops
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.
The problem now is how would I be able to format the values being displayed in datagridview from textfiles.
I have retrieved values from looping through textfiles removed the first two strings. Now I want to add separators or change the format of the displayed value like, for example:
textfile lines: result:
01Sample - line1
022 - line2
0306212019 - line3 06/21/2019
041234567890 - line4 12,345,678.90
I have already tried this one changing the defaultcellstyle but since the values are from textfiles in a directory its not affecting the output
DataGridView1.Columns("Gross Sales").DefaultCellStyle.Format = "##,0"
Private Sub ReadTextFiles()
Dim dt As New DataTable
dt.Columns.Add("Date")
dt.Columns.Add("Gross Sales")
Dim Folder As New IO.DirectoryInfo("c:\test\")
Dim lstLines As New List(Of String)
For Each fileentries As String In Folder.GetFiles("s*", IO.SearchOption.AllDirectories).OrderByDescending(Function(x) x.Name).Select(Function(x) x.FullName)
lstLines.AddRange(File.ReadAllLines(fileentries))
Next
Dim i As Integer
Dim OuterLoopIterations As Integer = CInt(lstLines.Count / 22)
For iterations = 0 To OuterLoopIterations - 1
Dim row = dt.NewRow
For col = 0 To 21
row(col) = lstLines(i).Remove(0, 2) 'i have removed the first 2 characters of each string
i += 1
Next
dt.Rows.Add(row(2), row(5), row(12), row(13), row(14), row(15), row(7), row(8), row(11))
Next
DataGridView1.DataSource = dt
'the code i tried applying
DataGridView1.Columns("Gross Sales").DefaultCellStyle.Format = "##,0"
this is my expected result
Current datagrid view:
the result should be for date column: 06/07/2019
for the gross : 48,990.14
Edit:
I tried this one
Dim B As Double
Dim Folder As New IO.DirectoryInfo("c:\test\")
Dim lstLines As New List(Of String)
For Each fileentries As String In Folder.GetFiles("s*", IO.SearchOption.AllDirectories).OrderByDescending(Function(x) x.Name).Select(Function(x) x.FullName)
B = CDbl(Val(fileentries))
lstLines.AddRange(File.ReadAllLines(B))
Next
If you want to format something as a number then it has to be a number. That means that, for example, if you read the text "1234.5" from the file and you want to display it as 1,234.50 in your grid then you have to convert the String you read to a Double or Decimal. If you do that then the numeric format specifier you're using in the grid column will work.
If I have the following string:
100456,3456,1235,0,0,100,500
I need to be able to extract specific values such as 100456, 1235 and 100. I am having trouble writing code to extract text in front of a comma in a certain position.
Basically extract text in front of the 1st comma, extract text in front of the 3rd comma, etc.
Dim fields() As String = Split(TextLine, ",")
For i = 0 To UBound(fields)
If i = 0 Then
Value1 = fields(i)
End If
If i = 3 Then
Value2 = fields(i)
End If
Next
I've tried this, but the loop seems to run more times than it should.
Dim fields() As String = Split(TextLine, ",")
Dim Value1 as String = fields(0)
Dim Value2 as String = fields(2) 'the field in front of 3rd comma is index 2