前面研究了正则的基本概念之后,接下来要做的事情就是在VBA中把他实现了。
遗憾的是,VB中并没有内置处理正则的库。所以我们要使用引用外部库的方式(与引用字典以及FSO的库类似),先添加VBScript引用。
在任何一个新的库开始之前,我们都要先了解他的对象体系。在引用完正则之后,首先按F2查看对象型。
在这里从网上盗图一张,来大概看一下这个对象体系:
整体来说,这个对象体系比较简单,我们需要了解3个核心对象以及他的属性和方法。
RegExp对象
这个可以看做是VBA中正则的核心引擎。
我们先用代码来实例化一个RegExp对象,在这里使用前期(注意不是前妻)绑定:
Dim Re As VBScript_RegExp_55.RegExp
Set Re = New VBScript_RegExp_55.RegExp
这个核心引擎对象的属性加方法一共只有7个,我们下面用一个实例来理解RegExp的关键属性和方法:
Pattern属性
这个Pattern属性,就是我们之前讨论的匹配模式
Dim sPattern As String
sPattern = "\d{4}年\d{1,2}月\d{1,2}日"
Re.Pattern = sPattern
Test方法
Test方法是对给定的字符串进行测试,看是否包含RegExp对象的Pattern。
Dim Str As String
Str = "2018年1月1日"
Debug.Print Re.Test(Str)
返回:
True
Global属性
Global属性是一个布尔值,用来设置全局查找。
如果设置为True,代表查找字符串中所有对Pattern的匹配。如果设置为False,那么就代表只查找出现的第一个匹配。
承接上面的代码,我们先把Global设置为True
Re.Global = True
Execute方法
对字符串进行Pattern匹配,所得到的返回值为MatchCollection。
所谓的MatchCollection,其实就是Match对象的集合。为了理解这个概念,可以把Match之于MatchCollection与Worksheet之于Worksheets来作比较。
Dim Str2 As String
Str2 = "2018年1月1日, 2018年1月2日"
Dim mhc As VBScript_RegExp_55.MatchCollection
Set mhc = Re.Execute(Str2)
Debug.Print mhc.Count
MatchCollection有两个属性,一个是count,表示有匹配集合中有几个匹配。
上面的打印结果返回2,代表有两个匹配。
另外一个属性是索引item。使用所以可以对单个匹配进行引用。例如,如果要获得上述匹配的内容,可以这么来写:
Dim i As Integer
For i = 0 To mhc.Count - 1
Debug.Print mhc.Item(i).Value
Next i
返回:
2018年1月1日
2018年1月2日
在实际使用中,mhc.item(0)可以缩写为mhc(0)
MatchCollection集合的索引值从0开始
Match对象
Match包含了对字符串按照指定Pattern所得到的匹配。Match对象比较重要的属性有两个:value以及submatches
value
使用Match.value方法可以获得Match的值。
Submatches
既然一个Match对象已经是对字符串的匹配,那么什么是Submatch呢?
举例来说,对于一个字符串匹配的Pattern:\d{4}年\d{1,2}月\d{1,2}日,可以匹配日期2018年1月1日,但我们如果只想获得年数2018应该怎么处理呢?
如果要获取匹配出来的字符串的某一部分,就需要用括号来进行捕获了。括号捕获出来的内容,会被存放在Submatches集合里面。
上面的匹配可以改成:(\d{4})年\d{1,2}月\d{1,2}日
我们可以使用下面的方法来打印捕获括号内的内容。
Dim sPatternNew As String
sPatternNew = "(\d{4})年\d{1,2}月\d{1,2}日"
Re.Pattern = sPatternNew
Set mhc = Re.Execute(Str2)
Debug.Print mhc.Count
Dim mh As VBScript_RegExp_55.Match
For i = 0 To mhc.Count - 1
Set mh = mhc(i)
Debug.Print "Count of Submatches: ", mh.SubMatches.Count
Debug.Print mh.SubMatches(0)
Next i
返回:
2
Count of Submatches: 1
2018
Count of Submatches: 1
2018
基本上,熟悉了RegExp, Match,以及SubMatch对象之后,就可以用正则做一些基本的匹配,文字处理的小脚本了。 不过从整体上来看,VBA的正则仍然比较弱,如果想用正则做一些高级功能,比如捕获内容然后赋值给变量,或是对匹配直接进行函数运算,还是需要高级语言来实现。