正则表达式不是VBA的一部分,很多语言都需要他,包括WORD中的查找通配符,也属于正则表达式的变体
测试工具:
https://deerchao.cn/tools/wegester/
语法查询:
https://www.runoob.com/regexp/regexp-metachar.html
重复结构
只处理紧贴在前的一个字符,更靠前的不管
同一内容连续出现 n次
+ 前面的内容连续出现1次或更多次
注意下面文本是否使用了空格和回车,因为不太好显示,如果结果和下图结果不同,最好测试一下哪里可以加减这些符号
空格a+b+空格
+为元字符,a和b称为文字
正则表达式中的每一个字符,如果不是元字符,就会被视作文字
查找结果
* 前面的内容出现任意次,包括 0次
所以多了bbb
? 前面的内容出现0次或1次
{n}正好出现n次
{n,m}最少n次,最多m次
特定内容
\d 数字 字符 \D 所有非数字字符
\w ==文字(包括数字和下划线)==字符
\W 所有非文字字符
\s 空白字符(空格、换行)可用于找跨行
\S 所有非空白字符
点号.可以代表除了换行符以外的所有字符
注意大小写
点号通吃
转义字符
文本中含有+号,需要用转义字符\来帮他转为普通文本
含有转移字符\,则要写成\
贪婪搜索和懒惰搜索
贪婪搜索
以某个字符为起始,如果同时有多个符合要求的字符串
比如 3+5,3+5 2+7,则选择最长的一个作为最终结果
懒惰搜索
选择最短的作为结果
a*? 可有任意个a,但尽可能少
a+? 一个或多个a,但尽可能少
a?? 零个或一个a,但尽可能少
a{3,8}? 3到8个a,但尽可能少
字符组[]
代表一个字符,且必须是方括号内字符之一
例如[ab12]:一个字符,且只看是a b 1 2 中某一个
在字符组里面,加号不需要转义就代表普通字符
方括号里面的元字符只有 ^
如果^出现在方括号的第一位,则该字符组代表一个未在方括号列出的字符
比如【^abc】代表可以是任意字符,除了abc (这里的方括号要用英文,因为在csdn编辑器用英文会被转义,所以打的中文)
注意:敲了回车也会被算进去,所以写的时候要看清楚
如果减号-出现在两个字符之间,就代表一个元字符
[c-f]等同于[cdef]
[3-8]-[345678]
[e-a]写法错误
分组()
当正则表达式的一部分被圆括号括起时,这些字符被视作同一个整体
比如
\sa(bc)+s
把bc当做整体,+替代的是bc
bc,bcbc可以,但bcc,cc不行
分支|
\sa(bc|de)+\s
一个或多个字符串,其中每个或为bc或者为de
交替出现也符合要求
在VBA中调用正则表达式
客户信息
张三电话 0411-82373923 李四邮编 102303 张三工号
233#54234423 张三邮编 201332 李四电话
0571#23325634 王五工号
0123-56668823 王五电话
021-62344356 赵六电话
010#84234235 赵六工号
23423352 赵六邮编 102324
李四工号 234#65234662
把所有电话号码找出来
即 姓名电话 电话号码找出来
以 李四电话0571#23325634 为例
首先是任意空白字符+多个非空白字符(名字)+电话+任意个空白字符+多个数字字符+减号或井号
+多个数字(因为号码不全是8位)
写出来就是
\s*\S+电话\s*\d+[-#]\d+
但是为了分组后得到更好的结果,选择添加2个括号,原因在代码注释里说明了
\s*(\S+)电话\s*(\d+[-#]\d+)
得到上述结果
在编译器里面测试好后,我们进入VBE里面写代码
Option Explicit
Sub matchdemo()
Dim i As Long, s As String
Dim myreg As Object
Dim mymatches As Object, mymatch As Object
'前面是匹配的对象集合,后面是一个个的对象
'定义外部对象要提前声明
'因为这个不属于VBA而是VBscript的一部分
s = Range("g2").Value
Set myreg = CreateObject("vbscript.regexp")
'该函数专门用于生成外部对象,括号内的
'是用来调用正则表达式的语句
myreg.Pattern = "\s*(\S+)电话\s*(\d+[-#]\d+)"
'设定将要执行的正则表达式
'双引号引正则表达式字符串
'如果正则表达式里面存在双引号,那就打""XX""
'这样就可以避免编译错误
myreg.Global = True
'Cells(2, 2) = myreg.Replace(s, "$1:$2")
'为true时,找到并返回所有符合表达式要求的结果
'False,只返回第一个符合查询条件的结果
Set mymatches = myreg.Execute(s)
'execute用来执行正则表达式
'因为是对象,所以要加上set这个关键字
i = 2
For Each mymatch In mymatches
'matches是整个集合,match是每一个对象
Cells(i, 1) = mymatch.submatches(0)
'submatches主要是保留其中的一部分
'需要在正则表达式中辅以圆括号
'用来切分成几个整体,打包处理
'圆括号此时的用途称为capture group
'捕获组
Cells(i, 2) = mymatch.submatches(1)
i = i + 1
Next mymatch
End Sub
替换功能
选中替换功能
$1提取第一个括号里面的,然后加一个冒号,$2提取第二个括号里的内容,中间用冒号作为连接
Sub replacedemo()
Dim i As Long, s As String
Dim myreg As Object
Dim mymatches As Object, mymatch As Object
s = Range("g2").Value
Set myreg = CreateObject("vbscript.regexp")
myreg.Pattern = "\s*(\S+)电话\s*(\d+[-#]\d+)"
myreg.Global = True
Cells(2, 3) = myreg.Replace(s, "$1:$2")
'regexp.replace(s,r) 按照已经在pattern中定义好的
'正则表达式进行查找,并将每一个找到的字符串
'按照参数r的表达式进行替换
'生成的是一个新字符串,原来的s不变
'传值不传参
End Sub