Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case-insensitive Regular Expression - VBA

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.

like image 750
JvdV Avatar asked Jan 03 '20 12:01

JvdV


People also ask

How do I remove case sensitive in Excel VBA?

One of the easiest and fastest ways to remove case sensitivity in VBA is to declare the Option Compare Text statement. This statement must be declared at the very top of the module and before any Sub or function. Option Compare Text is applicable to a module in which it is declared or written not other modules.

Can we use regular expression in VBA?

Regular Expressions (Regex) are a pattern that is used to find matches within strings. This is very useful when you want to validate, replace, or extract data from strings. In Excel, regular expressions can be used when working with VBA.

Is VBA find case sensitive?

VBA: usage is case sensitive. Application. -- invokes an Excel function so it will be case sensitive if the Excel function is case sensitive. To make VBA not case sensitive you can use UCASE or LCASE as in IF UCASE(myvar) = "ABC" THEN ...

Which VBA constant term helps to compare case-insensitive?

StrComp VBA can perform both case sensitive and case insensitive string comparisons. This tutorial will walk you through an StrComp example and teach you how to use it to compare two strings in VBA.


1 Answers

Set the property on the RegExp object i.e.

regex.ignorecase = True

RegExp object

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://docs.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.

like image 83
QHarr Avatar answered Sep 30 '22 04:09

QHarr