如何在Microsoft Excel中使用正则表达式(Regex)进行单元格内和循环操作

748

我该如何在Excel中使用正则表达式,并利用Excel强大的网格状设置进行数据操作?

  • 单元格函数可返回字符串中匹配的模式或替换后的值。
  • Sub循环遍历数据列并提取匹配到相邻单元格中的内容。
  • 需要哪些设置?
  • Excel中的正则表达式特殊字符有哪些?

我知道正则表达式并不适合于许多情况(是否使用正则表达式?),因为在类似操作中,Excel可以使用LeftMidRightInstr等命令。


17
我强烈推荐Patrick Matthews撰写的VB/VBA正则表达式文章 - brettdj
1
尝试使用这个免费的插件:http://seotoolsforexcel.com/regexpfind/ - Niels Bosma
5
别忘了 Like 运算符,它提供了一种类似于正则表达式的轻量级功能。即使包装在子程序或函数过程中,它通常比正则表达式快得多。 - Egalth
9个回答

1135

正则表达式 用于模式匹配。

在Excel中使用,请按照以下步骤:

第一步: 添加VBA对“Microsoft VBScript Regular Expressions 5.5”的引用

  • 选择“开发人员”选项卡(我没有此选项卡该怎么办?
  • 从“代码”选项卡中选择“Visual Basic”图标
  • 在“Microsoft Visual Basic for Applications”窗口中,从顶部菜单中选择“工具”
  • 选择“引用”
  • 选中“包含在工作簿中的Microsoft VBScript Regular Expressions 5.5”旁边的框
  • 点击“确定”

第二步: 定义你的模式

基本定义:

- 范围。

  • 例如 a-z 匹配小写字母a到z
  • 例如 0-5 匹配0到5之间的任何数字

[] 只匹配括号内的一个对象。

  • 例如 [a] 匹配字母a
  • 例如 [abc] 匹配单个字母 a、b 或 c
  • 例如 [a-z] 匹配任意一个小写字母。

() 用于将不同的匹配分组以便返回。请参见以下示例。

{} 为之前定义的模式的重复副本设置乘数。

  • 例如 [a]{2} 匹配两个连续的小写字母a: aa
  • 例如 [a]{1,3} 匹配至少一个并最多三个小写字母 a, aa, aaa

+ 匹配至少一个或多个之前定义的模式。

  • 例如 a+ 将匹配连续的a's: a, aa, aaa等等。

? 匹配零个或一个之前定义的模式。

  • 例如,模式可能存在也可能不存在,但只能匹配一次。
  • 例如,[a-z]? 匹配空字符串或任何单个小写字母。

* 匹配零个或多个之前定义的模式。

  • 例如,用于可能存在或不存在的模式的通配符。
  • 例如,[a-z]* 匹配空字符串或小写字母字符串。

.匹配除换行符 \n 以外的任何字符

  • 例如,a.匹配以a开头并以除 \n 以外的任何字符结尾的两个字符字符串

| 或运算符

  • 例如,a|b 表示可以匹配 ab
  • 例如,red|white|orange 精确匹配其中一种颜色。

^ 非运算符

  • 例如,[^0-9] 字符不能包含数字
  • 例如,[^aA] 字符不能是小写字母 a 或大写字母 A

\ 转义后面的特殊字符(覆盖上述行为)

  • 例如,\., \\, \(, \?, \$, \^

锚定模式:

^ 匹配必须出现在字符串开头

  • 例如,^a 第一个字符必须是小写字母 a
  • 例如,^[0-9] 第一个字符必须是数字。

$ 匹配必须出现在字符串结尾

  • 例如,a$ 最后一个字符必须是小写字母 a

优先级表:

Order  Name                Representation
1      Parentheses         ( )
2      Multipliers         ? + * {m,n} {m, n}?
3      Sequence & Anchors  abc ^ $
4      Alternation         |

预定义字符缩写:

abr    same as       meaning
\d     [0-9]         Any single digit
\D     [^0-9]        Any single character that's not a digit
\w     [a-zA-Z0-9_]  Any word character
\W     [^a-zA-Z0-9_] Any non-word character
\s     [ \r\t\n\f]   Any space character
\S     [^ \r\t\n\f]  Any non-space character
\n     [\n]          New line
示例1作为宏运行 下面的示例宏检查单元格A1中的值,看看前1或2个字符是否是数字。如果是,则将其删除并显示字符串的其余部分。如果不是,则会出现一个框,告诉您未找到匹配项。单元格A1值为12abc将返回abc,值为1abc将返回abc,值为abc123将返回“未匹配”,因为数字不在字符串的开头。
Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range
    
    Set Myrange = ActiveSheet.Range("A1")
    
    If strPattern <> "" Then
        strInput = Myrange.Value
        
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With
        
        If regEx.Test(strInput) Then
            MsgBox (regEx.Replace(strInput, strReplace))
        Else
            MsgBox ("Not matched")
        End If
    End If
End Sub

示例2: 作为单元格函数运行

此示例与示例1相同,但设置为作为单元格函数运行。要使用,请将代码更改为以下内容:

Function simpleCellRegex(Myrange As Range) As String
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim strReplace As String
    Dim strOutput As String
    
    
    strPattern = "^[0-9]{1,3}"
    
    If strPattern <> "" Then
        strInput = Myrange.Value
        strReplace = ""
        
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = strPattern
        End With
        
        If regEx.test(strInput) Then
            simpleCellRegex = regEx.Replace(strInput, strReplace)
        Else
            simpleCellRegex = "Not matched"
        End If
    End If
End Function

将字符串("12abc")放入单元格A1中。在单元格B1中输入公式=simpleCellRegex(A1),结果将为"abc"。

results image


示例3循环范围

这个例子和示例1相同,但是循环处理一系列单元格。

Private Sub simpleRegex()
    Dim strPattern As String: strPattern = "^[0-9]{1,2}"
    Dim strReplace As String: strReplace = ""
    Dim regEx As New RegExp
    Dim strInput As String
    Dim Myrange As Range
    
    Set Myrange = ActiveSheet.Range("A1:A5")
    
    For Each cell In Myrange
        If strPattern <> "" Then
            strInput = cell.Value
            
            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With
            
            If regEx.Test(strInput) Then
                MsgBox (regEx.Replace(strInput, strReplace))
            Else
                MsgBox ("Not matched")
            End If
        End If
    Next
End Sub

例子4: 分解不同的模式

此例子循环遍历一个区域 (A1, A2A3),查找以三个数字开头,后跟一个字母和4个数字的字符串。输出将模式匹配拆分到相邻单元格中,使用()$1代表第一个在第一组()中匹配的模式。

Private Sub splitUpRegexPattern()
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim Myrange As Range
    
    Set Myrange = ActiveSheet.Range("A1:A3")
    
    For Each C In Myrange
        strPattern = "(^[0-9]{3})([a-zA-Z])([0-9]{4})"
        
        If strPattern <> "" Then
            strInput = C.Value
            
            With regEx
                .Global = True
                .MultiLine = True
                .IgnoreCase = False
                .Pattern = strPattern
            End With
            
            If regEx.test(strInput) Then
                C.Offset(0, 1) = regEx.Replace(strInput, "$1")
                C.Offset(0, 2) = regEx.Replace(strInput, "$2")
                C.Offset(0, 3) = regEx.Replace(strInput, "$3")
            Else
                C.Offset(0, 1) = "(Not matched)"
            End If
        End If
    Next
End Sub

结果:

结果图片


额外示例模式


(Note: 由于缺少上下文,翻译可能存在歧义,请您谨慎理解)
String   Regex Pattern                  Explanation
a1aaa    [a-zA-Z][0-9][a-zA-Z]{3}       Single alpha, single digit, three alpha characters
a1aaa    [a-zA-Z]?[0-9][a-zA-Z]{3}      May or may not have preceding alpha character
a1aaa    [a-zA-Z][0-9][a-zA-Z]{0,3}     Single alpha, single digit, 0 to 3 alpha characters
a1aaa    [a-zA-Z][0-9][a-zA-Z]*         Single alpha, single digit, followed by any number of alpha characters

</i8>    \<\/[a-zA-Z][0-9]\>            Exact non-word character except any single alpha followed by any single digit

35
当频繁执行该子程序时,您应该不要忘记设置regEx = Nothing。否则将会出现内存不足异常。 - Kiril
18
延迟绑定代码行:Set regEx = CreateObject("VBScript.RegExp") - ZygD
2
好的,我非常确定这是因为代码在ThisWorkbook中。尝试将代码移动到单独的模块中。 - Automate This
4
在“项目资源管理器”中,这个 Excel 文件缺少“模块”子文件夹,而另一个文件则显示了该文件夹。右键单击该文件并选择“插入模块”,然后双击“模块1”,将代码粘贴到其中。保存后返回工作簿,再次键入函数-它就可以正常工作了。对于像我这样的新手来说,这可能值得注意?感谢您的帮助。 - youcantryreachingme
6
在像Notepad++这样的简单独立工具中,有一个“正则表达式”选项,可以在查找和替换中使用。但是在像Excel这样的世界级工具中,你必须是程序员才能使用,而且使用方式也非常复杂和晦涩。 - Ciabaros
显示剩余16条评论

237

为了直接在Excel公式中使用正则表达式,可以使用以下UDF(用户定义函数)。它几乎直接将正则表达式功能作为Excel函数暴露出来。

工作原理

它需要2-3个参数。

  1. 要对其使用正则表达式的文本。
  2. 一个正则表达式。
  3. 一个格式字符串,指定结果应该如何显示。它可以包含$0$1$2等等。 $0是整个匹配项,$1及以上对应于正则表达式中各自的匹配组。默认为$0

一些示例

提取电子邮件地址:

=regex("Peter Gordon: some@email.com, 47", "\w+@\w+\.\w+")
=regex("Peter Gordon: some@email.com, 47", "\w+@\w+\.\w+", "$0")

结果为:some@email.com

提取多个子字符串:

=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "E-Mail: $2, Name: $1")

结果为:E-Mail: some@email.com, Name: Peter Gordon

将单个单元格中的组合字符串拆分成多个单元格中的各个部分:

=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "$" & 1)
=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "$" & 2)

结果为:Peter Gordon some@email.com ...

如何使用

按以下步骤使用此UDF(粗略基于此 Microsoft 页面,那里有一些很好的额外信息!):

  1. 在一个启用宏的 Excel 文件('.xlsm')中,按下 ALT+F11 打开 Microsoft Visual Basic for Applications 编辑器。
  2. 添加 VBA 引用到正则表达式库(从Portland Runners++ 的回答中抄袭而来):
    1. 点击工具引用(请原谅德文截图) Tools -> References
    2. 在列表中找到 Microsoft VBScript Regular Expressions 5.5 并选中旁边的复选框。
    3. 点击 确定
  3. 点击插入模块。如果给模块命名,请确保模块名称与下面的UDF不同(例如将模块命名为 Regex,函数命名为 regex 会导致#NAME!错误)。

    icon row的第二个图标 -> Module

  4. 在中间的大文本窗口中插入以下内容:

    Function regex(strInput As String, matchPattern As String, Optional ByVal outputPattern As String = "$0") As Variant
        Dim inputRegexObj As New VBScript_RegExp_55.RegExp, outputRegexObj As New VBScript_RegExp_55.RegExp, outReplaceRegexObj As New VBScript_RegExp_55.RegExp
        Dim inputMatches As Object, replaceMatches As Object, replaceMatch As Object
        Dim replaceNumber As Integer
    
        With inputRegexObj
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = matchPattern
        End With
        With outputRegexObj
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = "\$(\d+)"
        End With
        With outReplaceRegexObj
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
        End With
    
        Set inputMatches = inputRegexObj.Execute(strInput)
        If inputMatches.Count = 0 Then
            regex = False
        Else
            Set replaceMatches = outputRegexObj.Execute(outputPattern)
            For Each replaceMatch In replaceMatches
                replaceNumber = replaceMatch.SubMatches(0)
                outReplaceRegexObj.Pattern = "\$" & replaceNumber
    
                If replaceNumber = 0 Then
                    outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).Value)
                Else
                    If replaceNumber > inputMatches(0).SubMatches.Count Then
                        'regex = "A to high $ tag found. Largest allowed is $" & inputMatches(0).SubMatches.Count & "."
                        regex = CVErr(xlErrValue)
                        Exit Function
                    Else
                        outputPattern = outReplaceRegexObj.Replace(outputPattern, inputMatches(0).SubMatches(replaceNumber - 1))
                    End If
                End If
            Next
            regex = outputPattern
        End If
    End Function
    
  5. 保存并关闭 Microsoft Visual Basic for Applications 编辑器窗口。


7
这个答案结合了这里的步骤,创建了一个插件,非常有帮助。谢谢。请确保不要给模块和函数取相同的名称! - Chris Hunt
2
强调一下Chris Hunt上面的评论。也不要把你的模块命名为“Regex”。由于#NAME错误,我曾经以为自己疯了一段时间,因此函数无法正常工作。 - Chris
好吧,我疯了,我尝试了所有方法(包括更改模块/名称),但仍然收到“#NAME”错误 >_> http://i.imgur.com/UUQ6eCi.png - Enissay
尝试创建一个最小的 Function foo() As Variant \n foo="Hello World" \n End Function UDF,看看是否有效。如果可以,请逐步升级到上面的完整内容;如果不行,则可能是某些基本设置出了问题(宏已禁用?)。 - Patrick Böker
2
@Vijay:与 https://github.com/malcolmp/excel-regular-expressions 相同。 - Vadim
显示剩余3条评论

95

对于那些匆忙的人,扩展了patszim答案

  1. 打开Excel工作簿。
  2. Alt+F11 打开VBA/Macros窗口。
  3. 工具下选择引用添加正则表达式引用。
    ![Excel VBA Form add references
  4. 选择Microsoft VBScript Regular Expression 5.5
    ![Excel VBA add regex reference
  5. 插入新模块(代码需要驻留在模块中,否则不起作用)。
    ![Excel VBA insert code module
  6. 在新插入的模块中,
    ![Excel VBA insert code into module
  7. 添加以下代码:

    Function RegxFunc(strInput As String, regexPattern As String) As String
        Dim regEx As New RegExp
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .pattern = regexPattern
        End With
    
        If regEx.Test(strInput) Then
            Set matches = regEx.Execute(strInput)
            RegxFunc = matches(0).Value
        Else
            RegxFunc = "not matched"
        End If
    End Function
    
  8. 正则表达式模式放置在其中一个单元格中,并对其使用绝对引用![Excel regex function in-cell usage 该函数将与创建它的工作簿相关联。
    如果需要在不同的工作簿中使用它,请将函数存储在Personal.XLSB中。


3
谢谢提醒,需要将文件保存在 Personal.xlsb 才能在您所使用的所有 Excel 文档中使用。大多数其他答案没有明确指出这一点。Personal.xlsb 文件应该保存在 C:\Users\用户名\AppData\Local\Microsoft\Excel\XLStart 文件夹中(可能需要创建该文件夹)。 - Mark Stewart
我选择了这种方法。然而,对于我来说,在Office 365中存在一个问题。我注意到,如果我打开xlsm文件,使用RegxFunc的公式会变成#NAME。实际上,为了解决这个问题,我需要重新创建文件。有什么建议吗? - HoRn
@HoRn #Name? 你可能需要尝试这个答案,https://dev59.com/4mMk5IYBdhLWcg3w8STa#18841575。它指出函数名和模块名相同的问题,并提供了解决方案:重命名模块名或函数名。同一页面上的其他帖子也可能有所帮助。 - SAm
1
我放弃尝试让personal.xlsb工作了。相反,我将这个函数放在我的剪贴板缓冲区的永久集合(arsclip)中,需要时只需创建一个新模块即可。令人发笑的是,这对于一个应该在2021年成为Excel本地功能的函数来说是多么困难。PS:就在这件事情的中间,Stack要求我付费才能粘贴。你们好啊,现在是4月2日。^april\x20?0?1$'今天失败了。你们抓住我了。 - wistlo
对于来自非英语国家的一些人来说,这可能很有趣:在 RegxFunc(B5,$C$2) 中,您必须使用分号 ";" 而不是逗号 ","。 - devbf

32

这是我的尝试:

Function RegParse(ByVal pattern As String, ByVal html As String)
    Dim regex   As RegExp
    Set regex = New RegExp
    
    With regex
        .IgnoreCase = True  'ignoring cases while regex engine performs the search.
        .pattern = pattern  'declaring regex pattern.
        .Global = False     'restricting regex to find only first match.
        
        If .Test(html) Then         'Testing if the pattern matches or not
            mStr = .Execute(html)(0)        '.Execute(html)(0) will provide the String which matches with Regex
            RegParse = .Replace(mStr, "$1") '.Replace function will replace the String with whatever is in the first set of braces - $1.
        Else
            RegParse = "#N/A"
        End If 
    End With
End Function

31
这不是直接的答案,但或许可以提供更高效的替代方案。Google表格内置了一些正则表达式函数,这些函数非常方便,可以避免在Excel中进行一些技术性的操作。当然,在您的电脑上使用Excel也有一些优势,但对于绝大多数用户来说,Google表格将提供相同的体验,并可能在文档的可移植性和共享方面提供一些优势。
它们提供以下功能: REGEXEXTRACT:根据正则表达式提取匹配的子字符串。 REGEXREPLACE:使用正则表达式将文本字符串的一部分替换为不同的文本字符串。 SUBSTITUTE:在字符串中用新文本替换现有文本。 REPLACE:将文本字符串的一部分替换为不同的文本字符串。
您可以将它们直接键入单元格中,就会产生您想要的任何内容。
=REGEXMATCH(A2, "[0-9]+")

它们与其他函数的组合也非常出色,比如与IF语句一起使用,如下所示:

=IF(REGEXMATCH(E8,"MiB"),REGEXEXTRACT(E8,"\d*\.\d*|\d*")/1000,IF(REGEXMATCH(E8,"GiB"),REGEXEXTRACT(E8,"\d*\.\d*|\d*"),"")

在此输入图片描述

希望这提供了一个简单的解决办法,使那些感到 Excel 中 VBS 组件令人生畏的用户能够轻松应对。


6
谢谢分享,Alex。对于寻找Google版本的人来说,这很有用。你可以考虑撰写并回答另一个关于Google Sheets Regex的问题,因为它有自己的术语,并且对他人非常有用。无论如何,你已经得到我的点赞了! - Automate This
你能否创建一个在Excel中完全支持Google语法的模块? - Vijay

17
为了补充有价值的内容,我想提醒一下为什么有时在VBA中使用正则表达式并不理想,因为并非所有表达式都受支持,有些可能会抛出“错误5017”,让作者猜测(我自己就是受害者)。
虽然我们可以在这里找到一些关于支持哪些内容的说明,但知道哪些元字符等被支持也将很有帮助。更详细的说明可在此处找到。该来源中提到:

“尽管VBScript正则表达式...版本5.5实现了以前版本缺失的许多基本正则表达式功能...JavaScript和VBScript实现了Perl风格的正则表达式。但是,它们缺少许多Perl和其他现代正则表达式语言中的高级功能:”


所以不支持以下内容:
  • 字符串开头锚点\A,或者使用^符号匹配字符串第一个字符之前的位置
  • 字符串结尾锚点\Z,或者使用$符号匹配字符串最后一个字符之后的位置
  • 正向后行断言,例如:(?<=a)b(虽然支持正向前行断言)
  • 负向后行断言,例如:(?<!a)b(虽然支持负向前行断言)
  • 原子组
  • 占有量词
  • Unicode,例如:\{uFFFF}
  • 具名捕获组。或者使用数字捕获组
  • 内联修饰符,例如:/i(不区分大小写)或/g(全局)。通过RegExp对象属性设置这些 > 如果可用,则将RegExp.Global = TrueRegExp.IgnoreCase = True
  • 条件语句
  • 正则表达式注释。在脚本中使用常规的'注释来添加它们。

我在使用VBA中的正则表达式时已经遇到了不止一次的问题。通常是在使用LookBehind时,但有时我甚至会忘记修改器。我自己没有经历过上述所有这些问题,但我想尝试更详细地提到一些更深入的信息。欢迎评论/纠正/添加。非常感谢regular-expressions.info提供如此丰富的信息。

P.S. 你提到了常规的VBA方法和函数,我可以确认它们(至少对我自己而言)在RegEx失败时也很有帮助。


10

我需要将这个作为单元格函数(比如 SUM 或者 VLOOKUP)使用,发现很容易实现以下步骤:

  1. 确保你在启用宏的Excel文件中(另存为 xlsm 格式)。
  2. 打开开发人员工具 Alt + F11
  3. 像其他回答一样添加 Microsoft VBScript Regular Expressions 5.5
  4. 在工作簿或其自己的模块中创建以下函数:

    Function REGPLACE(myRange As Range, matchPattern As String, outputPattern As String) As Variant
        Dim regex As New VBScript_RegExp_55.RegExp
        Dim strInput As String
    
        strInput = myRange.Value
    
        With regex
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .Pattern = matchPattern
        End With
    
        REGPLACE = regex.Replace(strInput, outputPattern)
    
    End Function
    
  5. 那么你可以在单元格中使用=REGPLACE(B1, "(\w) (\d+)", "$1$2")(例如:"A 243" 变成 "A243")


这个 outputPattern 的命名让我有些困惑,它其实是替换值。 - Thor
1
是的。我想我把它命名为“pattern”,这样就清楚了它不仅仅是字符串替换,你还可以使用正则表达式匹配组,如$1 $2等。 - Andrew Wynham

8

这里有一个 regex_subst() 函数。例如:

=regex_subst("watermellon", "[aeiou]", "")
---> wtrmlln
=regex_subst("watermellon", "[^aeiou]", "")
---> aeeo

这是简化的代码(对我来说更简单)。我无法使用上述内容构建合适的输出模式,使其像我的示例一样工作:
Function regex_subst( _
     strInput As String _
   , matchPattern As String _
   , Optional ByVal replacePattern As String = "" _
) As Variant
    Dim inputRegexObj As New VBScript_RegExp_55.RegExp

    With inputRegexObj
        .Global = True
        .MultiLine = True
        .IgnoreCase = False
        .Pattern = matchPattern
    End With

    regex_subst = inputRegexObj.Replace(strInput, replacePattern)
End Function

2
我不想启用参考库,因为我需要我的脚本是可移植的。"Dim foo As New VBScript_RegExp_55.RegExp"这行代码导致了"User Defined Type Not Defined"错误,但我找到了适合我的解决方案。
更新RE评论与@chrisneilsen:
我原以为启用参考库与本地计算机设置有关,但实际上与工作簿直接相关。因此,您可以启用参考库,共享启用宏的工作簿,最终用户也不必启用库。注意:Late Binding的优点在于开发人员不必担心用户计算机上安装了错误版本的对象库。这可能对VBScript_RegExp_55.RegExp库不是问题,但我认为此时“性能”利益是否值得,我还没有下定论,因为我们正在谈论代码中无法感知的毫秒级差异。我觉得这值得更新,以帮助其他人理解。如果启用参考库,则可以使用“early bind”,但是,据我所知,如果不启用,则代码将正常工作,但需要“late bind”,并且会损失一些性能/调试功能。
来源:https://peltiertech.com/Excel/EarlyLateBinding.html 您需要在单元格A1中放入示例字符串,然后测试您的strPattern。一旦这个工作正常,就可以根据需要调整rng。
Public Sub RegExSearch()
'https://dev59.com/u2Eh5IYBdhLWcg3wVCEb
'https://wellsr.com/vba/2018/excel/vba-regex-regular-expressions-guide/
'https://www.vitoshacademy.com/vba-regex-in-excel/
    Dim regexp As Object
    'Dim regex As New VBScript_RegExp_55.regexp 'Caused "User Defined Type Not Defined" Error
    Dim rng As Range, rcell As Range
    Dim strInput As String, strPattern As String
    
    Set regexp = CreateObject("vbscript.regexp")
    Set rng = ActiveSheet.Range("A1:A1")
        
    strPattern = "([a-z]{2})([0-9]{8})"
    'Search for 2 Letters then 8 Digits Eg: XY12345678 = Matched

    With regexp
        .Global = False
        .MultiLine = False
        .ignoreCase = True
        .Pattern = strPattern
    End With

    For Each rcell In rng.Cells

        If strPattern <> "" Then
            strInput = rcell.Value

            If regexp.test(strInput) Then
                MsgBox rcell & " Matched in Cell " & rcell.Address
            Else
                MsgBox "No Matches!"
            End If
        End If
    Next
End Sub

1
我不想启用参考库,因为我需要我的脚本具有可移植性。VBScript_RegExp_55 库几乎无处不在,因此很少出现在特定目标机器上找不到的风险。而且,从 Early Bound 切换到 Late Bound 也无法解决可移植性问题(代码仍然会出错,只是在运行时而不是编译时)。 - chris neilsen
2
当然可以,但是正则表达式代码可能不会“可用”。如果正则表达式部分是较大库工作簿的一部分,我想让它不抛出编译错误,从而允许使用其他部分可能被认为是有用的。 - chris neilsen
1
我的观点是,如果代码在早期绑定时(已经安装所需的引用)无法正常工作,则晚期绑定也无法正常工作。至于可移植性问题,在不同PC上可能存在相同库的不同版本时,这是有价值的。但这里几乎不是问题,Regex库在过去十年中没有发生过变化,并且不太可能很快发生变化。无论如何,您所说的“更改默认设置”是什么意思?库引用是工作簿的一部分,而不是PC设置。 - chris neilsen
1
我已经使用VBA Regex库约20年了,从未遇到过切换从早期绑定到晚期绑定可以解决的错误。如果您能证明一个,我会很感兴趣看看(这本身就是一个好问题)。与此同时,我坚持我的原始评论。 - chris neilsen
如果您查看VBA项目的对象模型,您会发现VBProject对象具有References属性。库引用作为宿主文档中VBA项目的一部分保存。 - Mathieu Guindon
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接