ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: liu-aguang

[原创] 正则表达式入门与提高---VBA平台的正则学习参考资料

    [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-6-11 09:20 | 显示全部楼层
本帖已被收录到知识树中,索引项:文本处理和正则
本帖最后由 liu-aguang 于 2014-6-12 08:29 编辑

     <1>Matches集合的Item和Count属性
     利用Matches集合的Item属性可以得到它包含的每个Match对象;利用Count属性可以得到成功匹配的个数.
    Matches集合对象中元素(成功匹配)的索引编号从0开始.我们可以用遍历集合的方式或索引方法读取每一个匹配值.
     例:从一段文本中提取所有英文单词.
     目标文本:”苹果:iphone_5s;诺基亚:Nokia_1020”
   结果要求:分别提取出iphone_5s和Nokia_1020
捕获6.PNG
:
Sub test2()
    Dim reg, k, mh, strA$
    strA = "苹果:iphone_5s;诺基亚:Nokia_1020"
    Set reg =CreateObject("vbscript.regexp")
    reg.Pattern = "\w+"
    reg.Global = True
    Set mh = reg.Execute(strA)
    For Each mhk In mh
        Debug.Print mhk.value
    Next
End Sub
讨论:
  通过语句Set mh = reg.Execute(strA),Execute方法返回一个集合对象mh,在这个集合对象里包含两个匹配对象,代码中用遍历方法取出每一个匹配对象的值.
  Execute方法返回的集合对象mh,有两个属性:
  1)Count:      Execute方法成功匹配的次数,也可理解为mh集合对象中包含的成功匹配对象的个数.语法:
      N=mh.count   本例中n值为2
  2)Item: 索引,可以通过索引值,返回集合对象中指定的匹配对象.语法:
      Set mhk=mh.item(0)
      K=mhk.value
  用索引返回第一个Match对象即mhk. 本例中k为第一个Match对象的值(iphone_5s). 同样的方法可以得到第二匹配的值.
   由于ItemValue属性是集合的默认属性,所以上面两个语句也可简写为:
      K=mh(0)......第一个匹配对象的值(iphone_5s)
               M=mh(1)...........第二个匹配对象的值(Nokia_1020)
  上面代码中遍历集合也可以用索引法遍历:
  For i=0 to mh.count-1
    Debug.print mh(i).value
  Next i
<2>Match对象的属性
  Execute方法返回的集合对象中包含的也是对象元素,match对象,match对象有四个属性:
  FirstIndex:匹配对象所匹配字符串的起始位置。
  Length:匹配对象所匹配字符串的字符长度。
  SubMatches:匹配对象所匹配结果中的子项集合。
  Value:匹配对象所匹配的值。
  在本例中:索引为0,即第一个匹配对象的属性值为:
  K=mh(0).value   k的值为iphone_5s,value是默认属性可简写为k=mh(0)
  sn=Mh(0).firsindex   sn的值为3,表示在目标字符串中,位置3上找到该匹配iphone_5s.(位置是从0开始的)
  Ln=mh(0).length   ln值为9,iphone_5s的字符长度



评分

8

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-6-11 09:25 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-6-11 09:31 | 显示全部楼层
本帖最后由 liu-aguang 于 2014-6-12 08:43 编辑

<3>Match对象的Submatches属性  
  匹配对象match的Submatches是一个集合属性,它包含正则表达式中用圆括号捕捉到的所有子匹配.它为用户提供了返回$1特殊变量值的方法.

  集合Submatches有两个固有属性:Count和Item.可以通过Item得到集合中的每个值,它实际就是在正则表达式中用圆括号捕获的内容;Count值是集合中元素个数,实际上就是正则表达式中捕获性圆括号的个数.
下面给一个实例来说明:
   目标文本:给定一个标准邮箱地址:J3721@163.com
   要求:从邮箱中分别提取出:用户名j3721,服务器域名163.com
   正则表达式:  ^(\w+)@(.+)$
   代码:
Sub test5()
     Dim reg, mh, strA$, username$, domname$
     strA = "J3721@163.com"
     Set reg = CreateObject("vbscript.regexp")
     reg.Pattern = "^(\w+)@(.+)$"
     Set mh = reg.Execute(strA)
     N=mh(0).submatches.count         ‘n值等于2
     username = mh(0).submatches(0)    ‘j3721
     domname = mh(0).submatches(1)    ‘163.com
End Sub
讨论:
   正则表达式中,\w+表示匹配@前面的所有英文单词字符;@后面的点号是一个元字符,表示匹配除换行符外的所有字符之一,后面紧跟+,”.+”表示匹配@后面除了换行符外的所有字符.用括号包围起来,用户名和域名就会自动分别保存在变量$1$2.
   前面已经知道VBA不能在replace之外直接调用$1$2,而这个例子告诉我们可以用match对象的submatches集合属性来提取.
   在这个例子中,execute方法返回的集合对象mh,mh中只有一个匹配对象Match,mh(0);mh(0)对象的属性submatches(0),返回第一个括号中的内容,j3721.submatches(1),返回第二个括号中的内容.submathches集合也有count属性,所以如果有很多子项需要提取,也可用遍历或索引方法返回每一个特殊变量值.最后再给一例子:
   下面的代码演示了如何从一个正则表达式获得一个 SubMatches 集合以及它的专有成员:
  正则表达式(一个邮箱地址):
   (\w+)@(\w+)\.(\w+)
   如果你没有进一步了解元字符,可能不懂其中含义,不过没关系,在这里你只要知道,该代码的任务是显示电子邮箱dragon@xyzzy.com,用户名和组织名.
Function SubMatchTest(inpStr)
  Dim oRe, oMatch, oMatches
  Set oRe = New RegExp
  ' 查找一个电子邮件地址
  oRe.Pattern = "(\w+)@(\w+)\.(\w+)"
  ' 得到 Matches 集合
  Set oMatches = oRe.Execute(inpStr)
  ' 得到 Matches 集合中的第一项
  Set oMatch = oMatches(0)
  ' 创建结果字符串。
  ' Match 对象是完整匹配 dragon@xyzzy.com
  retStr = "电子邮件地址是: " & oMatch & vbNewline
  ' 得到地址的子匹配部分。
  retStr = retStr & "电子邮件别名是: " & oMatch.SubMatches(0)   ' dragon
  retStr = retStr & vbNewline
  retStr = retStr & "组织是: " & oMatch. SubMatches(1)          ' xyzzy
  SubMatchTest = retStr
End Function
Sub SubMatchesTest()
   MsgBox(SubMatchTest("请写信到 dragon@xyzzy.com 谢谢!"))
End Sub

捕获7.PNG


评分

7

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-6-11 10:27 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
liu-aguang 发表于 2014-6-11 09:31
Match对象的Submatches属性  匹配对象match的Submatches是一个集合属性,它包含正则表达式中用圆括号中捕捉到 ...

好帖,收藏,谢谢分享!

TA的精华主题

TA的得分主题

发表于 2014-6-11 10:39 | 显示全部楼层
liu-aguang 发表于 2014-6-11 09:31
Match对象的Submatches属性  匹配对象match的Submatches是一个集合属性,它包含正则表达式中用圆括号中捕捉到 ...

非常好的教程,收藏学习。谢谢分享

TA的精华主题

TA的得分主题

发表于 2014-6-11 11:13 | 显示全部楼层
本帖最后由 香川群子 于 2014-6-11 15:19 编辑

如果知道一点英文,理解记忆会更快。

\w
→ word 首字母 w
表示26个英文字符【A-Za-z】以及下划线【_】和数字【0-9】的集合,
.Pattern ="\w" 等价于 .Pattern ="[0-9a-z_A-Z]"

其中有英文字符很好理解,因为英语中的word肯定是由英文字母构成的。
另外,在VBA编程中,变量还可以含有数字和下划线,因此数字和下划线也被当做构成统一word的要素。

除此之外的其它字符,都不算构成word的要素了。


…………

\d
→ digit 首字母 d
表示数字【0-9】的集合,
.Pattern ="\d" 等价于 .Pattern ="[0-9]"


…………

\s
→ separate 首字母 s   或space、tab、return简称str字符的首字母。
表示分隔符号 含space 空格【 】或【char(32)】、回车vbCr【char(13)】、换行vbLf【char(10)】、vbTab【char(9)】等,
全部ASCII码值为: char(9)、char(10)、char(11)、char(12)、char(13)、char(32)(空格)

分隔符号的单独分开是\t   tab 首字母  vbTab【chr(9)】或 其反集 \T  

\v   verticaltab 首字母  vbVerticalTab【chr(11)】或 其反集 \V  

\f   formfeed 首字母  vbFormFeed【chr(12)】或 其反集 \F

\r   回车 return 首字母 r 而在VBA中对应的是:vbCr【chr(13)】或 其反集 \R   (Cr是Carriage Return的简称,是机械式打字机时代,字车carriage回复return 到最左边开始的意思 )
     苹果机(MAC OS系统) 采用回车符Cr 表示下一行.

\n   换行 newline 首字母n  vbLf【chr(10)】或 其反集 \N
   (Lf是Line Feed的简称,是机械式打字机时代,回车的同时自动滚进一行的意思 )
     UNIX/Linux系统采用 换行符Lf 表示下一行.

\r\n 回车换行  vbCrLf【chr(13) & chr(10)】
     Dos和windows系统 采用 回车+换行CrLf 表示下一行,


=================

接下来介绍,对上述几个常用元序列/集合,使用小写字母时是有效,含有的意思,
而使用大写字母时是无效,排除(不含有)的意思,

如:

\W → word 首字母 大写 W 标记的【英文字母、数字、下划线】的序列/集合的反集

小写字母w .Pattern ="\w" 等价于 .Pattern ="[0-9a-z_A-Z]"

大写字母W .Pattern ="\W" 等价于 .Pattern ="[^0-9a-z_A-Z]"


2.

\D → digit 首字母 大写 D 标记的【数字】的序列/集合的反集

小写字母d .Pattern ="\d" 等价于 .Pattern ="[0-9]"

大写字母D .Pattern ="\D" 等价于 .Pattern ="[^0-9]"


3.

\S → separate 首字母 大写 S 标记的不可见换行字符的序列/集合的反集

小写字母s .Pattern ="\s" 等价于 含有char 9,10,11,12,13,32

大写字母S .Pattern ="\S" 等价于 含有char 9,10,11,12,13,32


=======
以上




评分

20

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-6-11 11:26 | 显示全部楼层
本帖最后由 香川群子 于 2014-6-11 11:33 编辑

\b 和 \B

begin 的首字母 b

意义: 以上述\s separate 集合分隔后得到的每一个 \w word 中的第1个begin字符。

如:
abe sau
dty12 f_34

执行小写字母b .Pattern ="\b." 则得到每一个word的首字母:a s d f

=====

执行大写字母B .Pattern ="\B." 则得到每一个word的首字母以外的字符:b e a u t y 1 2 _ 3 4


====
以上。

补充,该规则仅对英文word能100%正确作用。
如果对象字符集中出现\W字符即非英文数字下划线字符,如汉字或其他符号,
则可能会返回不可预知的结果。(因为汉字等其它词汇无法像英文那样简单区分word和word之间的间隔。)
(如同Vlookup函数中搜寻数组中没有正确A-Z排序时可能返回不可预知结果一样。)


评分

5

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-6-11 11:33 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2014-6-11 11:26
\b 和 \B

begin 的首字母 b

谢谢香川君的讲解!

TA的精华主题

TA的得分主题

发表于 2014-6-11 11:43 | 显示全部楼层
顺便介绍一下我写的 正则结果模拟用 自定义函数:
http://club.excelhome.net/thread-1088768-1-1.html

RegExp.zip

14.56 KB, 下载次数: 1388

评分

7

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-6-11 12:01 | 显示全部楼层
不明觉厉,好好学习一下。谢谢楼主分享成果~
我就想搞懂几件事情
1.什么是正则
2.有什么用
3.怎么用
等学习完有问题再请教楼主~
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-25 15:33 , Processed in 0.048203 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表