基础扩展 | 08. VBA正则表达式

Posted 完美Excel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础扩展 | 08. VBA正则表达式相关的知识,希望对你有一定的参考价值。

excelperfect

 

正则表达式(RegEx)是一系列字符,定义搜索模式,用于查找字符串中特定的字符模式。

 

VBA正则表达式的语法与其他语言(如Python)中使用的语法有较大的区别,主要是因为VBARegEx对象带有可选参数,因此有时必须指定这些参数以获得与在其他语言中使用标准的正则表达式语法相同的结果。

 

VBA正则表达式语法基础

正则表达式搜索模式是由一个或多个下列元素组成的字符序列:

  • 文字字符。文字字符只是匹配输入文本中的对应字符,例如搜索模式中的文字字符序列“xyz”将简单地与输入文本中所有出现的“xyz”相匹配。

  • 元字符。元字符更抽象些,看下面的介绍。

 

元字符

元字符是字符或字符组合,在正则表达式模式中具有特殊含义。元字符可以匹配输入文本中的几个不同字符,甚至可以表示字符以外的其他字符。下面是需要熟练掌握的一些元字符。

 

.

通配符。未转义的句点匹配任意字符,但新行除外。

 

^

“字符串或者行的开头”或“否定”。插入符号在搜索模式中的重要性取决于上下文。1)如果在VBA中将参数MultiLine设置为True,则插入符号表示“行首”,而不是“字符串的开头”。2)如果插入符号放在一个字符类[^]中,它就像一个否定,即“匹配与字符类的其他参数不匹配的所有字符。”

 

$

“字符串的结尾。”搜索模式中美元符号的重要性取决于上下文。如果在VBA中将参数MultiLine设置为True,则美元符号表示“行尾”,而不是“字符串结尾”。

 

\

“转义字符。” 元字符前面的反斜杠将其转换为文字字符。

 

\b

“字边界”或“退格字符”。在字符类的外面,\b匹配文本源中单词之前或之后的位置。在字符类中,\b表示退格符。

 

\B

“不是一个字边界。”\B\b的否定,但在字符类中没有替代含义。

 

\d

“数字。”匹配从09的任意数字。

 

\D

“非数字。”匹配不是数字的任意字符。

 

\s

“空白”。匹配空格、换行符或制表符。

 

\S

“非空白。”匹配不是空格、换行符或制表符的字符。

 

字符^$\b称为锚点,因为它们匹配字符之前、之后或之间的位置。

操作符

一些元字符改变了如何解释搜索模式中的一个或多个其他元素,例如,它们对这些其他元素执行操作。VBA正则表达式具有三种类型的运算符。

 

布尔运算“或”

元字符:|

说明:表示布尔“或”运算符

示例:a|b匹配“a”或“b

 

分组

元字符:()

说明:括号用于下列目的:1)定义运算符的范围和优先级;2)对字符进行分组并记住文本。

示例:h(a|e)y匹配“hay”或“hey

 

量化

元字符:?

说明:前一个元素出现0次或1次。

示例:colou?r匹配“color”和“colour

 

元字符:*

说明:前一个元素出现0次或多次。

示例:ab*c匹配“ac”、“abc”、“abbc”、“abbbc”,等等

 

元字符:+

说明:前一个元素出现1次或多次。

示例:ab+c匹配“abc”、“abbc”、“abbbc”,等等,但不匹配“ac

 

元字符:{n}

说明:前面的项目恰好匹配n次。

示例:a{3}匹配“aaa

 

元字符:{min,}

说明:前面的项目匹配min次或更多次。

示例:a{1,}匹配“a”、“aa”、“aaa”,等等

 

元字符:{min,max}

说明:前面的项目匹配至少min次,但不多于max次。

示例:a{1,3}匹配“a”、“aa”和“aaa”,但不匹配“aaaa

 

字符类

字符类或字符集使用方括号[]指定,一些最常见的如下:

 

[a-z]

范围从az的小写字母集。

 

[A-Z]

范围从AZ的大写字母集。

 

[0-9]

范围从09的单个数字集。

 

字符类经常与搜索模式中的运算符一起使用。例如,[0-5] +转换为“找到一个或多个数字”,而不是仅从05的单个数字。

 

VBARegEx函数

VBE菜单栏中,选取“工具——引用”命令,在“引用”对话框中找到并选取“Microsoft VBScript Regular Expressions 5.5”复选框,如下图1所示。

1

 

插入一个标准模块并输入下面的代码:

Sub CallRegEx()

    Dim r As Match

    Dim mcolResults As MatchCollection

    Dim strInput As String

    Dim strPattern As String

   

    strPattern ="[a-z0-9-.+_]+@[a-z-]+\.[a-z]+"

   

    Set mcolResults = RegEx(strInput,strPattern, , , True)

   

    If Not mcolResults Is Nothing Then

        For Each r In mcolResults

            Debug.Print r

        Next r

    End If

End Sub

 

Function RegEx(strInput AsString, strPattern As String, _

    Optional GlobalSearch As Boolean, OptionalMultiLine As Boolean, _

    Optional IgnoreCase As Boolean) AsMatchCollection

   

    Dim mcolResults As MatchCollection

    Dim objRegEx As New RegExp

   

    If strPattern <> vbNullString Then

        With objRegEx

            .Global = GlobalSearch

            .MultiLine = MultiLine

            .IgnoreCase = IgnoreCase

            .Pattern = strPattern

        End With

       

        If objRegEx.Test(strInput) Then

            Set mcolResults =objRegEx.Execute(strInput)

            Set RegEx = mcolResults

        End If

    End If

End Function

 

RegEx函数中前两个参数是刚才讨论的输入字符串和搜索模式变量,这些参数是必需的,而接下来的三个参数可选:

  • 参数Global,布尔型。如果设置为True,返回所有的匹配。如果设置为False,仅返回第一个匹配。默认值为False

  • 参数lgnoreCase,布尔型。如果设置为True,匹配模式不区分大小写。默认值为False,即区分大小写。

  • 参数MultiLine,布尔型。如果设置为True,则会改变搜索模式中^(“字符串开头”)和$(“字符串结尾”)元字符的解析,以便它们匹配行的开头和结尾。默认值为False

 

[a-zA-Z0-9-.+_]+@[a-zA-Z-]+\.[a-zA-Z]+

 

上面模式中括号内的项目表示字符集,后面跟着的加号是量词,用于指定要查找字符的数量。中间的“@”字符表示搜索该字符,两对双括号中的点被反斜杠转义,表示搜索文本中的点。

 

从左至右阅读上述模式,其表达的意思如下:

查找一个或者多个从az的小写字母或大写字母、从09的数字、连字符(-)、点(.)、加号(+)或下划线(_)

并查找

@”符号

并查找

一个或者多个从az的小写字母或大写字母,或连字符(-)

并查找

.”号

并查找

一个或者多个从az的小写字母或大写字母

 

如果满足所有条件并且输入的字符串中的所有匹配字符是连续的且顺序正确,那么RegEx函数将返回匹配的结果。这意味着,如果搜索模式中含有空白字符,将从根本上改变其意义。如果你错误地在搜索模式中包含了空白字符,那么RexEx将在你指定的其他字符中查找空格。

 

小结

正则表达式常用于“查找和替换”,其中替换功能使用RegEx对象的Replace方法。你可以使用VBA正则表达式进行各种高级文本处理,包括:

  • 查找

  • 查找和替换

  • 查找和删除重复的词语。大多数文本处理软件,如MS Word,可以查找出现的重复词语,但如果手动删除重复词语则太费时间,而RegEx函数就能够解决。

  • 本地化。如果你需要将文本翻译另一种语言,两种语言的日期和数字格式可能会有所不同,例如,如果输入文本包含数千个数字,那么编写RegEx算法将是非常有用的,而不是手动编辑。

 

虽然RegEx有很多非常好的应用场合,但是也有一些不应该使用的情形:

  • 现有功能已经能够完成的工作。VBA RegEx非常强大,因为它允许你从输入文本中精确提取所需要的信息,但是如果Excel函数和运算符,例如LikeFindReplace,可以完成这些工作,那就无需再使用RegEx了。

  • 在使用RegEx解析html之前请多考虑一下。确实,如果足够幸运,可以得到你想要的结果,但大多数情况下都可能得到一些无法正确修复的奇怪错误。如果发生这种情况,唯一可靠的解决方案是弃用RegEx,重构代码。

 

本文学习整理自wellsr.com。欢迎分享本文,转载请注明出处。