【问题标题】:How do I get regex support in Excel via a function, or custom function?如何通过函数或自定义函数在 Excel 中获得正则表达式支持?
【发布时间】:2010-12-29 18:51:06
【问题描述】:

Excel 中似乎不支持正则表达式(如在正则表达式中),除非通过 VBA。是这样吗,如果是,是否有任何支持正则表达式的“开源”自定义 VBA 函数?在这种情况下,我希望在字符串中提取复杂的模式,并且在函数本身中公开对正则表达式的支持的自定义 VBA 函数的任何实现都是有用的。如果您知道半相关函数,例如 IS 函数,请随时发表评论,尽管我真的在寻找通过函数公开的完整正则表达式实现。

另外,请注意我在 Windows 7 上使用 Office 2010;在似乎是一个很好的建议的答案被证明不适用于 Office 2010 之后添加了此信息。

【问题讨论】:

标签: regex excel vba


【解决方案1】:

Excel 中没有内置任何内容。 VBScript 具有内置支持,可以从 VBA 调用。更多信息available here。您可以在 VBA 中使用后期绑定调用该对象。我已经包含了一些我最近放在一起的功能。请注意,这些都没有经过充分测试,可能存在一些错误,但它们非常简单。

这至少应该让你开始:

'---------------------------------------------------------------------------------------vv
' Procedure : RegEx
' Author    : Mike
' Date      : 9/1/2010
' Purpose   : Perform a regular expression search on a string and return the first match
'               or the null string if no matches are found.
' Usage     : If Len(RegEx("\d{1,2}[/-]\d{1,2}[/-]\d{2,4}", txt)) = 0 Then MsgBox "No date in " & txt
'           : TheDate = RegEx("\d{1,2}[/-]\d{1,2}[/-]\d{2,4}", txt)
'           : CUSIP = Regex("[A-Za-z0-9]{8}[0-9]",txt)
'---------------------------------------------------------------------------------------
'^^
Function RegEx(Pattern As String, TextToSearch As String) As String 'vv
    Dim RE As Object, REMatches As Object

    Set RE = CreateObject("vbscript.regexp")
    With RE
        .MultiLine = False
        .Global = False
        .IgnoreCase = False
        .Pattern = Pattern
    End With

    Set REMatches = RE.Execute(TextToSearch)
    If REMatches.Count > 0 Then
        RegEx = REMatches(0)
    Else
        RegEx = vbNullString
    End If
End Function '^^

'---------------------------------------------------------------------------------------
' Procedure : RegExReplace
' Author    : Mike
' Date      : 11/4/2010
' Purpose   : Attempts to replace text in the TextToSearch with text and back references
'               from the ReplacePattern for any matches found using SearchPattern.
' Notes     - If no matches are found, TextToSearch is returned unaltered.  To get
'               specific info from a string, use RegExExtract instead.
' Usage     : ?RegExReplace("(.*)(\d{3})[\)\s.-](\d{3})[\s.-](\d{4})(.*)", "My phone # is 570.555.1234.", "$1($2)$3-$4$5")
'             My phone # is (570)555-1234.
'---------------------------------------------------------------------------------------
'
Function RegExReplace(SearchPattern As String, TextToSearch As String, ReplacePattern As String, _
                      Optional GlobalReplace As Boolean = True, _
                      Optional IgnoreCase As Boolean = False, _
                      Optional MultiLine As Boolean = False) As String
Dim RE As Object

    Set RE = CreateObject("vbscript.regexp")
    With RE
        .MultiLine = MultiLine
        .Global = GlobalReplace
        .IgnoreCase = IgnoreCase
        .Pattern = SearchPattern
    End With

    RegExReplace = RE.Replace(TextToSearch, ReplacePattern)
End Function

'---------------------------------------------------------------------------------------
' Procedure : RegExExtract
' Author    : Mike
' Date      : 11/4/2010
' Purpose   : Extracts specific information from a string.  Returns empty string if not found.
' Usage     : ?RegExExtract("(.*)(\d{3})[\)\s.-](\d{3})[\s.-](\d{4})(.*)", "My phone # is 570.555.1234.", "$2$3$4")
'             5705551234
'             ?RegExExtract("(.*)(\d{3})[\)\s.-](\d{3})[\s.-](\d{4})(.*)", "My name is Mike.", "$2$3$4")
'
'             ?RegExReplace("(.*)(\d{3})[\)\s.-](\d{3})[\s.-](\d{4})(.*)", "My name is Mike.", "$2$3$4")
'             My name is Mike.
'---------------------------------------------------------------------------------------
'
Function RegExExtract(SearchPattern As String, TextToSearch As String, PatternToExtract As String, _
                      Optional GlobalReplace As Boolean = True, _
                      Optional IgnoreCase As Boolean = False, _
                      Optional MultiLine As Boolean = False) As String
Dim MatchFound As Boolean

    MatchFound = Len(RegEx(SearchPattern, TextToSearch)) > 0
    If MatchFound Then
        RegExExtract = RegExReplace(SearchPattern, TextToSearch, PatternToExtract, _
                                    GlobalReplace, IgnoreCase, MultiLine)
    Else
        RegExExtract = vbNullString
    End If
End Function

【讨论】:

  • +1 太好了,谢谢——在我尝试使用代码之前问一个简单的问题(看起来很棒,谢谢)——你在什么系统上使用它?我在使用 64 位的 Window 7、Office 2010 上。再次感谢!
  • Windows 7 64 位,Office XP。 vbscript.regexp 对象附带 windows,而不是 office,因此它应该适合您。
  • +1 据我所知,这个正则表达式引擎随(某些版本的)Internet Explorer 一起提供。我已经在我的排序插件 LAselect 中使用了它,它似乎可以很好地对街道名称、人名、邮政编码等进行排序,而无需使用拆分单元格。
  • 您也可以使用早期绑定调用它,方法是添加对 VBScript 正则表达式库的引用。
【解决方案2】:

这是一篇关于 Excel 中正则表达式使用的帖子:

http://mathfest.blogspot.com/2010/03/regular-expressions-in-excel.html

希望对你有帮助。

另一个使用 Python 和 IronSpread

http://mathfest.blogspot.ca/2012/06/using-ironspread-and-regular.html

【讨论】:

  • +1 谢谢,看来它只与 Excel 95 到 2007 兼容——我在 Win7 上使用 2010;会认为任何解决方案都可以在我的平台上运行,但猜不到。我会将该信息添加到我的问题中。
  • 只是一个更新,似乎问题与 Office2010-Win7 上的 64 位有关 mrexcel.com/forum/showthread.php?t=467397 在这一点上,真的不想仅仅为了这个而切换到 32 位 Office 2010,但是以为我会将此信息添加到您的答案中,以防其他人正在调查它。
【解决方案3】:

在函数中使用正则表达式包含在 OpenOffice/LibreOffice Calc 中。要激活,请转到工具 > 选项 > 计算 > 计算:Y = 在公式中启用正则表达式。

【讨论】:

【解决方案4】:

我尝试了几种解决方案,但由于我缺乏 VBA 专业知识,我发现其中大多数对我来说太麻烦了。 我找到的最简单的是 SeoTools for Excel (http://nielsbosma.se/projects/seotools/)。 对我来说就像一个魅力。

【讨论】:

  • 是的,这个工具真的很棒;)
【解决方案5】:

--- 2014 年 2 月 ---

只是提供一个替代方案,Open OfficeLibre Office Calc 软件(它们的电子表格软件名称)都允许在其搜索功能中使用正则表达式。

【讨论】:

  • 不清楚为什么您的答案是主题或为什么“2014 年 2 月”在您的答案中。请解释一下,谢谢。
  • 正如我在回答中所述,它是一种更新的替代方案,而不是四年前声明和接受的功能。对于那些会滚动浏览答案而不必搜索答案的年龄的人,我会加粗月份和年份。
【解决方案6】:

我最近遇到了同样的问题,在努力创建自己的工具并使其正常工作后,我发现了一个非常易于使用的出色在线 ADDIN。

这是创作者的摘录

在过去几个月的实习中,我一直在 营销科学部门和我的部分工作一直在 数据导入 MS Access 并生成报告。这涉及获得 来自各种数据源的潜在客户列表。这通常是一个 非常简单的壮举,涉及一些基本的 SQL 查询。然而, 有时我会收到一些不匹配的地址等数据 IT 使用的标准格式。在最坏的情况下,数据以 一个 pdf,这意味着我只能将它导出到一个非分隔的文本文件。 我发现我真的需要几个通用正则表达式 解析字段以导入 MS Access 的函数。我找到了一些 .xla 在线示例,但我真的想要一个更易于使用,更多 广泛且可移植的库。我还想包括一些基本的 因此不必每次都重新发明轮子。

所以,我创建了一个简单的 Excel Add-In Regular Expressions.xla,它添加了 几个自定义函数来实现标准的 VBScript 正则 表达式。

这里是website

我已经成功地使用它通过正则表达式提取有用的文本。

这是插件中的代码

' Regular Expressions.xla
'
' ? 2010 Malcolm Poindexter
' This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
' as published by the Free Software Foundation, version 3.
' This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
' without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
' See the GNU General Public License for more details. http://www.gnu.org/licenses/gpl.html
'
' I would appreciate if you would notify me of any modifications or re-distributions of this code at contact@malcolmp.com
' and appropriately attribute me as the original author in the header.
' ------------------------------------------------------------------------------------------------------------------------
'
' This file provides an Excel Add-In containing regular expression processing functions and several pre-defined regular expressions.
' The regular expressions provided are not necessarially exhaustive, but are intended to cover the most common cases.
'
' Regular Expressions Syntax: http://msdn.microsoft.com/en-us/library/1400241x%28VS.85%29.aspx

' -----------------------------
' NAME: xREPLACE
' DESCRIPTION: Replace all portions of the search text matching the pattern with the replacement text.
' -----------------------------
Function xREPLACE(pattern As String, searchText As String, replacementText As String, Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = pattern
    RegEx.ignoreCase = ignoreCase
    xREPLACE = RegEx.Replace(searchText, replacementText)
End Function

' -----------------------------
' NAME: xMATCHES
' DESCRIPTION: Find and return the number of matches to a pattern in the search text.
' -----------------------------
Function xMATCHES(pattern As String, searchText As String, Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = pattern
    RegEx.ignoreCase = ignoreCase
    Dim matches As MatchCollection
    Set matches = RegEx.Execute(searchText)
    xMATCHES = matches.Count
End Function

' -----------------------------
' NAME: xMATCH
' DESCRIPTION: Find and return an instance of a match to the pattern in the search text. MatchIndex may be used in the case of multiple matches.
' -----------------------------
Function xMATCH(pattern As String, searchText As String, Optional matchIndex As Integer = 1, _
                Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = pattern
    RegEx.ignoreCase = ignoreCase
    Dim matches As MatchCollection
    Set matches = RegEx.Execute(searchText)
    Dim i As Integer
    i = 1
    For Each Match In matches
        If i = matchIndex Then
            xMATCH = Match.Value
        End If
        i = i + 1
    Next
End Function

' -----------------------------
' NAME: xMATCHALL
' DESCRIPTION: Find and return a comma-separated list of all matches to the pattern in the search text.
' -----------------------------
Function xMATCHALL(pattern As String, searchText As String, Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = pattern
    RegEx.ignoreCase = ignoreCase
    Dim matches As MatchCollection
    Set matches = RegEx.Execute(searchText)
    Dim i As Integer
    i = 1
    Dim returnMatches As String
    returnMatches = ""
    For Each Match In matches
        If i = 1 Then
            returnMatches = Match.Value
        Else
            returnMatches = returnMatches + "," + Match.Value
        End If
        i = i + 1
    Next
    xMATCHALL = returnMatches
End Function

' -----------------------------
' NAME: xGROUP
' DESCRIPTION: Find and return a group from within a matched pattern.
' -----------------------------
Function xGROUP(pattern As String, searchText As String, group As Integer, Optional matchIndex As Integer = 1, _
                Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    If group <> 0 Then
        group = group - 1
    End If
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = pattern
    RegEx.ignoreCase = ignoreCase
    Dim matches As MatchCollection
    Set matches = RegEx.Execute(searchText)
    Dim i As Integer
    i = 1
    For Each Match In matches
        If i = matchIndex Then
            xGROUP = Match.SubMatches(group)
        End If
        i = i + 1
    Next
End Function

' -----------------------------
' NAME: xSTARTSWITH
' DESCRIPTION: Returns true or false if the search text starts with the pattern.
' -----------------------------
Function xSTARTSWITH(pattern As String, searchText As String, Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = "^" + pattern
    RegEx.ignoreCase = ignoreCase
    Dim matches As MatchCollection
    Set matches = RegEx.Execute(searchText)
    xSTARTSWITH = matches.Count > 0
End Function

' -----------------------------
' NAME: xENDSWITH
' DESCRIPTION: Returns true or false if the search text ends with the pattern.
' -----------------------------
Function xENDSWITH(pattern As String, searchText As String, Optional ignoreCase As Boolean = True) As String
    On Error Resume Next
    Dim RegEx As New RegExp
    RegEx.Global = True
    RegEx.MultiLine = True
    RegEx.pattern = pattern + "$"
    RegEx.ignoreCase = ignoreCase
    Dim matches As MatchCollection
    Set matches = RegEx.Execute(searchText)
    xENDSWITH = matches.Count > 0
End Function

' ************************************
' Regular Expression Definitions
' ************************************

' -----------------------------
' NAME: xxEMAIL
' DESCRIPTION: Pattern to match an email address.
' -----------------------------
Function xxEMAIL() As String
    xxEMAIL = "\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b"
End Function

' -----------------------------
' NAME: xxUSZIP
' DESCRIPTION: Pattern to match an US Zip code.
' -----------------------------
Function xxUSZIP() As String
    xxUSZIP = "\b(?!0{5})(\d{5})(?!-0{4})(-\d{4})?\b"
End Function

' -----------------------------
' NAME: xxPHONE
' DESCRIPTION: Pattern to match a phone number.
' -----------------------------
Function xxPHONE() As String
    xxPHONE = "\b[01]?[- .]?\(?[2-9]\d{2}\)?\s?[- .]?\s?\d{3}\s?[- .]?\s?\d{4}(\s*(x|(ext))[\.]?\s*\d{1,6})?\b"
End Function

' -----------------------------
' NAME: xxURL
' DESCRIPTION: Pattern to match a url.
' -----------------------------
Function xxURL() As String
    xxURL = "\b((ftp)|(https?))\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}\b"
End Function


' ************************************
'   Insert Function Dialog Category Setup
' ************************************
Sub AddCategoryDescription()
    Application.MacroOptions Macro:="xREPLACE", _
        Description:="Replace all portions of the search text matching the pattern with the replacement text.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xMATCHES", _
        Description:="Find and return the number of matches to a pattern in the search text.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xMATCH", _
        Description:="Find and return an instance of a match to the pattern in the search text. MatchIndex may be used in the case of multiple matches.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xMATCHALL", _
        Description:="Find and return a comma-separated list of all matches to the pattern in the search text.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xGROUP", _
        Description:="Find and return a group from within a matched pattern.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xSTARTSWITH", _
        Description:="Returns true or false if the search text starts with the pattern.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xENDSWITH", _
        Description:="Returns true or false if the search text ends with the pattern.", _
        Category:="Regular Expressions"

    '**** Regular Expressions ****

    Application.MacroOptions Macro:="xxEMAIL", _
        Description:="Pattern to match an email address.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xxUSZIP", _
        Description:="Pattern to match an US Zip code.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xxPHONE", _
        Description:="Pattern to match a phone number.", _
        Category:="Regular Expressions"

    Application.MacroOptions Macro:="xxURL", _
        Description:="Pattern to match a url.", _
        Category:="Regular Expressions"
End Sub

【讨论】:

  • 在此处添加代码以使其看起来不像广告,因此您可以看到它是一个有用且快速使用的库
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
相关资源
最近更新 更多