VBA中正则表达式之后向引用与非捕获分组

论坛 期权论坛 期权     
米宏Office   2019-7-7 23:59   4346   0
我的目标:让中国的大学生走出校门的那一刻就已经具备这些Office技能,让职场人士能高效使用Office为其服务。支持鹏哥,也为自己加油!

在介绍后向引用之前我们先来看一个案例:






上面的例子中要求把在职日期中年份相同的数据对应的姓名筛选出来。

第一步,我们先要找出在职日期中年份相同的数据。


我们看下正则表达式该怎么写?


Pattern = "\d{4}",这样可以把连在一起的四位数字给匹配出来。
Pattern = "\d{4}.+",这样可以把四位数字和后面的所有内容给匹配出来。
Pattern = "\d{4}.+\d{4}.+",这样写就相当于是两个"\d{4}.+"合在一起,前面一个可以认为是第一个年份数字到下个年份数字前的所有内容,后面一个当然就是剩下的部分。


我们可以通过匹配到的值来看下效果:


代码如下:

  1. Sub 筛选()
复制代码
  1. Dim regx As Object, rng As Range, mat, m
复制代码
  1. Set regx = CreateObject("vbscript.regexp")
复制代码
  1. With regx
复制代码
  1.     .Global = True
复制代码
  1.     .Pattern = "\d{4}.+\d{4}.+"
复制代码
  1.     For Each rng In [b2:b9]
复制代码
  1.            Set mat = .Execute(rng)
复制代码
  1.            For Each m In mat
复制代码
  1.            Next
复制代码
  1.     Next
复制代码
  1. End With
复制代码
  1. End Sub
复制代码
向右滑动可以查看完整代码

效果如下:(观察m值的变化)






表达式 "\d{4}.+\d{4}.+"和"\d{4}.+"其实没啥区别,都可以把所有内容匹配出来。


但是,当我们把表达式"\d{4}.+\d{4}.+"修改为:
"(\d{4}).+\1.+",
大家看下两个表达式之间的区别,对"\d{4}"进行了分组,同时后面的相同部分改成了1,1代表引用了表达式中第一个括号里的内容,如果表达式中有多个括号,那么数字写几就代表引用第几个括号里的内容,这就是所谓的后向引用。


用数字来表达引用前面分组中的部分,及前面分组中匹配到的内容要被后面引用。

我们看下修改后的效果:


代码如下:

  1. Sub 筛选()
复制代码
  1. Dim regx As Object, rng As Range, mat, m
复制代码
  1. Set regx = CreateObject("vbscript.regexp")
复制代码
  1. With regx
复制代码
  1.     .Global = True
复制代码
  1.     .Pattern = "(\d{4}).+\1.+"
复制代码
  1.     For Each rng In [b2:b9]
复制代码
  1.            Set mat = .Execute(rng)
复制代码
  1.            For Each m In mat
复制代码
  1.            Next
复制代码
  1.     Next
复制代码
  1. End With
复制代码
  1. End Sub
复制代码
向右滑动可以查看完整代码

效果如下:





通过以上的例子,我们就清楚了什么是后向引用,文章开始的案例的代码如下:

  1. Sub 筛选1()
复制代码
  1. Dim regx As Object, rng As Range, n%
复制代码
  1. Set regx = CreateObject("vbscript.regexp")
复制代码
  1. With regx
复制代码
  1.     .Global = True
复制代码
  1.     .Pattern = "(\d{4}).+\1.+"
复制代码
  1.     For Each rng In [b2:b9]
复制代码
  1.            If .test(rng) Then
复制代码
  1.                  n = n + 1
复制代码
  1.                  Cells(n + 1, 4) = Cells(rng.Row, 1)
复制代码
  1.            End If
复制代码
  1.     Next
复制代码
  1. End With
复制代码
  1. End Sub
复制代码
向右滑动可以查看完整代码

这里要注意的另外一个重要内容:
If .test(rng) Then,表示假如表达式匹配成功时……

后向引用是在分组的基础上的一个延续。


在 "(\d{4}).+\1.+"中,每匹配到一个"(\d{4})",都会形成一个组用以保存记录,方便后面引用,所以会占用一定的内存,这种叫做捕获分组,只要分了组,运行代码时都会产生组记录。


那如果我们不需要捕获,不做后向引用,只是单纯的匹配呢?
那就用(?:pattern)这种语法。


比如:"(?:\d{4}),这样的表达式在运行时就不会产生组记录。

本节的分享就到这里,鹏哥祝大家每天都有进步。

加入米宏Office培训群,每天进步一点点!
两杯咖啡的钱,
即可加入米宏Office培训群
你还在犹豫?
微信号:527240310
每天进步一点,每天提升一点!
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:75
帖子:15
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP