如何在VBA中使用正则表达式测试特定字符

3
我需要测试一个字符串变量,确保它匹配特定的格式:
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
其中x可以是任何字母数字字符(a-z, 0-9)。
我尝试了以下代码,但似乎不起作用(测试值始终失败)。
If val Like "^([A-Za-z0-9_]{8})([-]{1})([A-Za-z0-9_]{4})([-]{1})([A-Za-z0-9_]{4})([-]{1})([A-Za-z0-9_]{4})([-]{1})([A-Za-z0-9_]{12})" Then
    MsgBox "OK"
Else
    MsgBox "FAIL"
End If

.

fnCheckSubscriptionID "fdda752d-32de-474e-959e-4b5bf7574436"

有什么建议吗?如果可以使用VBA或公式实现,我不介意。
3个回答

2

你已经在使用 ^ 开始字符串锚定符号,很好。你还需要使用 $ 结束字符串锚定符号,否则在最后一组数字中,正则表达式引擎会匹配更长数字组的前12个数字(例如15位数字)。

我用更简洁的方式重写了你的正则表达式:

^[A-Z0-9]{8}-(?:[A-Z0-9]{4}-){3}[A-Z0-9]{12}$

注意以下几点细节:
  • [-]{1} 可以用 - 表达
  • 我删掉了下划线因为你说你只想要字母和数字。如果你确实想要下划线,可以用 \w{8} 代替 [A-Z0-9]{8},因为 \w 匹配字母、数字和下划线。
  • 删掉了小写字母。如果你想允许小写字母,我们会在代码中开启不区分大小写模式(见下面示例代码第3行)。
  • 不需要使用 (捕获组),所以删除了括号
  • 有三组由四个字母和一个短横线组成,所以用 {3} 写成了 (?:[A-Z0-9]{4}-)

示例代码

Dim myRegExp, FoundMatch
Set myRegExp = New RegExp
myRegExp.IgnoreCase = True
myRegExp.Pattern = "^[A-Z0-9]{8}-(?:[A-Z0-9]{4}-){3}[A-Z0-9]{12}$"
FoundMatch = myRegExp.Test(SubjectString)

我喜欢正则表达式的复杂简洁性以及它的实现。再见。 - aSystemOverload
1
如果你对正则表达式技巧感兴趣,这个技巧适用于许多情况,你可能会在一个雨天享受它:匹配(或替换)一种模式,除了... 我写这篇文章的时候非常开心。 - zx81

1
Sub Test()
    MsgBox fnCheckSubscriptionID("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
End Sub

Function fnCheckSubscriptionID(strCont)
    ' Tools - References - add "Microsoft VBScript Regular Expressions 5.5"
    With New RegExp
        .Pattern = "^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$"
        .Global = True
        .MultiLine = True
        fnCheckSubscriptionID = .Test(strCont)
    End With
End Function

如果使用早期绑定出现任何问题,您可以使用后期绑定 With CreateObject("VBScript.RegExp") 代替 With New RegExp


1
你的想法没问题,但是\w=[A-Za-z0-9_],所以\d和.ignorecase都是多余的。同时建议显式声明变量。设置Option Explicit能使你的代码更加高效,并且有助于捕捉拼写错误。这里有很好的讨论:http://www.cpearson.com/excel/declaringvariables.aspx。 - Ron Rosenfeld

1
您可以使用正则表达式或本地VBA来实现此目的。我假设根据您的代码,下划线字符在字符串中也是有效的。
要使用本地VBA完成此操作,您需要构建LIKE字符串,因为量词不包括在内。另外,使用Option Compare Text使“like”动作不区分大小写。
Option Explicit
Option Compare Text
Function TestFormat(S As String) As Boolean
    'Sections
    Dim S1 As String, S2_4 As String, S5 As String
    Dim sLike As String
With WorksheetFunction
    S1 = .Rept("[A-Z0-9_]", 8)
    S2_4 = .Rept("[A-Z0-9_]", 4)
    S5 = .Rept("[A-Z0-9_]", 12)
    sLike = S1 & .Rept("-" & S2_4, 3) & "-" & S5
End With

TestFormat = S Like sLike

End Function

使用正则表达式,模式构建更简单,但执行时间可能会更长,如果您正在处理大量数据,则可能会产生影响。

Function TestFormatRegex(S As String) As Boolean
    Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
With RE
    .Global = True
    .MultiLine = True
    .Pattern = "^\w{8}(?:-\w{4}){3}-\w{12}$"
    TestFormatRegex = .test(S)
End With
End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接