1

I'm trying to build a regex pattern that will return False if a string starts with certain characters or contains non-word characters, but because VBA's RegExp object doesn't support lookbehind, I am finding this difficult. The only word character prefixes that should fail are B_, B-, b_, b-.

This is my test code:

Sub testregex()

Dim re As New RegExp

re.pattern = "^[^Bb][^_-]\w+$"

Debug.Print re.Test("a24")
Debug.Print re.Test("a")
Debug.Print re.Test("B_")
Debug.Print re.Test(" a1")


End Sub

I want this to return:

True
True
False
False

but instead it returns

True
False
False
True

The problem is that the pattern looks for a character that's not in [Bb], followed by a character that's not in [-_], followed by a sequence of word characters, but what I want is just one or more word characters, such that if there are 2 or more characters then the first two are not [Bb][-_].

Community
  • 1
  • 1
sigil
  • 9,370
  • 40
  • 119
  • 199
  • 1
    In expression `" a1"` there are 2 or more characters, and the first two are not `[Bb][-_]`, but you want `.Test(" a1")` to return `False`. Following your definition it should be `True`. Please explain am I missing something? – omegastripes Mar 23 '15 at 21:39
  • @omegastripes, the string should only have **word characters**, which is why I used `\w` in the regex pattern. – sigil Mar 23 '15 at 21:41
  • @femtoRgon, yes, my current workaround for this involves two regexes. I'm hoping to find a single-regex solution, as that will help with the extensibility of the code. – sigil Mar 23 '15 at 21:46

3 Answers3

3

Try matching this expression:

^([Bb][\-_]\w*)|(\w*[^\w]+\w*)$

...which will match "B_", "b_", "B-" and "b-" or anything that's not a word character. Consider a successful match a "failure" and only allow non-matches to be valid.

Colin
  • 4,025
  • 21
  • 40
  • While this will exclude "B_xxy", it will also exclude "B2xxy", which should pass. The only prefixes that should fail are `B_,B-,b_,b-`. I'm sorry if I didn't make that clear in the original question. – sigil Mar 23 '15 at 21:56
  • I adjusted the expression, though it's easiest to invert the way you think about the result such that "success" is a failure. – Colin Mar 23 '15 at 22:24
0
re.Pattern = "^(?:[^ Bb][^ _-]\w+|[^ Bb][^ _-]|[^ Bb])$"
omegastripes
  • 12,351
  • 4
  • 45
  • 96
0

You can get your matches with

regEx.Pattern = "^[^ bB][^_ -]*\w*$"
regEx.MultiLine = True
Debug.Print regEx.Test("a24")
Debug.Print regEx.Test("a")
Debug.Print regEx.Test("B_")
Debug.Print regEx.Test(" a1")

Output:

True
True
False
False
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563