如何在Microsoft Excel中使用正则expression式(正则expression式)在单元格内和循环中

如何在Excel中使用正则expression式并利用Excel的强大网格(如设置数据操作)?

  • 在单元格函数返回匹配的模式或replacestring中的值。
  • Sub循环访问一列数据并提取与相邻单元格的匹配。
  • 什么设置是必要的?
  • 什么是Excel正则expression式的特殊字符?

我知道正则expression式在许多情况下( 使用或不使用正则expression式? )并不理想,因为excel可以使用LeftMidRightInstrtypes命令进行类似的操作。

正则expression式用于模式匹配。

在Excel中使用请按照下列步骤操作:

步骤1 :将VBA引用添加到“Microsoft VBScript Regular Expressions 5.5”

  • select“开发者”选项卡( 我没有这个标签,我该怎么办? )
  • 从“代码”function区部分select“Visual Basic”图标
  • 在“Microsoft Visual Basic for Applications”窗口中,从顶部菜单中select“工具”。
  • select“参考”
  • 选中“Microsoft VBScript Regular Expressions 5.5”旁边的框以将其包含在工作簿中。
  • 点击“确定”

第2步 :定义你的模式

基本定义:

-范围。

  • 例如, az匹配从a到z的小写字母
  • 例如0-5匹配从0到5的任何数字

[]恰好匹配这些括号内的一个对象。

  • 例如[a]匹配字母a
  • 例如[abc]匹配单个字母,可以是a,b或c
  • 例如[az]匹配字母表中的任何一个小写字母。

()为返回目的分组不同的匹配。 看下面的例子。

{}用于在其之前定义的模式的重复副本的乘数。

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

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

  • 例如a+将匹配连续的aaaaaa

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

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

*匹配之前定义的零个或多个模式。 – 例如通配符用于可能存在或不存在的模式。 – 例如[az]*匹配空string或小写字母的string。

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

  • 例如a. 匹配以“a”开始的两个string,并以除\n以外的任何内容结尾

| OR运算符

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

^ NOT运算符

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

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

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

锚定模式:

^匹配必须发生在string的开头

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

$匹配必须出现在string的末尾

  • 例如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以macros运行

下面的示例macros查看单元格A1中的值,以查看前1或2个字符是否是数字。 如果是这样,他们被删除,并显示其余的string。 如果不是,则会出现一个框,告诉您没有find匹配。 12abc单元格A1值将返回abc1abc值将返回abcabc123值将返回“不匹配”,因为数字不在string的起始位置。

 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 

将您的string(“12abc”)放在单元格A1 。 在单元格B1input这个公式=simpleCellRegex(A1) ,结果将是“abc”。

在这里输入图像描述


示例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 :拆分不同的模式

这个例子循环遍历一个范围( A1A2A3 ),并查找一个以三位数字开头的string,接着是一个字母字符,然后是四位数字。 输出通过使用()将模式匹配拆分成相邻的单元格。 $1表示在第一组()内匹配的第一个模式。

 Private Sub splitUpRegexPattern() Dim regEx As New RegExp Dim strPattern As String Dim strInput As String Dim strReplace 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 strReplace = "$1" 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 

结果:

在这里输入图像描述


其他模式示例

 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 preceeding 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 

要直接在Excel公式中使用正则expression式,以下UDF(用户定义函数)可以提供帮助。 它或多或less直接将正则expression式function作为一个Excel函数来公开。

怎么运行的

它需要2-3个参数。

  1. 一个文本使用正则expression式。
  2. 一个正则expression式。
  3. 指定结果外观的格式string。 它可以包含$0$1$2等等。 $0是整个比赛, $1以上对应于正则expression式中的各个比赛组。 默认为$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

提取几个子string:

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

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

将单个单元格中的组合string拆分为多个单元格中的组件:

 =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. 在macros启用文件('.xlsm')中的Excel中按ALT+F11以打开Microsoft Visual Basic for Applications编辑器。
  2. 将VBA引用添加到正则expression式库(无耻地从波特兰跑步者++复制):
    1. 点击工具 – > 参考 (请原谅德国的截图) 工具 - >参考
    2. 在列表中findMicrosoft VBScript Regular Expressions 5.5并勾选它旁边的checkbox。
    3. 点击OK
  3. 点击插入模块 。 如果你给你的模块一个不同的名字,请确保模块名称与下面的UDF名称不同(例如命名模块regex Regex和函数regex导致#NAME!错误)。

    图标行中的第二个图标 - >模块

  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. 保存并closuresMicrosoft Visual Basic for Applications编辑器窗口。

我不是你们的专家,即使这样,我的方式也是如此。

 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 

对于那些急于求成的人来说,扩大patszim的答案 。

  1. 打开Excel工作簿。
  2. Alt + F11打开VBA /macros窗口。
  3. 工具然后引用添加引用正则expression式
    ![Excel VBA表单添加引用
  4. 并selectMicrosoft VBScript正则expression式5.5
    ![Excel VBA添加正则表达式参考
  5. 插入一个新的模块(代码需要驻留在模块中,否则不能工作)。
    ![Excel VBA插入代码模块
  6. 在新插入的模块中,
    ![Excel VBA插入代码到模块中
  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. 正则expression式模式放置在其中一个单元格中,并使用绝对引用![Excel正则表达式函数in-cell的用法 函数将被绑定到其创build的工作簿。
    如果需要在不同的工作簿中使用它,请将该函数存储在Personal.XLSB中

我需要使用这个单元格函数(如SUM或VLOOKUP),并发现很容易:

  1. 确保您处于启用macros的Excel文件(另存为xlsm)。
  2. 打开开发人员工具ALT+F11
  3. 在其他答案中添加Microsoft VBScript正则expression式5.5
  4. 在工作簿或其自己的模块中创build以下function:

     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”)

@ patszim:非常有帮助,谢谢。 增加了一个regex_subst()函数。 例子:

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

这里是简化的代码(无论如何,对我来说更简单)。 我无法弄清楚如何使用上面的工作来构build合适的输出模式,就像我的例子一样:

 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