本文转载自公众号:完美Excel,作者:fanjy。 excelperfect 正则表达式(RegEx)是一系列字符,定义搜索模式,用于查找字符串中特定的字符模式。 VBA正则表达式的语法与其他语言(如Python)中使用的语法有较大的区别,主要是因为VBA的RegEx对象带有可选参数,因此有时必须指定这些参数以获得与在其他语言中使用标准的正则表达式语法相同的结果。 VBA正则表达式语法基础 正则表达式搜索模式是由一个或多个下列元素组成的字符序列: 文字字符。文字字符只是匹配输入文本中的对应字符,例如搜索模式中的文字字符序列"xyz"将简单地与输入文本中所有出现的"xyz"相匹配。 元字符。元字符更抽象些,看下面的介绍。 元字符 元字符是字符或字符组合,在正则表达式模式中具有特殊含义。元字符可以匹配输入文本中的几个不同字符,甚至可以表示字符以外的其他字符。下面是需要熟练掌握的一些元字符。 . 通配符。未转义的句点匹配任意字符,但新行除外。 ^ "字符串或者行的开头"或"否定"。插入符号在搜索模式中的重要性取决于上下文。1)如果在VBA中将参数MultiLine设置为True,则插入符号表示"行首",而不是"字符串的开头"。2)如果插入符号放在一个字符类[^]中,它就像一个否定,即"匹配与字符类的其他参数不匹配的所有字符。" $ "字符串的结尾。"搜索模式中美元符号的重要性取决于上下文。如果在VBA中将参数MultiLine设置为True,则美元符号表示"行尾",而不是"字符串结尾"。 "转义字符。" 元字符前面的反斜杠将其转换为文字字符。 "字边界"或"退格字符"。在字符类的外面,匹配文本源中单词之前或之后的位置。在字符类中,表示退格符。 B "不是一个字边界。"B是的否定,但在字符类中没有替代含义。 d "数字。"匹配从0至9的任意数字。 D "非数字。"匹配不是数字的任意字符。 s "空白"。匹配空格、换行符或制表符。 S "非空白。"匹配不是空格、换行符或制表符的字符。 字符^、$和称为锚点,因为它们匹配字符之前、之后或之间的位置。 操作符 一些元字符改变了如何解释搜索模式中的一个或多个其他元素,例如,它们对这些其他元素执行操作。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] 范围从a到z的小写字母集。 [A-Z] 范围从A到Z的大写字母集。 [0-9] 范围从0到9的单个数字集。 字符类经常与搜索模式中的运算符一起使用。例如,[0-5] 转换为"找到一个或多个数字",而不是仅从0到5的单个数字。 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 strInput = "在这个字符串中包含邮件地址,"Mary-Jo.T.Williamson_01 test@test-site.com"." 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 CallRegEx过程将调用自定义的RegEx函数。在CallRegEx过程中,在变量strInput中指定输入文本,在变量strPattern中定义了搜索模式。代码中,输入文本包含一个假定电子邮件地址的字符串,其中包含有效电子邮件地址中允许的所有字符类型(允许 号)。无论在输入文本中如何重新排列该电子邮件地址,自定义函数RegEx都会找到它并将其返回,前提条件是,你要传递正确的参数。 在RegEx函数中前两个参数是刚才讨论的输入字符串和搜索模式变量,这些参数是必需的,而接下来的三个参数可选: 参数Global,布尔型。如果设置为True,返回所有的匹配。如果设置为False,仅返回第一个匹配。默认值为False。 参数lgnoreCase,布尔型。如果设置为True,匹配模式不区分大小写。默认值为False,即区分大小写。 参数MultiLine,布尔型。如果设置为True,则会改变搜索模式中^("字符串开头")和$("字符串结尾")元字符的解析,以便它们匹配行的开头和结尾。默认值为False。 在CallRegEx过程中,设置参数GlobalSearch为False,但是如果我们将其设置为True并且在输入文本中有多个电子邮件地址,那么它们将全部返回到匹配集合中。可选参数IgnoreCase设置为True,否则搜索模式会变长: [a-zA-Z0-9-. _] @[a-zA-Z-] .[a-zA-Z] 上面模式中括号内的项目表示字符集,后面跟着的加号是量词,用于指定要查找字符的数量。中间的"@"字符表示搜索该字符,两对双括号中的点被反斜杠转义,表示搜索文本中的点。 从左至右阅读上述模式,其表达的意思如下: 查找一个或者多个从a到z的小写字母或大写字母、从0到9的数字、连字符(-)、点(.)、加号( )或下划线(_) 并查找 "@"符号 并查找 一个或者多个从a到z的小写字母或大写字母,或连字符(-) 并查找 "."号 并查找 一个或者多个从a到z的小写字母或大写字母 如果满足所有条件并且输入的字符串中的所有匹配字符是连续的且顺序正确,那么RegEx函数将返回匹配的结果。这意味着,如果搜索模式中含有空白字符,将从根本上改变其意义。如果你错误地在搜索模式中包含了空白字符,那么RexEx将在你指定的其他字符中查找空格。 小结 正则表达式常用于"查找和替换",其中替换功能使用RegEx对象的Replace方法。你可以使用VBA正则表达式进行各种高级文本处理,包括: 查找 查找和替换 验证用户输入。例如,你可以使用RegEx函数验证密码或电子邮件地址。 查找和删除重复的词语。大多数文本处理软件,如MS Word,可以查找出现的重复词语,但如果手动删除重复词语则太费时间,而RegEx函数就能够解决。 本地化。如果你需要将文本翻译另一种语言,两种语言的日期和数字格式可能会有所不同,例如,如果输入文本包含数千个数字,那么编写RegEx算法将是非常有用的,而不是手动编辑。 虽然RegEx有很多非常好的应用场合,但是也有一些不应该使用的情形: 现有功能已经能够完成的工作。VBA RegEx非常强大,因为它允许你从输入文本中精确提取所需要的信息,但是如果Excel函数和运算符,例如Like、Find或Replace,可以完成这些工作,那就无需再使用RegEx了。 在使用RegEx解析html之前请多考虑一下。确实,如果足够幸运,可以得到你想要的结果,但大多数情况下都可能得到一些无法正确修复的奇怪错误。如果发生这种情况,唯一可靠的解决方案是弃用RegEx,重构代码。 本文学习整理自wellsr.com。欢迎分享本文,转载请注明出处。