VB.Net Regex Help - vb.net

I've got 3 or 4 patterns that I'm comparing user input against and I need to figure out if the user input matches one of the patters and to return the match if it does.
Since the input is multiline, I'm passing each individual line like so:
Dim strRawInput() As String = Split(txtInput.Text, vbCrLf)
Dim strInput As String
txtOutput.Text = ""
For Each strInput In strRawInput
strInput.Trim(vbCr, vbLf, Chr(32))
Validation(strInput)
Next
Then I have this to find matches:
Dim m As Match
For i = 0 To strValidator.Length - 1
Dim r As New Regex(strValidator(i))
m = r.Match(strInput)
If m.Success Then
txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
Exit Sub
Else
End If
Next
txtOutput.Text = txtOutput.Text & "Not this time" & vbCrLf
How can I do this more efficiently? Also, I added the Exit Sub there to avoid showing the "Not this time" message even after a match is found (if the match is with one of the later patterns in the array), but I'd like to find a better way of doing that too.
Thanks in advance.

Rather than generating your Regexs in the loop, generate them one time at the startup of the application. So maybe something like:
Private Shared m_regexes As New List(Of Regex)
Shared Sub New()
For Each v As String In strValidator
m_regexes.Add(New Regex(v))
Next
End Sub
And then you can change your other code to:
For Each r As Regex In m_regexes
Dim m As Match = r.Match(strInput)
If m.Success Then
txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
Exit Sub
Else
End If
Next
Regarding the Exit Sub, I think it's fine, You've discovered that it matches at least one pattern, so why continue to evaluate the rest. But if you don't like methods that can "return" in multiple places, you could just replace it with a Boolean and a Exit For as:
Dim found as Boolean = false
For Each ...
If IsMatch Then
found = True
Exit For
End If
Next
If Found Then
....
Else
.....
End If

Hmm if that's the case then wouldn't this be even better?
For i = 0 To strValidator.Length - 1
Dim r As New Regex(strValidator(i))
Dim m As Match = r.Match(strInput)
If m.Success Then
txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
Exit Sub
End If
Next

Related

How to use this VBA code to use as Public Subroutine in Access VBA

I have got this code below that restricts users to leave an empty field in a form. Now I want to use this in all of my forms. I've tried to use in Public Subroutine using a module. But it doesn't work.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim msg As String, Style As Integer, Title As String
Dim nl As String, ctl As Control
nl = vbNewLine & vbNewLine
For Each ctl In Me.Controls
If ctl.ControlType = acTextBox Then
If ctl.Tag = "*" And Trim(ctl & "") = "" Then
msg = "Data Required for '" & ctl.Name & "' field!" & nl & _
"You can't save this record until this data is provided!" & nl & _
"Enter the data and try again . . . "
Style = vbCritical + vbOKOnly
Title = "Required Data..."
MsgBox msg, Style, Title
ctl.SetFocus
Cancel = True
Exit For
End If
End If
Next
End Sub
I just want to use this in all of my forms. How do I accomplish this?
Good question, and good idea.
So, keep in mind that "me" is just the current form you are working with.
So, create a plane jane standard code module. And drop in your function like this with a "few" changes.
Public Function CheckRequired(MyMe As Form) As Boolean
Dim msg As String
Dim Style As Integer
Dim Title As String
Dim nl As String
Dim ctl As Control
nl = vbCrLf ' crlf gives you one line
CheckRequired = False ' assume everything ok
For Each ctl In MyMe.Controls
If ctl.ControlType = acTextBox Then
If ctl.Tag = "*" And Trim(ctl & "") = "" Then
msg = "Data Required for '" & ctl.Name & "' field!" & nl & _
"You can't save this record until this data is provided!" & nl & _
"Enter the data and try again . . . "
Style = vbCritical + vbOKOnly
Title = "Required Data..."
MsgBox msg, Style, Title
ctl.SetFocus
CheckRequired = True
Exit Function
End If
End If
Next
End Function
Now, in the forms event (which has that cancel), then you do this:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = CheckRequired(Me)
End Sub
As #June7 mentioned, Me is only valid behind forms and reports. It is shorthand alias for the form/report name/object. To achieve what you are looking for, you can try this concept. Create the global routine like below :
Public Function Validate_BeforeUpdate(frm As Form) As Integer
Dim msg As String, Style As Integer, Title As String
Dim nl As String, ctl As Control
nl = vbNewLine & vbNewLine
For Each ctl In frm.Controls
'''' your other code
Validate_BeforeUpdate = 1
Exit For
Next
End Sub
And to use this from your other forms, do it like below :
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Validate_BeforeUpdate(Me) = 1 Then
Cancel = True
End If
End Sub
This is not a tested code, if you follow this idea, you should be okay to have what you are trying to do.

Read message from text file and display in message box in vb.net

JavaError.128 = "project creation failed. & vbLf & Please try again and if the problem persists then contact the administrator"
I am able to read this message from text file. the issue is vbLf is not considered as newline in msgbox. it prints vbLf in msgbox.
Using sr As System.IO.StreamReader = My.Computer.FileSystem.OpenTextFileReader(errorfilePath)
While ((sr.Peek() <> -1))
line = sr.ReadLine
If line.Trim().StartsWith("JavaError." & output) Then
isValueFound = True
Exit While
End If
End While
sr.Close()
End Using
If isValueFound Then
Dim strArray As String() = line.Split("="c)
MsgBox(strArray(1).Replace("""", "").Trim({" "c}))
End If
You can make all your code a simpler one line version using File.ReadAllLines and LINQ. This code will put all the lines starting with javaerror into the textbox, not just the first:
textBox.Lines = File.ReadAllLines(errorFilePath) _
.Where(Function(s) s.Trim().StartsWith("JavaError")) _
.Select(Function(t) t.Substring(t.IndexOf("= ") + 2).Replace(" & vbLf & ", Environment.NewLine)) _
.ToArray()
You need to Imports System.IO and System.Linq
This code reads all the lines of the file into an array, then uses LINQ to pull out only those starting with java error, then projects a new string of everything after the = with vbLf replaced with a newline, converts the enumerable projection to an array of strings and assigns it to the textBox lines
If you don't want all the lines but instead only the first:
textBox.Text = File.ReadLines(errorFilePath) _
.FirstOrDefault(Function(s) s.Trim().StartsWith("JavaError")) _
?.Substring(t.IndexOf("= ") + 2).Replace(" & vbLf & ", Environment.NewLine))
This one uses ReadLine instead of ReadALlLines - ReadLines works progressively, and it makes sense to be able to stop reading after we foundt he first rather than have the overhead of reading ALL (million) lines only to then end up pulling the first out and throwing 999,999 lines of effort away. So it's reading line by line, pulls out the first that starts with "JavaError" (or Nothing if there is no such line), then checks if Nothing came out (the ?) and skips the Substring if it was Nothing, or it does a Substring on everything after the = and replaces vbLf with newline
For a straight up mod of your original code:
Using sr As System.IO.StreamReader = My.Computer.FileSystem.OpenTextFileReader(errorfilePath)
While ((sr.Peek() <> -1))
line = sr.ReadLine
If line.Trim().StartsWith("JavaError." & output) Then
isValueFound = True
line = line.Replace(" & vbLf & ", Environment.NewLine))
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ added code
Exit While
End If
End While
sr.Close()
End Using
If isValueFound Then
Dim strArray As String() = line.Split("="c)
MsgBox(strArray(1).Replace("""", "").Trim({" "c}))
End If
Note that I've always made my replacement on & vbLf & with a space at each end to avoid stray spaces being left behind - if your file sometimes doesn't have them, consider using Regex to do the replace, e.g. Regex.Replace(line, " ?& vbLf & ?", Environment.NewLine
This could work:
Dim txtFile As String = "project creation failed. & vbLf & Please try again and if the problem persists then contact the administrator"
Dim arraytext() As String = txtFile.Split("&")
Dim txtMsgBox As String = Nothing
For Each row As String In arraytext
If Trim(row) = "vbLf" Then
txtMsgBox = txtMsgBox & vbLf
Else
txtMsgBox = txtMsgBox & Trim(row)
End If
Next
MsgBox(txtMsgBox)

Search in datagrid using value in textbox

How can I display value in msgbox. In the first column in datagrid is looking value based on textbox and I want display value from second column and the same row in msgbox. Now I have only "Item found"
Here are columns
Private Sub PictureBox12_Click(sender As Object, e As EventArgs) Handles PictureBox12.Click
Dim temp As Integer = 0
For i As Integer = 0 To List2DataGridView.RowCount - 1
For j As Integer = 0 To List2DataGridView.ColumnCount - 1
If List2DataGridView.Rows(i).Cells(j).Value.ToString = TextBox2.Text Then
MsgBox("Intem found")
temp = 1
End If
Next
Next
If temp = 0 Then
MsgBox("Item not found")
End If
End Sub
You can enumerate List2DataGridView.Rows directly via For Each, there is no need to use indexing to visit them.
For Each row As DataGridViewRow In List2DataGridView.Rows
Then, for each row we test its value and when we find the matching row, we display a message incorporating its value. We have access to the value because it is in scope. When we find the matching element we exit the For Each
For Each row As DataGridViewRow In List2DataGridView.Rows
If row.Cells.Item(1).Value = TextBox2.Text Then
MsgBox("Item is found in row: " & row.Index)
MsgBox("Value of second column in this row: " & row.Cells.Item(1).Value)
Exit For
End If
Next
MsgBox("Item not found")
However this is not the most elegant solution and suffers from poor readability. Specifically, use of Exit For is somewhat ugly and makes the code harder to grok at a clance.
We can do better by using LINQ.
Dim Matches = From row As DataGridViewRow In List2DataGridView.rows
Let CellValue = row.Cells.Item(1).Value
Where CellValue = TextBox2.Text
Select New With {CellValue, row.Index}
Dim Match = Matches.FirstOrDefault()
If Match IsNot Nothing Then
MsgBox("Item is found in row: " & Match.Index)
MsgBox("Value of second column in this row: " & Match.CellValue)
End If
Private Sub PictureBox12_Click(sender As Object, e As EventArgs) Handles PictureBox12.Click
Dim barcode As String
Dim rowindex As String
Dim found As Boolean = False
barcode = InputBox("Naskenujte čárový kód ||||||||||||||||||||||||||||||||||||")
If Len(Trim(barcode)) = 0 Then Exit Sub 'Pressed cancel
For Each row As DataGridViewRow In List2DataGridView.Rows
If row.Cells.Item("DataGridViewTextBoxColumn1").Value = barcode Then
rowindex = row.Index.ToString()
found = True
Dim actie As String = row.Cells("DataGridViewTextBoxColumn2").Value.ToString()
MsgBox("Čárový kód: " & barcode & vbNewLine & "Číslo dílu je: " & actie, , "Vyhledání dílu")
Exit For
End If
Next
If Not found Then
MsgBox("Item not found")
End If
End Sub

Custom search from textbox switch/parameter

I think I am over engineering this a bit. Any assistance is greatly appreciated on how I can fix this little problem. I have an app that searches multiple sites. But if a user types a custom parameter of g=, then it will search google. The problem is I have right now is it strips the G from the first word of my search term. For example, If I type g=golf game, google pops up with olf game. With the other searches, the = character is getting stripped. Should I use contains instead of this custom firstChars function?
Here is my code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text = "" Then
MsgBox("Enter text to search on." & vbCrLf & Err.Description, MsgBoxStyle.Information, "Need search term to search on.")
TextBox1.Focus()
End If
Try
'CHECK FOR GOOGLE.COM SEARCHING
Dim MyString As String = TextBox1.Text
Dim MyChar() As Char = {"g", "G", "="}
Dim NewString As String = MyString.TrimStart(MyChar)
Dim myUri As New Uri("http://google.com/search?hl=en&q=" & NewString)
Dim first2Chars As String
Dim first3Chars As String
Dim first4Chars As String
first2Chars = TextBox1.Text.Substring(0, 2)
first3Chars = TextBox1.Text.Substring(0, 3)
first4Chars = TextBox1.Text.Substring(0, 4)
MsgBox(first2Chars)
If first2Chars = "G=" Or first2Chars = "g=" Then
System.Diagnostics.Process.Start(myUri.AbsoluteUri)
ElseIf first3Chars = "TS=" Or first3Chars = "ts=" Then
System.Diagnostics.Process.Start("https://localhost/search.do?query=" & Net.WebUtility.UrlEncode(TextBox1.Text))
ElseIf first4Chars = "PIC=" Or first4Chars = "pic=" Then
System.Diagnostics.Process.Start("https://localhost/search.do?query_pic=" & Net.WebUtility.UrlEncode(TextBox1.Text))
End If
Catch ex As Exception
MsgBox("Error running search. The error was: " & vbCrLf & Err.Description, MsgBoxStyle.Exclamation, "Error")
End Try
End Sub

extracting text from comma separated values in visual basic

I have such kind of data in a text file:
12343,M,Helen Beyer,92149999,21,F,10,F,F,T,T,T,F,F
54326,F,Donna Noble,92148888,19,M,99,T,F,T,F,T,F,T
99999,M,Ed Harrison,92147777,28,F,5,F,F,F,F,F,F,T
88886,F,Amy Pond,92146666,31,M,2,T,F,T,T,T,T,T
37378,F,Martha Jones,92144444,30,M,5,T,F,F,F,T,T,T
22444,M,Tom Scully,92145555,42,F,6,T,T,T,T,T,T,T
81184,F,Sarah Jane Smith,92143333,22,F,5,F,F,F,T,T,T,F
97539,M,Angus Harley,92142222,22,M,9,F,T,F,T,T,T,T
24686,F,Rose Tyler,92142222,22,M,5,F,F,F,T,T,T,F
11113,F,Jo Grant,92142222,22,M,5,F,F,F,T,T,T,F
I want to extract the Initial of the first name and complete surname. So the output should look like:
H. Beyer, M
D. Noble, F
E. Harrison, M
The problem is that I should not use String Split function. Instead I have to do it using any other way of string handling.
This is my code:
Public Sub btn_IniSurGen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_IniSurGen.Click
Dim vFileName As String = "C:\temp\members.txt"
Dim vText As String = String.Empty
If Not File.Exists(vFileName) Then
lbl_Output.Text = "The file " & vFileName & " does not exist"
Else
Dim rvSR As New IO.StreamReader(vFileName)
Do While rvSR.Peek <> -1
vText = rvSR.ReadLine() & vbNewLine
lbl_Output.Text += vText.Substring(8, 1)
Loop
rvSR.Close()
End If
End Sub
You can use the TextFieldParserClass. It will parse the file and return the results directly to you as a string array.
Using MyReader As New Microsoft.VisualBasic.FileIO.
TextFieldParser("c:\logs\bigfile")
MyReader.TextFieldType =
Microsoft.VisualBasic.FileIO.FieldType.Delimited
MyReader.Delimiters = New String() {","}
Dim currentRow As String()
'Loop through all of the fields in the file.
'If any lines are corrupt, report an error and continue parsing.
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
' Include code here to handle the row.
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
" is invalid. Skipping")
End Try
End While
End Using
For your wanted result, you may changed
lbl_Output.Text += vText.Substring(8, 1)
to
'declare this first
Dim sInit as String
Dim sName as String
sInit = vText.Substring(6, 1)
sName = ""
For x as Integer = 8 to vText.Length - 1
if vText.Substring(x) = "," Then Exit For
sName &= vText.Substring(x)
Next
lbl_Output.Text += sName & ", " & sInit
But better you have more than one lbl_Output ...
Something like this should work:
Dim lines As New List(Of String)
For Each s As String In File.ReadAllLines("textfile3.txt")
Dim temp As String = ""
s = s.Substring(s.IndexOf(","c) + 1)
temp = ", " + s.First
s = s.Substring(s.IndexOf(","c) + 1)
temp = s.First + ". " + s.Substring(s.IndexOf(" "c), s.IndexOf(","c) - s.IndexOf(" "c)) + temp
lines.Add(temp)
Next
The list Lines will contain the strings you need.