VBA之正则表达式(16)-- 提取非重复值

161 篇文章 16 订阅
49 篇文章 18 订阅

实例需求:数据序列使用减号连接,其中序列中包含重复元素。需要提取非重复元素,并使用减号连接,对于重复元素保留最后一次出现位置。
测试字符串:A-B-D-CC-C-C-F-C-E-C-D-E-CC-F
重复元素标记为蓝色,去重后结果为:A-B-C-D-E-CC-F


这个字符提取规则相对简单,直接使用VBA方法也可以实现。

Sub VBA_DEMO_0725()
    Dim arrData
    Dim i As Integer
    Dim dic As Object
    Dim n As Integer
    Dim arrRes()
    Dim arrTmp()
    Set dic = CreateObject("scripting.dictionary")
    strTxt = "A-B-D-CC-C-C-F-C-E-C-D-E-CC-F"
    arrData = Split(strTxt, "-")
    For i = UBound(arrData) To LBound(arrData) Step -1
        If Not dic.exists(arrData(i)) Then
            dic(arrData(i)) = arrData(i)
        End If
    Next i
    arrTmp = dic.Items
    n = 1
    For i = dic.Count - 1 To 0 Step -1
        ReDim Preserve arrRes(1 To n)
        arrRes(n) = arrTmp(i)
        n = n + 1
    Next
    Debug.Print Join(arrRes, "-")
    Set dic = Nothing
End Sub

【代码解析】
提取唯一值最简单的实现方式就是字典对象,第8行代码创建字典对象。
第10行代码就字符串拆分为数组。
对于重复元素保留最后一次出现位置,所以第11行到第15行倒序读取数组,加入到字典对象中。
第16行代码将字典对象的值保存在数组中。
第18行到第22行将唯一值数组倒序保存在结果数组中。
第23行代码使用Join函数组合唯一值结果为字符串。


使用正则来实现这个需求代码会更简单。

Sub RegExpDemo()
    Dim strTxt As String
    Dim objRegEx As Object
    Set objRegEx = CreateObject("vbscript.regexp")
    objRegEx.Pattern = "\b(\w+)-(?=.*-\1(-|$))"
    objRegEx.Global = True
    strTxt = "A-B-D-CC-C-C-F-C-E-C-D-E-CC-F"
    If objRegEx.test(strTxt) Then MsgBox objRegEx.Replace(strTxt, "")
    Set objRegEx = Nothing
End Sub

【代码解析】
第5行代码设置正则匹配模式,其具体含义如下。

正则表达式含义
\b匹配英文单词的边界,所在位置的一侧为单词字符,另一侧为非单词字符、字符串的开始或结束位置
(\w+)匹配一个或者多个英文字符,相当于[a-zA-Z]
-匹配分隔符
(?=.*-\1(-|$))是一个零宽正向先行断言,\1提取第一个匹配组,代表重复出现的元素,重复元素之前为分隔符,其后可以是分隔符或者字符串结束位置,在两个重复元素之间可以包含任意多个字符,此处使用.*为贪婪匹配

正则可以成功匹配七次,即如下的蓝色粗体部分字符(不包括分隔符)
A-B-D-CC-C-C-F-C-E-C-D-E-CC-F
在这里插入图片描述
第8行代码使用正则替换,将匹配部分替换为空。

粗略来看,构建正则表达式时的思路有两大类:

  1. 利用匹配组,获取匹配结果
  2. 匹配不需要的字符,利用正则替换为空,进而获得所需结果。

相关博文链接:
VBA之正则表达式(12)-- 格式调整
VBA之正则表达式(13)-- 字符串变换
VBA之正则表达式(14)-- 提取指定位数的数字
VBA之正则表达式(15)-- 提取数字求和
VBA之正则表达式(16)-- 提取非重复值
VBA之正则表达式(17)-- 提取多组数据(去除末尾字符)

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值