Reputation: 75850
Background:
Just now, I was answering a question and was playing around with RegEx
within VBA
. The goal is to create a list of names that exist within a string. RegEx
was the go-to solution since we want to prevent VBA
to stumble over punctuation marks and substrings that look similar e.g.: Jack
or Jacky
.
Sample Data:
Let me give a simple sample. Imagine we have a string like:
Dim str As String: str = "Jack's turn, Becky's or Frank?"
we want to know which names in a certain array are mentioned within the string, for example:
Dim arr As Variant: arr = Array("Jack", "Frank")
Sample Code:
To prevent an iteration over the array, I went with the following code:
Sub Test()
Dim str As String: str = "Jack's turn, Becky's or Frank?"
Dim arr As Variant: arr = Array("Jack", "Frank", "Beth")
Dim regex As Object: Set regex = CreateObject("VBScript.RegExp")
regex.Pattern = "\b(" & Join(arr, "|") & ")\b"
regex.Global = True
Set hits = regex.Execute(str)
For Each hit In hits
Debug.Print hit
Next hit
End Sub
Problem:
Whereas the above would neatly return the two hits, it would not work case-insensitive. For example, changing the following line will only return Jack
:
Dim str As String: str = "Jack's turn, Becky's or frank?"
I thought I could counter that by turning off case-sensitivity using (?i)
:
regex.Pattern = "(?i)\b(" & Join(arr, "|") & ")\b"
But the problem is that this would work perfectly for most languages (test here), however VBA
seems to have a problem with it and generates an Error 5017
upon execution.
Question:
Does anybody know why? Is this not supported within VBA
or is my syntax wrong? If not supported, what is the alternative to get hits case-insensitive while retaining the possibility to Join
the array of names?
Bonus-Question:
Ultimately I would like to Join
the Hits
together through a delimiter, for example like:
Debug.Print Join(regex.Execute(str),", ")
However, I realized execution returns a collection and needs iteration first which I would like to avoid.
Upvotes: 7
Views: 4422
Reputation: 84465
Set the property on the RegExp object i.e.
regex.ignorecase = True
The RegExp object has three properties that affect how regular expressions are applied:
IgnoreCase: I trust this is self-explanatory
Global: Determines whether or not to find all possible matches in the input string. If Global is set to false, only the first match will be found or replaced, as applicable.
MultiLine: Determines whether matches can span accross line breaks.
See also: https://learn.microsoft.com/en-us/previous-versions//1400241x%28v%3dvs.85%29
And from https://www.regular-expressions.info/vbscript.html regarding VBScript’s Regular Expression Support as we are using Microsoft VBScript Regular Expressions 5.5
No mode modifiers to set matching options within the regular expression.
Upvotes: 14