在上一篇帖子当中我们介绍了XMLHTTP对象及方法获取网页中Table对应的网页字符串. 那么如何从这些字符串中获取我们想要的数据呢?在python或者java中这些会有对应的包和函数可以实现. 而本篇将会介绍一种简单而基础的方法: 正则表达式 (Regex).
3.正则表达式 (Regex):
正则表达式是一种用于匹配字符串中字符模式的工具, 它可以用来搜索、编辑和处理文本.
正则表达式的作用非常强大,详细的总结可以参考CSDN大佬的帖子:VBA学习笔记六:正则表达式.
下面我会总结用到的一些对象和方法:
3.1 创建正则表达式对象:
3.1.1 前期绑定:
添加引用库:工具 > 引用 >勾选 ’Microsoft VBScript Regular Expressions 5.5‘
'直接声明reg对象就可以使用'
Dim reg as New RegExp
3.1.2 后期绑定 (推荐使用):
使用 CreateObject 方法来创建 VBScript.RegExp
对象,便可使用
代码
'先声明再创建reg对象'
Dim reg As Object
Set reg = CreateObject("VBScript.RegExp")
3.2 用到的属性及方法:
3.2.1 Pattern 属性
• 描述:定义要匹配的正则表达式模式
• 示例:匹配任意四个字母的单词
reg.Pattern = "\b\w{4}\b"
3.2.2 Global 属性
• 描述:设置是否全局搜索匹配。默认为 False,只匹配第一个
• 示例:全局匹配所有符合模式的字符串
reg.Global = True
3.2.3 Execute 方法
• 描述:执行正则表达式匹配,查找所有符合匹配模式的子字符串,并返回一个匹配集合对象 (MatchCollection对象)
• 示例:查找匹配项,其中 string 是要搜索的字符串
Set matches = reg.Execute(string)
3.3 匹配规则 这里我照抄CSDN文章:
3.4 匹配结果的对象:
3.4.1 MatchCollection对象:
含义:是一个集合对象,包含了正则表达式在输入文本中找到的所有匹配项,每个匹配项都表示为一个 Match 对象.
用到的属性:
Item 属性
○ 功能:返回集合中第几个 Match
对象,从0开始计数
○ 用法:matches.Item(index)
或 matches(index)
○ 示例:输出第一个匹配到的对象
Set match = matches(0)
MsgBox "Found match: " & match.Value
3.4.2 Match对象:
含义:表示正则表达式匹配中的一个匹配项,包含匹配的文本和其他相关信息
用到的属性:
SubMatches 属性
○ 功能:返回一个 SubMatches
集合(注意这里返回了集合,因而适用MatchCollection对象的所有方法),包含所有捕获的子匹配项,通过索引访问捕获组的内容(索引从0开始)可以获取匹配到的分组内容
○ 前提:在正则表达式模式中使用了括号来创建捕获组 (参考3.3.>>>)
○ 用法:match.SubMatches(n)
*表示访问子匹配项第n+1个捕获组的内容,也就是表达式里面的第n+1个括号
*这里的语法也可以写成match.SubMatches.Item(n)
来表达同样的意思。
4.正则表达式应用实例:
4.1 代码及注释
Sub getrates(s As String)
Dim reg As Object, m As Object, mchs As Object
Dim i As Long, j As Long, p As String
Set reg = CreateObject("vbscript.regexp")'后期绑定创建regex'
'----regex'
p = "<tr>\s*<td.*><time.*>([^<]*)</time>\s*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>.*</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*<td.*>([^<]*)</td>\s*</tr>"
reg.pattern = p'3.2.1 pattern属性'
reg.Global = True'3.2.2 global属性'
Set mchs = reg.Execute(s)'3.2.3 execute方法'
i = 6
For Each m In mchs'3.4.1 MatchCollection对象'
For j = 0 To m.submatches.Count - 1
Cells(i, j + 1) = m.submatches.Item(j)
'利用3.4.2match对象的submatches属性去将捕获字符输出到单元格中'
Next j
i = i + 1
Next m
End Sub
4.2 正则表达式p
的写法:
这里我复制出来整个Table的字符串, 以第一行(<tr>...</tr>
为一行的字符串)为例, 用黄色标出来我想要的字符.
参照3.3匹配规则中的捕获组方法, 将需要输出的字符以()
包含进去,根据网页字符串的语法<tr>.*</tr>
和<td>.*</td>
做一些识别与中间内容的捕获, 作者就得到了如下的正则表达式.
5.总结:
作者所使用的方法基本可以分为两步:
第一步, 利用XMLHTTP对象先从网页中返回字符串;
第二步, 利用正则表达式的匹配及捕获funtion从字符串中返回需要的字符
6.杂谈:
本帖是作者应管理员珂珂之邀写的第一篇技术分享帖子, 谢邀~
但作者对本论坛的流量表示怀疑, 因为截止到作者写part 2时, part 1帖仅有两个浏览量, 其中一个还是作者本人贡献QAQ.
在此呼吁珂珂阿姨将论坛内容在公众号中做实时更新, 并祝愿珂珂阿姨做大做强, 再创辉煌~ 此致, 敬礼^.^-!