VBA正则表达式深度解析

8 篇文章 0 订阅
1 篇文章 0 订阅

目录

本文章可以学到:

先上代码:

 分析:

调式:

细心一点会发现两个问题:

 一个一个的来解答


本文章可以学到:

  • VBA正则表达式匹配第N个结果
  • VBA正则表达式剔除匹配包含字符的数字中剔除字符,只保留数字

先上代码:

Function GetStr(ByVal rng As String, str As String, Optional i As Long, Optional s As Boolean)
    '第一个参数rng    为数据源
    '第二个参数str    为正则表达式
    '第三个参数i      为正则表达式成功匹配的结果列表中的第几个,从0开始,默认为0即第1个
    '第四个参数s      为文本[True]或数字[False],用于剔除数字中的文本内容,默认为数字[False]

    If IsMissing(i) Then i = 0
    If IsMissing(s) Then s = False

    Dim iRg As Object

    Set iRg = CreateObject("VBscript.regexp")
    With iRg
        .Global = True
        .Pattern = str   '表达式,直接从用户函数的第二个参数中调用

        If .Execute(rng).Count = 0 Then
            '如果匹配到结果的量为0则
            GetStr = ""
            '返回结果为空值
            '函数结束
        Else

            If IsNumeric(.Execute(rng)(i)) Or s Then
            '如果第一次得到的结果是数字或者函数的第4个参数为True或非0则
                GetStr = .Execute(rng)(i)
                '直接返回第一次得到的结果
                '函数结束
            Else
                GetStr = GetStr(.Execute(rng)(i), "[0-9]+[.]{0,1}[0-9]{0,}")
                '否则从第一次返回的结果中剔除数字以外的字符
                '即调用函数本身再传入一个数字的正则表达式"[0-9]+[.]{0,1}[0-9]{0,}"
            End If
        End If
    End With
End Function

 

 测试结果:

 BCDEF
2源文本.1ss11.11cmcxzas/.'22.22cmwq.,3cmd.,/;eq4.44444cm
3正则表达式.1[0-9]+[.]{0,}[0-9]{0,}[cm]
4                第3参数(i)
第4参数(s)     
0123
5
6011.11   =GetStr(C2,C3,C4,B6)22.22  =GetStr(C2,C3,D4,B6)3  =GetStr(C2,C3,E4,B6)4.44444  =GetStr(C2,C3,F4,B6)
7111.11c  =GetStr(C2,C3,C4,B7)22.22c =GetStr(C2,C3,D4,B7)3c =GetStr(C2,C3,E4,B7)4.44444c =GetStr(C2,C3,F4,B7)
8     
9源文本.2ss11.11cmcmxzas/.'22.22cmwq.,333333cmd.,/;eq4.44444cm
10正则表达式.2[0-9]+[.]{0,}[0-9]{0,}[cm]+
11                第3参数(i)
第4参数(s)     
0123
12
13011.11      =GetStr(C9,C10,C11,B13)22.22    =GetStr(C9,C10,D11,B13)333333   =GetStr(C9,C10,E11,B13)333333cm  =GetStr(C9,C10,E11,B14)
14111.11cmcm  =GetStr(C9,C10,C11,B14)22.22cm  =GetStr(C9,C10,D11,B14)333333cm =GetStr(C9,C10,E11,B14)4.44444cm =GetStr(C9,C10,F11,B14)

 分析:

我们从[C6]单元格开始说起

代入目标单元格解析的公式是:

=GetStr("ss11.11cmcxzas/.'22.22cmwq.,3cmd.,/;eq4.44444cm","[0-9]+[.]{0,}[0-9]{0,}[cm]",0,0)

 

调式:

在第17行代码添加断点,然后在监视窗口中添加监视:

irg.Execute(Rng)

双击[C6]单元格,回车就可以看到如下图所示

可以看到这个 "[0-9]+[.]{0,}[0-9]{0,}[cm]正则表达式作用在这段"ss11.11cmcxzas/.'22.22cmwq.,3cmd.,/;eq4.44444cm"文字中,会得到4个结果,那么就可以通过传入第3个参数  i   来选择我们想要的第几个结果。

在[C6]单元格中我们第三个参数是0,也是就返回匹配到的第0个结果,11.11c

 

细心一点会发现两个问题:

  1. 传入的正则表达式是 "[0-9]+[.]{0,}[0-9]{0,}[cm]",末尾是 cm 为啥只匹配到了c
  2. 【C6】单元格的结果是11.11
     

 

 一个一个的来解答

第1个问题是因为[cm]默认只匹配中括号中的第一个符号,也就是c,如果想要匹配[cm]有几种方法

  • 笨方法:[c][m]或者[cm]{2}或者[cm]{0,}
  • 好方法:[cm]+或者cm

 第2个问题是因为一般匹配的数字的时候,数字后面可能会有一些特定字符比如单位。而匹配的结果会把这些字符一起放进去,这样就不方便使用公式进行计算或者统计总数,需要二次匹配,也就是在得到一个包含字符的数字中剔除字符,只保留数字。

关键就在24-33行代码:

            If IsNumeric(.Execute(rng)(i)) Or s Then
            '如果第一次得到的结果是数字或者函数的第4个参数为True或非0则
                GetStr = .Execute(rng)(i)
                '直接返回第一次得到的结果
            Else
                GetStr = GetStr(.Execute(rng)(i), "[0-9]+[.]{0,1}[0-9]{0,}")
                '否则从第一次返回的结果中剔除数字以外的字符
                '即调用函数本身再传入一个数字的正则表达式"[0-9]+[.]{0,1}[0-9]{0,}"
            End If

根据这个思路看测试结果,就很清晰明了了。

看不明白的话把代码放在EXCEL模块里面多测试并调式就会明白了,有不明白的欢迎交流。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值