1 正则表达式
1.1 RegExp 对象
正则表达式提供了强大的字符匹配和替换功能。
RegExp
对象是 VBScript 中用于提供简单的正则表达式支持的对象。 VBScript 中所有和正则表达式有关的属性和方法都与这个对象有关联。
Dim re
Set re = New RegExp
这个对象有三个属性和三个方法
1.1.1 Global 属性
Global
属性负责设置或返回一个Boolean
值,指明模式是匹配整个字符串中所有与之相符的地方还是只匹配第一次出现的地方- 有两个可能的值:
True
和False
- 如果 Global 属性的值是 True,那就会对整个字符串进行查找;否则就不会。默认值是 False
1.1.2 IgnoreCase 属性
- 有两个可能的值: True 和 False
- 如果 IgnoreCase 属性的值为 False,搜索为大小写敏感;如果是 True,则不是。默认是 False
1.1.3 Pattern 属性
Pattern
属性设置或返回用于搜索的正则表达式- 需要搜索的正则字符串表达式。可能含有一些正则表达式字符—— 可选的
Dim re, s
Set re = New RegExp
re.Pattern = "\bin"
re.Global = True
s = "The rain In Spain falls mainly on the plains."
MsgBox re.Replace(s, "in the country of")
1.1.4 正则表达式字符
大写特殊字符的作用与相应的小写特殊字符的作用相反
字符 | 描述 |
---|---|
\ | 表示下一个字符是特殊字符或文字常量 |
^ | 匹配输入的开头 |
$ | 匹配输入的结尾 |
* | 匹配前一个字符零次或多次 |
+ | 匹配前一个字符一次或多次 |
? | 匹配前一个字符零次或一次 |
. | 匹配除换行符以外的任何单个字符 |
(pattern) | 匹配并记住这个模式。可以用[0]…[n]从结果的 matches 集合中获取匹配到的字符串。要匹配括号本身,在前面加上斜杠—— 用"(“或”)" |
(?:pattern) | 匹配但不捕获模式,也就是不会存储匹配结果供以后使用。这可以用于使用"or"字符( |
(?=pattern) | 当所要搜索的字符串匹配了模式的开头部分时就接着匹配这一部分。这是一个非捕获匹配,也就是说不会保存匹配结果供以后使用。例如, "Windows(?=95 |
(?!pattern) | 与上一个相反,这会匹配模式中没有出现的内容。这是一个非捕获匹配,也就是说不会保存匹配结果供以后使用。例如, "Windows(?=95 |
x|y | 匹配 x 或 y |
{n} | 准确地匹配 n 次(n 必须是一个非负整数) |
{n,} | 至少匹配 n 次(n 必须是一个非负整数—— 注意结尾的逗号) |
{n,m} | 至少匹配 n 次,最多匹配 m 次(m 和 n 必须都是非负整数) |
[xyz] | 匹配其中包括的任一个字符(xyz 表示一个字符集) |
[^xyz] | 匹配其中不包括的字符(^xyz 表示一个字符集的补集) |
[a-z] | 匹配指定范围内的字符(a-z 表示字符的范围) |
\b | 匹配一个单词边界,这个位置在单词和空格之间 |
\B | 匹配一个非单词边界 |
\d | 匹配数字。等价于[0-9] |
\D | 匹配非数字。等价于[^0-9] |
\f | 匹配换页符 |
\n | 匹配换行符 |
\r | 匹配回车符 |
\s | 匹配空白,包括空格、制表符、换页符等。等价于"[\f \n \r \t \v ]" |
\S | 匹配非空白的字符。等价于"[^\f \n \r \t \v ]" |
\t | 匹配制表符 |
\v | 匹配纵向制表符 |
\w | 匹配字母、数字,以及下划线。等价于"[A-Za-z0-9_]" |
\W | 匹配非字符数字。等价于"[^A-Za-z0-9_]" |
\. | 匹配点. |
\ | | 匹配| |
\{ | 匹配{ |
\} | 匹配} |
\\ | 匹配\ |
\[ | 匹配[ |
\] | 匹配] |
\( | 匹配( |
\) | 匹配) |
$ num | 匹配 num,其中 num 是正整数。返回匹配结果的引用 |
\n | 匹配 n,其中 n 是八进制转义符。八进制转义符的长度应为 1、 2 或 3 |
\uxxxx | 匹配 UNICODE 形式的 ASCII 字符 |
\xn | 匹配 n,其中 n 是十六进制转义符。十六进制转义符必须是两位长度 |
1.1.4.1锚定和缩短模式
- 有三种特殊字符用于锚定模式。它们本身不匹配任何字符,但是可以要求另一个模式必须出现在输入的开头(
在[]外使用^
)、输入的结尾($
)或是单词边界(\b
)。 - 缩短模式的方法是使用
重复数
。基本的思路就是在模式后面指定重复的次数。
1.1.4.2 指定匹配的范围或最小次数
还可以指定匹配的最小次数{min}
或范围{min, max,}
。其中一些常用的重复模式也有专门的快捷方式
re.Pattern = "\d+" 'one or more digits, \d{1, }
re.Pattern = "\d*" 'zero or more digits, \d{0, }
re.Pattern = "\d?" 'optional: zero or one, \d{0,1}
1.1.4.3 记住匹配结果
如果要在用于替换的文本中使用部分或全部的匹配结果,这就很有用。为了验证这一点,也为了将所有关于特殊字符的讨论集中在一起,我们来做点有实际意义的事情。搜索一个字符串,查找其中的 URL。为了控制这个例子的复杂度和规模,这里只查找其中的"http:"协议,但是您还可以处理各种 DNS 域名,包括无限的域名层次。不要担心如何与 DNS 交流,只需要知道在浏览器中输入 URL 就足够了。
Dim re, s
Set re = New RegExp
re.Global = True
re.Pattern = "http://(\w+[\w-]*\w+\.)*\w+"
s = "http://www.kingsley-hughes.com is a valid web address. And so is "
s = s & vbCrLf & "http://www.wrox.com. And "
s = s & vbCrLf & "http://www.pc.ibm.com - even with 4 levels."
Set colMatches = re.Execute(s)
For Each match In colMatchesMsgBox "Found valid URL: " & match.Value
Next
- 模式以固定的字符串
http://
开头。然后用圆括号将模式的主要部分括起来。re.Pattern = "http://(\ w[ \ w-]* \ w \ . )*\w+"
,这个模式以一个特殊字符\w
开头,用来匹配[a-zA-Z0-9]
,也就是英语中的所有数字和字母。 - 用括号匹配字母数字或横杠,因为 DNS 中可以有横杠。有效的 DNS 不能以横杠开始或结尾。然后用
*
重复匹配 0 个或多个字符re.Pattern = "http://(\w [ \ w-]* \w\..*\w+"
- 然后又严格地用字母数字,这样域名就不会以横杠结束。括号中的最后一个模式匹配用于分割 DNS 层次的点(.)。不能单独使用点,因为那是一个特殊字符,正常情况下能匹配除换行符以外的任何字符。可以用反斜杠转义这个字符。
- 在将这些东西封装到括号中之后,只需要继续使用
*
重复这个模式即可。re.Pattern = "http:// ( \ w[ \ w-]*\w\ .)*\w+"
- 模式最后是顶级域名(比如 com、 org、 edu 等)所需的一个或多个字符。
re.Pattern = "http://(\w[\w-]*\w\.)*\ w+ "
1.1.5 Execute 方法
这个方法将正则表达式应用到字符串上并返回Matches
集合。这是代码中使用模式匹配字符串的启动开关
1.1.6 Replace 方法
这个方法用于替换在正则表达式搜索中找到的文本
Replace
方法返回一份 RegExp.Pattern 被 string2 替换后的 string1 的副本。如果字符串中没有发生匹配,那么就会返回没有任何改变的 string1
1.1.7 Backreferencing
- 一个被记住的匹配结果就是模式的一部分。这就是所谓的
backreferencing
。需要用圆括号指定需要存储在临时缓存中的部分。 - 每个捕获到的匹配结果都会按匹配到的先后次序存放(在正则表达式模式中
从左到右
)。存放匹配结果的缓存从1
开始编号,最大可以到99
。可以依次用$1
、$2
之类的变量访问它们。 - 可以用非捕获元字符("?:"、 “?=“或”?!”)跳过正则表达式中的某些部分
0
代表本身
接下来的例子,前 5 个单词(由一个或多个非空白字符组成)会被记住,然后只有其中的4 个会出现在替换文本中:
Dim re, s
Set re = New RegExp
re.Pattern = "(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)"
s = "VBScript is not very cool."
MsgBox re.Replace(s, "$1 $2 $4 $5")
1.1.8 Test 方法
Test 方法对字符串执行正则表达式搜索,并返回一个布尔值说明匹配是否成功
1.2 Matches 集合
Matches
集合含有正则表达式的 Match 对象。- 只有使用 RegExp 对象的
Execute
方法才能创建这个集合。要记住 Matches 集合的属性跟独立的 Match 对象的属性一样,都是只读的。
当一个正则表达式被执行时,会产生0 个或多个
Match 对象。每个 Match 对象提供以下三个内容: - 正则表达式所找到的字符串
- 字符串的长度
- 指向找到该匹配的位置的索引
要记得将 Global 属性设为 True ,否则您的 Matches 集合中最多也只会有一个成员。这种方法很简单,但是很难调试
1.2.1 Matches 的属性
Matches 是一个简单的集合,只有两个属性:
Count
返回集合中的元素数量。Item
根据指定的键返回元素
1.2.2 Match 对象
Match对象
是Matches
集合中的成员。创建 Match 对象的唯一方法就是使用 RegExp 对象的Execute
方法。当一个正则表达式被执行时会产生 0 个或多个 Match 对象。每个 Match对象提供以下内容:
- 正则表达式所找到的字符串
- 字符串的长度
- 指向找到该匹配的位置的索引
Match
的三个属性都是只读的:FirstIndex
、Length
以及Value
1.2.2.1 FirstIndex 属性
FirstIndex 属性返回匹配结果在字符串中的位置
FirstIndex 属性从 0 开始对被搜索的字符串编号。换句话说就是字符串中的第一个字符就是字符 0
1.2.2.2 Length 属性
Length 属性返回在字符串中找到的匹配的长度
1.2.2.3 Value 属性
Value 属性返回在字符串中找到的匹配结果的值或文本
1.3 一些例子
1.3.1 验证电话号码输入
格式是(XXX) XXX-XXXX
Dim re, s, objMatch, colMatches
Set re = New RegExpre.Pattern = "\([0-9]{3}\[0-9]{3}-[0-9]{4}"
re.Global = True
re.IgnoreCase = True
s = InputBox("Enter your phone number in the following Format (XXX) XXX-XXXX:")
If re.Test(s) Then
MsgBox "Thank you!"
Else
MsgBox "Sorry but that number is not in a valid format."
End If
1.3.2 分解 URI
这个例子用来将统一资源定位器(Universal Resource Indicator
, URI
)分解成多个部分。
比如下面这个 URI:www.wrox.com:80/misc-pages/support.shtml
Dim re, s Set
re = New RegExp
re.Pattern = "(\w+):\ / \ /( [^ /:]+)(:\d*)?( [^ # ]*)"
re.Global = True
re.IgnoreCase = True
s = "http://www.wrox.com:80/misc-pages/support.shtml"
MsgBox re.Replace(s, "$1")
MsgBox re.Replace(s, "$2")
MsgBox re.Replace(s, "$3")
MsgBox re.Replace(s, "$4")
1.3.3 检查 HTML 元素
检查 HTML 元素很简单,需要的只是一个正确的模式。下面这个就能检查元素开始和结
束标签。"<(.*)>.*<\/\1>"
如何编写脚本取决于您想要实现什么功能。这个简单的脚本只是一个演示。可以改进这
段代码专门用于检查某种元素,或是实现基本的错误检查。
Dim re, s
Set re = New RegExpre.IgnoreCase = True
re.Pattern = "<(.*)>.*<\ / \1>"
s = "<p>This is a paragraph</p>"
If re.Test(s) Then
MsgBox "HTML element found."
Else
MsgBox "No HTML element found."
End If
1.3.4 匹配空白
有时可能真的需要匹配空白,也就是空行或是只有空白(空格和制表符)的行。下面的
模式可以满足这个需求。"^[ \t]*$"
说明如下:
^
—— 匹配每一行的开头。[ \t]*
—— 匹配 0 个或多个空格或制表符(\t)。$
—— 匹配行结尾。
Dim re, s, colMatches, objMatch, sMsg
Set re = New RegExp
re.Global = True re.Pattern = "^[ \t]*$"
s = " "
Set colMatches = re.Execute(s)
sMsg = ""
For Each objMatch in colMatches
sMsg = sMsg & "Blank line found at position " & _
objMatch.FirstIndex & " of the string."Next
MsgBox sMsg
1.3.5 匹配 HTML 注释标签
正则表达式的一个应用就是查找HTML 文件中的注释标签。可以在将其发布到网络之前将其中的注释清除。
这个脚本可以检查 HTML 注释标签。
Dim re, s
Set re = New RegExp
re.Global = True
re.Pattern = "^.*<!--.*-->.*$"
s = " <title>A Title</title> <!-- a title tag -->"
If re.Test(s) Then
MsgBox "HTML comment tags found."
Else
MsgBox "No HTML comment tags found."
End If
对该模式稍作修改,并使用 Replace 方法就能将脚本中的注释清除。
Dim re, s
Set re = New RegExp
re.Global = True
re.Pattern = "(^.*)(<!--.*-->)(.*$)"
s = " <title>A Title</title> <!-- a title tag -->"
If re.Test(s) Then
MsgBox "HTML comment tags found."
Else
MsgBox "No HTML comment tags found."
End If
MsgBox re.Replace(s, "$1" & "$3")