VBA之正则表达式(8)

实例需求:数据保存在A列中,需要将其中重复字符分拆后保存在后续的列中,为简化示例代码,只考虑小写英文字符。

这个需求也并不复杂,用VBA代码逐个判断字符和其前后的字符对比,就可以区分每组,高手可以写出递归调用过程。用正则处理这种问题会更简单。

Sub RegExpDemo()
    Dim strTxt As String
    Dim objRegEx As Object, objMatch As Object
    Dim objMH As Object, c As Range
    Set objRegEx = CreateObject("vbscript.regexp")
    objRegEx.Global = True
    objRegEx.Pattern = "([a-z])\1*"
    Range("B:AA").ClearContents
    For Each c In Range([A1], Cells(Rows.Count, "A").End(xlUp))
        strTxt = c.Value
        Set objMatch = objRegEx.Execute(strTxt)
        If objMatch.Count > 0 Then
            col = 2
            For Each objMH In objMatch
                Cells(c.Row, col) = objMH.Value
                col = col + 1
            Next
        End If
    Next
    Set objMH = Nothing
    Set objMatch = Nothing
    Set objRegEx = Nothing
End Sub


【代码解析】
第5行代码使用后期绑定创建正则对象。
第6行代码设置为全局搜索模式。
第7行代码指定正则匹配字符串,([a-z])用于匹配单个小写英文字符,并提取为第一组,\1*含义是第一组字符重复0次(也就是只有单个字符的情况)或者多次。
第8和代码清空后续列用于保存结果。
第9行代码第19行代码循环处理工作表中的数据。
第11行执行正则匹配。
如果匹配成功,第14行到第17行代码将匹配结果写入工作表后续列中。
注意第15行代码读取的是objMH.Value,而不是objMH.submatches(0).Value。


似乎这个代码也没有什么神奇的地方,只是匹配模式中使用了匹配组\1

接下来才是今天要讲的重点,上面的正则匹配是通用思路,解决问题时,都是去设法提取匹配的字符串,然后在VBA中加工,这个示例需要写入工作表单元格,那么只要拆分成数组,就可以一次性写入单元格区域了,VBA中拆分数组肯定是用Split函数了。下面的升级版解决方案中用到了正则替换。

Sub RegExpRepDemo()
    Dim strTxt As String, arrRes
    Dim objRegEx As Object, objMatch As Object
    Dim objMH As Object, c As Range
    Set objRegEx = CreateObject("vbscript.regexp")
    objRegEx.Global = True
    objRegEx.Pattern = "([a-z])(?!\1|$)"
    Range("B:AA").ClearContents
    For Each c In Range([A1], Cells(Rows.Count, "A").End(xlUp))
        strTxt = c.Value
        arrRes = Split(objRegEx.Replace(strTxt, "$1 "))
        Cells(c.Row, 2).Resize(1, UBound(arrRes) + 1).Value = arrRes
    Next
    Set objMH = Nothing
    Set objMatch = Nothing
    Set objRegEx = Nothing
End Sub

【代码解析】
与上面代码相同的步骤这里就不再赘述。

匹配模式 含义
([a-z]) 匹配单个小写英文字符,并提取为第一组
?! 零宽度否定顺序环视,不消耗字符,只用于环视判断
\1 第一组匹配字符(一个或者多个)
$ 行的结束标识

aaabbccccdeeee为例看一下正则匹配过程。

游标位置 匹配组 下一个字符 说明
0 a a 下一个字符与匹配组相同,不满足正则模式
1 a a 下一个字符与匹配组相同,不满足正则模式
2 a b 下一个字符与匹配组不同,满足正则模式,将被替换为a+空格
3 b b 下一个字符与匹配组相同,不满足正则模式
4 b c 下一个字符与匹配组不同,满足正则模式,将被替换为b+空格
依次处理每个字符
13 e $ 下一个为字符结束标识,不满足正则模式

正则替换之后的字符串为aaa bb cccc d eeee,注意字符串末尾并不会添加空格,使用Split拆分为数组,可以直接写入一行单元格内,这波操作比第一个代码更简洁。

(0)

相关推荐

  • 这个超牛逼的求和公式,请速收藏起来!

    与 30万 读者一起学Excel VIP学员的问题,要根据这杂乱无章的费用明细,计算合计金额. 这真是令人头疼的问题! 不幸中的大幸,这种居然可以解决.赶紧把下面的内容收藏起来,否则下回遇到猪队友,欲 ...

  • 关于VBA中的变量声明

    摘 要: 基于Microsoft Office系列办公软件中内嵌的VBA语言,本文作者针对其语法规则中的变量声明规则进行了论述,重点介绍了显式声明和隐式声明的用法,并对两种声明方式进行了对比,提出了程 ...

  • Excel VBA之函数篇-3.12区分订单号升级版,综合长度,起始字符判断

    前景提要 上一节我们学习了如果通过订单号的结构来判断不同类型的订单号,不过后来我发现自己的考虑的并不够全面,案例中提供的几种订单号非常的普通,区分表示比较的明显,要么中文,要么英文,太容易区分了,在日 ...

  • EXCEL VBA 使用正则表达式清洗替换数据

    在EXCEL表内遇到有规律性的数据需要提取或者替换时,比如在数据中提取时间,身份证号码等,EXCEL内自带的查找替换就难以实现,我们可以利用VBA适用正则表达式去对数据进行匹配. 什么是正则表达式? ...

  • vba中正则表达式

    vba中正则表达式

  • VBA之正则表达式(2)

    实例需求:数据保存在F列(公式,判断条件,whatever),需要在每个单元格引用之前添加A列指定的工作表名称+!,结果如H列所示,对于F16中的公式,由于I49已经指定工作表,所以此单元格不需要再处 ...

  •  VBA之正则表达式(3)

    实例需求:数据保存在B列,其格式为规格1*数量1 + 规格2*数量2 + ...,现在需要统计数量总和,如C列所示.例如B3中明细为100*3+115*1对应的包装个数就是3+1. 示例代码如下. S ...

  • VBA之正则表达式(5)

    实例需求:数据保存在A列中,需要将其中中文字符提取至B列.如何匹配中文字符呢? 大家都知道匹配英文单词很简单,[a-zA-z]把26个字母大小写将都涵盖了,可是中文字符怎么搞呢,是否也可以使用类似的方 ...

  •  VBA之正则表达式(6)

    实例需求:数据保存在A列中,需要对其中音标部分进行下划线标注,如C列所示,匹配这样的非典型字符,正则表达式是最佳选择. 示例代码如下. Sub RegExpDemo() Dim strTxt As S ...

  •  VBA之正则表达式(7)

    实例需求:数据保存在A列中,数据组之间使用全角逗号分隔,重整后需要将每组数据开始的圆括号部分移动到末尾,并合并相同的全角方括号内容.貌似这个需求有些拗口,实际效果见B列. 示例代码如下. Sub Re ...

  •  VBA之正则表达式(9)

    在正则表达式中有如下几种环视(断言),很多正则的教学文章中都会讲解其含义,也有一些例子. 正则表达式 说明 (?<=Expression) 逆序肯定环视,表示所在位置左侧能够匹配Expressi ...

  •  VBA之正则表达式(10)

    <添加千分位(1/3)>博文讲到,简单合并正则表达式无法实现想要的效果,问题在于小数部分数字. 这里的核心是如何消耗掉小数部分的数字,不被捕获,可以实现添加千分位功能的正则表达式如下: ( ...