Find text between two static strings - regex

I parse message data into a CSV file via Outlook rules.
How can I take the example below and store the text under "Customer Log Update:" into a string variable?
[Header Data]
Description: Problem: A2 - MI ERROR - R8036
Customer Log Update:
I'm having trouble with order #458362. I keep getting Error R8036, can you please assist?
Thanks!
View problem at http://...
[Footer Data]
Desired result to be stored into the string variable (note that the result may contain newlines):
I'm having trouble with order #458362. I keep getting Error R8036, can you please assist?
Thanks!
I haven't attempted to code anything pertaining to my question.
Function RegFind(RegInput, RegPattern)
Dim regEx As New VBScript_RegExp_55.RegExp
Dim matches, s
regEx.Pattern = RegPattern
regEx.IgnoreCase = True
regEx.Global = False
s = ""
If regEx.Test(RegInput) Then
Set matches = regEx.Execute(RegInput)
For Each Match In matches
s = Match.Value
Next
RegFind = s
Else
RegFind = ""
End If
End Function
Sub CustomMailMessageRule(Item As Outlook.MailItem)
MsgBox "Mail message arrived: " & Item.Subject
Const FileWrite = file.csv `file destination
Dim FF1 As Integer
Dim subj As String
Dim bod As String
On Error GoTo erh
subj = Item.Subject
'this gets a 15 digit number from the subject line
subj = RegFind(subj, "\d{15}")
bod = Item.Body
'following line helps formatting, lots of double newlines in my source data
bod = Replace(bod, vbCrLf & vbCrLf, vbCrLf)
'WRITE FILE
FF1 = FreeFile
Open FileWrite For Append As #FF1
Print #FF1, subj & "," & bod
Close #FF1
Exit Sub
erh:
MsgBox Err.Description, vbCritical, Err.Number
End Sub

While I would also go the more direct route like Jean-François Corbett did as the parsing is very simple, you could apply the Regexp approach as below
The pattern
Update:([\S\s]+)view
says match all characters between "Update" and "view" and return them as a submatch
This piece [\S\s] says match all non-whitespace or whitespace characters - ie everything.
In vbscript a . matches everything but a newline, hence the need for the [\S\s] workaround for this application
The submatch is then extracted by
objRegM(0).submatches(0)
Function ExtractText(strIn As String)
Dim objRegex As Object
Dim objRegM As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.ignorecase = True
.Pattern = "Update:([\S\s]+)view"
If .test(strIn) Then
Set objRegM = .Execute(strIn)
ExtractText = objRegM(0).submatches(0)
Else
ExtractText = "No match"
End If
End With
End Function
Sub JCFtest()
Dim messageBody As String
Dim result As String
messageBody = "Description: Problem: A2 - MI ERROR - R8036" & vbCrLf & _
"Customer Log Update:" & _
"I 'm having trouble with order #458362. I keep getting Error R8036, can you please assist?" & vbCrLf & _
"Thanks!" & vbCrLf & _
"View problem at http://..."
MsgBox ExtractText(messageBody)
End Sub

Why not something simple like this:
Function GetCustomerLogUpdate(messageBody As String) As String
Const sStart As String = "Customer Log Update:"
Const sEnd As String = "View problem at"
Dim iStart As Long
Dim iEnd As Long
iStart = InStr(messageBody, sStart) + Len(sStart)
iEnd = InStr(messageBody, sEnd)
GetCustomerLogUpdate = Mid(messageBody, iStart, iEnd - iStart)
End Function
I tested it using this code and it worked:
Dim messageBody As String
Dim result As String
messageBody = "Description: Problem: A2 - MI ERROR - R8036" & vbCrLf & _
"Customer Log Update:" & vbCrLf & _
"I 'm having trouble with order #458362. I keep getting Error R8036, can you please assist?" & vbCrLf & _
"Thanks!" & vbCrLf & _
"View problem at http://..."
result = GetCustomerLogUpdate(messageBody)
Debug.Print result

Related

regEx positive lookbehind in VBA language [duplicate]

This is not code I wrote completely, some I have pieced together from one or two sites and some is what I have set. What I'm trying to do is use a regex function defined in regex.Pattern to look at message subject and extract a value. This is what I'm going to see in the email subject:
New Linux Server: prod-servername-a001
So far I can get the full message subject into the Excel file, but when I have tried to implement the regex portion, I get an error code 5017 (error in expression from what I can find) and the regex is not "working". My expectation is the script will pull the message subject, use the regex to extract the value and place it in the cell. I'm using RegEx Builder (regex testing program) to test the expression and it works there, but not here. I am very new to VB, so I don't know if the issue is that VB can't use this expression or if the script is failing somewhere else and the error is something residual from another problem. Or is there a better way to write this?
Sub ExportToExcel()
On Error GoTo ErrHandler
'Declarations
Dim appExcel As Excel.Application
Dim wkb As Excel.Workbook
Dim wks As Excel.Worksheet
Dim rng As Excel.Range
Dim strSheet As String
Dim filePath As String
Dim strPath As String
Dim intRowCounter As Integer
Dim intColumnCounter As Integer
Dim msg As Outlook.MailItem
Dim nms As Outlook.NameSpace
Dim fld As Outlook.MAPIFolder
Dim itm As Object
'RegEx Declarations
Dim result As String
Dim allMatches As Object
Dim regex As Object
Set regex = CreateObject("vbscript.regexp")
regex.Pattern = "(?<=Server: ).*"
regex.Global = True
regex.IgnoreCase = True
' Set the filename and path for output, requires creating the path to work
strSheet = "outlook.xlsx"
strPath = "D:\temp\"
filePath = strPath & strSheet
'Debug
Debug.Print filePath
'Select export folder
Set nms = Application.GetNamespace("MAPI")
Set fld = nms.PickFolder
'Handle potential errors with Select Folder dialog box.
If fld Is Nothing Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.DefaultItemType <> olMailItem Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
ElseIf fld.Items.Count = 0 Then
MsgBox "There are no mail messages to export", vbOKOnly, "Error"
Exit Sub
End If
'Open and activate Excel workbook.
Set appExcel = CreateObject("Excel.Application")
appExcel.Workbooks.Open (filePath)
Set wkb = appExcel.ActiveWorkbook
Set wks = wkb.Sheets(1)
wks.Activate
appExcel.Application.Visible = True
'Copy field items in mail folder.
For Each itm In fld.Items
intColumnCounter = 1
Set msg = itm
If itm.UnRead = True Then
intRowCounter = intRowCounter + 1
wks.Cells(1, 1).value = "Subject" 'Row 1 Column 1 (A)
wks.Cells(1, 2).value = "Unread" 'Row 1 Column 2 (B)
wks.Cells(1, 3).value = "Server" 'Row 1 Column 3 (C)
Set rng = wks.Cells(intRowCounter + 1, intColumnCounter)
If InStr(msg.Subject, "Server:") Then
Set allMatches = regex.Execute(msg.Subject)
rng.value = allMatches
intColumnCounter = intColumnCounter + 1
msg.UnRead = False
Else
rng.value = msg.Subject
intColumnCounter = intColumnCounter + 1
msg.UnRead = False
End If
Set rng = wks.Cells(intRowCounter + 1, intColumnCounter)
rng.value = msg.UnRead
intColumnCounter = intColumnCounter + 1
End If
Next itm
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub
ErrHandler:
If Err.Number = 1004 Then
MsgBox filePath & " doesn't exist", vbOKOnly, "Error"
ElseIf Err.Number = 13 Then
MsgBox Err.Number & ": Type Mismatch", vbOKOnly, "Error"
ElseIf Err.Number = 438 Then
MsgBox Err.Number & ": Object doesn't support this property or method", vbOKOnly, "Error"
ElseIf Err.Number = 5017 Then
MsgBox Err.Number & ": Error in expression", vbOKOnly, "Error"
Else
MsgBox Err.Number & ": Description: ", vbOKOnly, "Error"
End If
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
End Sub
VBA regex does not support lookbehinds, but in this case, you do not need a positive lookbehind, you just can use a capturing group - "Server: (.*)"` - and then access Group 1 value:
Set regex = CreateObject("vbscript.regexp")
regex.Pattern = "Server: (.*)"
regex.IgnoreCase = True
Set allMatches = regex.Execute("New Linux Server: prod-servername-a001")
If allMatches.Count <> 0 Then
rng.Value = allMatches(0).Submatches(0)
End If
Here,
Server: - matches a string Server: + space
(.*) - matches and captures into Group 1 zero or more characters other than a newline up to the end of line.
See more about capturing groups.

VBA Find a string that has range of value in it with Regular Expression and replace with each value in that range

First of all, sorry for the long title. I just don't know how to put it succinctly. I am trying to do this in VBA as normal Excel will not cut it.
Basically, I have a column. Each cells may contain data in the format of something like
flat 10-14;Flat 18-19;unit 7-9;flat A-D;ABC;DEF;
What I need is to find the string that has "-" in it, and attempt to replace it with anything in between. so the above code will become
Flat 10, Flat 11; Flat 12, Flat 14;Flat 18, Flat 19;Unit 7, Unit 8, Unit 9;Flat A, Flat B, Flat C; ABC;DEF;
With the help of this article on RegExpression, I have managed to work out how to expand the bits of data with number, which I will post the code below. However, I don't know a good way to expand the data with the letter. i.e from Flat A-C to Flat A, Flat B, Flat C
My code is below, please feel free to give any pointers if you think it can be more efficient. I am very much an amateur at this. Thank you in advance.
Sub CallRegEx()
Dim r As Match
Dim mcolResults As MatchCollection
Dim strInput As String, strPattern As String
Dim test As String, StrOutput As String, prefix As String
Dim startno As Long, endno As Long
Dim myrange As Range
strPattern = "(Flat|Unit) [0-9]+-+[0-9]+"
With Worksheets("Sheet1")
lrow = .Cells(Rows.Count, 9).End(xlUp).Row
For Each x In .Range("A2:A" & lrow)
strInput = Range("A" & x.Row).Value
Set mcolResults = RegEx(strInput, strPattern, True, , True)
If Not mcolResults Is Nothing Then
StrOutput = strInput
For Each r In mcolResults
startno = Mid(r, (InStr(r, "-") - 2), 2)
endno = Mid(r, (InStr(r, "-") + 1))
prefix = Mid(r, 1, 4)
test = ""
For i = startno To endno - 1
test = test & prefix & " " & i & ","
Next i
test = test & prefix & " " & endno
'this is because I don't want the comma at the end of the last value
StrOutput = Replace(StrOutput, r, test)
Debug.Print r ' remove in production
Next r
End If
.Range("D" & x.Row).Value = StrOutput
Next x
End With
End Sub
This function below is to support the Sub above
Function RegEx(strInput As String, strPattern As String, _
Optional GlobalSearch As Boolean, Optional MultiLine As Boolean, _
Optional IgnoreCase As Boolean) As MatchCollection
Dim mcolResults As MatchCollection
Dim objRegEx As New RegExp
If strPattern <> vbNullString Then
With objRegEx
.Global = GlobalSearch
.MultiLine = MultiLine
.IgnoreCase = IgnoreCase
.Pattern = strPattern
End With
If objRegEx.test(strInput) Then
Set mcolResults = objRegEx.Execute(strInput)
Set RegEx = mcolResults
End If
End If
End Function
Letters have character codes that are ordinal (A < B < C ...) & these can be accessed via asc()/chr$() - here is one way to do it:
inputStr = "flat 10-14;Flat 18-19;unit 7-9;flat A-D;ABC;DEF;flat 6;flat T"
Dim re As RegExp: Set re = New RegExp
re.Pattern = "(flat|unit)\s+((\d+)-(\d+)|([A-Z])-([A-Z]))"
re.Global = True
re.IgnoreCase = True
Dim m As MatchCollection
Dim start As Variant, fin As Variant
Dim tokens() As String
Dim i As Long, j As Long
Dim isDigit As Boolean
tokens = Split(inputStr, ";")
For i = 0 To UBound(tokens) '// loop over tokens
Set m = re.Execute(tokens(i))
If (m.Count) Then
With m.Item(0)
start = .SubMatches(2) '// first match number/letter
isDigit = Not IsEmpty(start) '// is letter or number?
If (isDigit) Then '// number
fin = .SubMatches(3)
Else '// letter captured as char code
start = Asc(.SubMatches(4))
fin = Asc(.SubMatches(5))
End If
tokens(i) = ""
'// loop over items
For j = start To fin
tokens(i) = tokens(i) & .SubMatches(0) & " " & IIf(isDigit, j, Chr$(j)) & ";"
Next
End With
ElseIf i <> UBound(tokens) Then tokens(i) = tokens(i) & ";"
End If
Next
Debug.Print Join(tokens, "")
flat 10;flat 11;flat 12;flat 13;flat 14;Flat 18;Flat 19;unit 7;unit 8;unit 9;flat A;flat B;flat C;flat D;ABC;DEF;flat 6;flat T

Excel VBA - Returning Positions of all Sub-Strings within a String from the Clipboard

I'm trying to find all the positions of the unique keys (followed by two Tab keystrokes) in a string in taken from clipboard, positions with which I then hope to use to insert carriage returns, and then have everything put back into the clipboard again.
First things first; getting the position part to work!
Here is a shortened example of the string:
Initial Approval in First Market or Non-Submitted Closure 090052fb842ef82f 090052fb842f3659 090052fb842ef82e
Here is the non-functional code I have put together so far from researching the problem:
Sub oldRecords()
Dim clipboard As MSForms.DataObject
Dim strContents As String
Set clipboard = New MSForms.DataObject
clipboard.GetFromClipboard
strContents = clipboard.GetText
Set objRegEx = CreateObject("vbscript.regexp")
objRegEx.Pattern = "(090052fb)[0-9A-Za-z]{8}\t\t"
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.MultiLine = True
Start = 1
Do
pos = InStr(Start, strContents, objRegEx.Execute(strContents), vbBinaryCompare)
If pos > 0 Then
Start = pos + Len(objRegEx.Pattern)
WScript.Echo pos
WScript.Echo Mid(strContents, pos, Len(objRegEx.Pattern))
End If
Loop While pos > 0
End Sub
Right now I am getting a Run-time error '450': Wrong number of arguments or invalid property assignment, and I believe the culprit is:
objRegEx.Execute(strContents)
I'm not sure where to go from here, so any help would be fantastic! :)
Edit 1:
Firstly thank you for the interest in my issue!
BrackNicku has provided a simple solution for a problem I evidently thought more complex than it needed to be! Here is the code I finally went with, adding in a few extra bits that I needed on top of the core issue:
Sub oldRecords2()
Dim clipboard As MSForms.DataObject
Dim strContents As String
Dim start As Long, pos As Long
Set clipboard = New MSForms.DataObject
clipboard.GetFromClipboard
strContents = clipboard.GetText
Dim objRegEx
Set objRegEx = CreateObject("vbscript.regexp")
objRegEx.Pattern = "(090052fb[0-9A-Za-z]{8})\t\t"
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.MultiLine = True
X1 = 10 ' Line Feed Character
X2 = 13 ' Carriage Return Character
X3 = "Archive Custodain Group"
X4 = "Archive Custodain Group" & Chr(X2)
'======================================================================================================
strContents = Replace(strContents, Chr(X1), "") ' REMOVES LINE FEEDS
strContents = Replace(strContents, X3, X4) ' ADDS CR AFTER TITLE ROW
strContents = objRegEx.Replace(strContents, "$1" & vbNewLine)
'======================================================================================================
clipboard.SetText strContents 'PUT BACK INTO CLIPBOARD
clipboard.PutInClipboard
End Sub
When you run objRegEx.Execute(strContents), it returns a match collection. Then, you are not even using the results as Len(objRegEx.Pattern) returns the length of the pattern and not the match.
It seems you just want to obtain the matches and their indices in the string. Remove all starting from Start = 1 and ending with Loop While pos > 0 and use
Dim ms As Object, m As Object
'...
objRegEx.Pattern = "(090052fb[0-9A-Za-z]{8})\t\t"
'...
Set ms = objRegEx.Execute(strContents)
For Each m In ms
WScript.Echo m.FirstIndex
WScript.Echo m.SubMatches(0)
Next
Tested with
strContents = "Initial Approval in First Market or Non-Submitted Closure" & vbTab & vbTab & "090052fb842ef82f" & vbTab & vbTab & "090052fb842f3659" & vbTab & vbTab & "090052fb842ef82e" & vbTab & vbTab
Result:
59
090052fb842ef82f
77
090052fb842f3659
95
090052fb842ef82e
Note I moved the capturing group around all but tab pattern, (090052fb[0-9A-Za-z]{8})\t\t, feel free to adjust as per your needs.
I'm trying to find all the positions of the unique keys (followed by
two Tab keystrokes) in a string in taken from clipboard, positions
with which I then hope to use to insert carriage returns, and then
have everything put back into the clipboard again.
If you want to insert new lines before each key, then instead of locating the keys and inserting new lines, you could try RegExp.Replace
strContents = objRegEx.Replace(strContents, vbNewLine & "$1")
You have to modify the pattern to include whole key in the group:
objRegEx.Pattern = "(090052fb[0-9A-Za-z]{8})\t\t"
Result:
Initial Approval in First Market or Non-Submitted Closure
090052fb842ef82f
090052fb842f3659
090052fb842ef82e
Full code (with new line after pattern):
Sub oldRecords()
Dim clipboard As MSForms.DataObject
Dim strContents As String
Set clipboard = New MSForms.DataObject
clipboard.GetFromClipboard
strContents = clipboard.GetText
Dim objRegEx
Set objRegEx = CreateObject("vbscript.regexp")
objRegEx.Pattern = "(090052fb[0-9A-Za-z]{8})\t\t"
objRegEx.Global = True
objRegEx.IgnoreCase = True
objRegEx.MultiLine = True
strContents = objRegEx.Replace(strContents,"$1" & vbNewLine)
'Put back to clipboard
clipboard.SetText strContents
clipboard.PutInClipboard
End Sub
Using your string example I came into this:
Sub findKeyPositions()
Dim str As String
Dim splitStr() As String
Dim searchStr As String
str = "Initial Approval in First Market or Non-Submitted Closure 090052fb842ef82f 090052fb842f3659 090052fb842ef82e "
splitStr() = Split(Replace(str, "090052fb", ""), " ") 'in your example i did it with 7 spaces and not vbtab
For i = LBound(splitStr) To UBound(splitStr)
searchStr = Trim(splitStr(i))
Debug.Print (InStr(1, str, searchStr, vbTextCompare))
Next i
End Sub
If I understand your post correctly you want to replace the Tabs with CR
If so, then there's no need to find the positions, you could just replace.
Sub replaceTab()
Dim clipboard As MSForms.DataObject
Set clipboard = New MSForms.DataObject
clipboard.GetFromClipboard
clipboard.SetText Replace(clipboard.GetText, vbTab, vbCrLf)
clipboard.PutInClipboard
End Sub

Regular Expression only returns 1 match

My VBA function should take a string referencing a range of units (i.e. "WWW1-5") and then return another string.
I want to take the argument, and put it in a comma separated string,
So "WWW1-5" should become "WWW1, WWW2, WWW3, WWW4, WWW5".
It's not always going to be a single digit. For example, I might need to separate "XXX11-18" or something similar.
I have never used regular expressions, but keep trying different things to make this work and it seems to only be finding 1 match instead of 3.
Any ideas? Here is my code:
Private Function split_group(ByVal group As String) As String
Dim re As Object
Dim matches As Object
Dim result As String
Dim prefix As String
Dim startVar As Integer
Dim endVar As Integer
Dim i As Integer
Set re = CreateObject("vbscript.regexp")
re.Pattern = "([A-Z]+)(\d+)[-](\d+)"
re.IgnoreCase = False
Set matches = re.Execute(group)
Debug.Print matches.Count
If matches.Count <> 0 Then
prefix = matches.Item(0)
startVar = CInt(matches.Item(1)) 'error occurs here
endVar = CInt(matches.Item(2))
result = ""
For i = startVar To endVar - 1
result = result & prefix & i & ","
Next i
split_group = result & prefix & endVar
Else
MsgBox "There is an error with splitting a group."
split_group = "ERROR"
End If
End Function
I tried setting global = true but I realized that wasn't the problem. The error actually occurs on the line with the comment but I assume it's because there was only 1 match.
I tried googling it but everyone's situation seemed to be a little different than mine and since this is my first time using RE I don't think I understand the patterns enough to see if maybe that was the problem.
Thanks!
Try the modified Function below:
Private Function split_metergroup(ByVal group As String) As String
Dim re As Object
Dim matches As Variant
Dim result As String
Dim prefix As String
Dim startVar As Integer
Dim endVar As Integer
Dim i As Integer
Set re = CreateObject("VBScript.RegExp")
With re
.Global = True
.IgnoreCase = True
.Pattern = "[0-9]{1,20}" '<-- Modified the Pattern
End With
Set matches = re.Execute(group)
If matches.Count > 0 Then
startVar = CInt(matches.Item(0)) ' <-- modified
endVar = CInt(matches.Item(1)) ' <-- modified
prefix = Left(group, InStr(group, startVar) - 1) ' <-- modified
result = ""
For i = startVar To endVar - 1
result = result & prefix & i & ","
Next i
split_metergroup = result & prefix & endVar
Else
MsgBox "There is an error with splitting a meter group."
split_metergroup = "ERROR"
End If
End Function
The Sub I've tested it with:
Option Explicit
Sub TestRegEx()
Dim Res As String
Res = split_metergroup("DEV11-18")
Debug.Print Res
End Sub
Result I got in the immediate window:
DEV11,DEV12,DEV13,DEV14,DEV15,DEV16,DEV17,DEV18
Another RegExp option, this one uses SubMatches:
Test
Sub TestRegEx()
Dim StrTst As String
MsgBox WallIndside("WAL7-21")
End Sub
Code
Function WallIndside(StrIn As String) As String
Dim objRegex As Object
Dim objRegMC As Object
Dim lngCnt As Long
Set objRegex = CreateObject("VBScript.RegExp")
With objRegex
.Global = True
.IgnoreCase = True
.Pattern = "([a-z]+)(\d+)-(\d+)"
If .test(StrIn) Then
Set objRegMC = .Execute(StrIn)
For lngCnt = objRegMC(0).submatches(1) To objRegMC(0).submatches(2)
WallIndside = WallIndside & (objRegMC(0).submatches(0) & lngCnt & ", ")
Next
WallIndside = Left$(WallIndside, Len(WallIndside) - 2)
Else
WallIndside = "no match"
End If
End With
End Function
#Shai Rado 's answer worked. But I figured out on my own WHY my original code was not working, and was able to lightly modify it.
The pattern was finding only 1 match because it was finding 1 FULL MATCH. The full match was the entire string. The submatches were really what I was trying to get.
And this is what I modified to make the original code work (asking for each submatch of the 1 full match):

match date pattern in the string vba excel

Edit:
Since my string became more and more complicated looks like regexp is the only way.
I do not have a lot experience in that and your help is much appreciated.
Basically from what I read on the web I construct the following exp to try matching occurrence in my sample string:
"My very long long string 12Mar2012 is right here 23Apr2015"
[0-9][0-9] + [a-zA-Z] + [0-9][0-9][0-9][0-9]
and trying this code. I do not have any match. Any good link on regexp tutorial much appreciated.
Dim re, match, RegExDate
Set re = CreateObject("vbscript.regexp")
re.Pattern = "(^[0-9][0-9] + [a-zA-Z] + [0-9][0-9][0-9][0-9]$)"
re.Global = True
For Each match In re.Execute(str)
MsgBox match.Value
RegExDate = match.Value
Exit For
Next
Thank you
This code validates the actual date from the Regexp using DateValuefor robustness
Sub Robust()
Dim Regex As Object
Dim RegexMC As Object
Dim RegexM As Object
Dim strIn As String
Dim BDate As Boolean
strIn = "My very long long string 12Mar2012 is right here 23Apr2015 and 30Feb2002"
Set Regex = CreateObject("vbscript.regexp")
With Regex
.Pattern = "(([0-9])|([0-2][0-9])|([3][0-1]))(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(\d{4})"
.Global = True
If .test(strIn) Then
Set RegexMC = .Execute(strIn)
On Error Resume Next
For Each RegexM In RegexMC
BDate = False
BDate = IsDate(DateValue(RegexM.submatches(0) & " " & RegexM.submatches(4) & " " & RegexM.submatches(5)))
If BDate Then Debug.Print RegexM
Next
On Error GoTo 0
End If
End With
End Sub
thanks for all your help !!!
I managed to solve my problem using this simple code.
Dim rex As New RegExp
Dim dateCol As New Collection
rex.Pattern = "(\d|\d\d)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(\d{4})?"
rex.Global = True
For Each match In rex.Execute(sStream)
dateCol.Add match.Value
Next
Just note that on my side I'm sure that I got valid date in the string so the reg expression is easy.
thnx
Ilya
The following is a quick attempt I made. It's far from perfect.
Basically, it splits the string into words. While looping through the words it cuts off any punctuation (period and comma, you might need to add more).
When processing an item, we try to remove each month name from it. If the string gets shorter we might have a date.
It checks to see if the length of the final string is about right (5 or 6 characters, 1 or 2 + 4 for day and year)
You could instead (or also) check to see that there all numbers.
Private Const MonthList = "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC"
Public Function getDates(ByVal Target As String) As String
Dim Data() As String
Dim Item As String
Dim Index As Integer
Dim List() As String
Dim Index2 As Integer
Dim Test As String
Dim Result As String
List = Split(MonthList, ",")
Data = Split(Target, " ")
Result = ""
For Index = LBound(Data) To UBound(Data)
Item = UCase(Replace(Replace(Data(Index), ".", ""), ",", ""))
For Index2 = LBound(Data) To UBound(Data)
Test = Replace(Item, List(Index2), "")
If Not Test = Item Then
If Len(Test) = 5 Or Len(Test) = 6 Then
If Result = "" Then
Result = Item
Else
Result = Result & ", " & Item
End If
End If
End If
Next Index2
Next
getDates = Result
End Function