如何在Microsoft Excel中使用正则expression式(正则expression式)在单元格内和循环中
如何在Excel中使用正则expression式并利用Excel的强大网格(如设置数据操作)?
- 在单元格函数返回匹配的模式或replacestring中的值。
- Sub循环访问一列数据并提取与相邻单元格的匹配。
- 什么设置是必要的?
- 什么是Excel正则expression式的特殊字符?
我知道正则expression式在许多情况下( 使用或不使用正则expression式? )并不理想,因为excel可以使用Left
, Mid
, Right
, Instr
types命令进行类似的操作。
正则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一个,最多三个小写字母a
,aa
,aaa
+
匹配之前定义的至less一个或多个模式。
- 例如
a+
将匹配连续的a
,aa
,aaa
等
?
匹配零或之前定义的模式之一。
- 例如模式可能存在也可能不存在,但只能匹配一次。
- 例如
[az]?
匹配空string或任何单个小写字母。
*
匹配之前定义的零个或多个模式。 – 例如通配符用于可能存在或不存在的模式。 – 例如[az]*
匹配空string或小写字母的string。
.
匹配除换行符之外的任何字符\n
- 例如
a.
匹配以“a”开始的两个string,并以除\n
以外的任何内容结尾
|
OR运算符
- 例如
a|b
表示a
或b
可以匹配。 - 例如,
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
值将返回abc
, 1abc
值将返回abc
, abc123
值将返回“不匹配”,因为数字不在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
。 在单元格B1
input这个公式=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 :拆分不同的模式
这个例子循环遍历一个范围( A1
, A2
& A3
),并查找一个以三位数字开头的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个参数。
- 一个文本使用正则expression式。
- 一个正则expression式。
- 指定结果外观的格式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页面 ,他们有一些很好的附加信息!):
- 在macros启用文件('.xlsm')中的Excel中按
ALT+F11
以打开Microsoft Visual Basic for Applications编辑器。 - 将VBA引用添加到正则expression式库(无耻地从波特兰跑步者++复制):
- 点击工具 – > 参考 (请原谅德国的截图)
- 在列表中findMicrosoft VBScript Regular Expressions 5.5并勾选它旁边的checkbox。
- 点击OK 。
-
点击插入模块 。 如果你给你的模块一个不同的名字,请确保模块名称与下面的UDF名称不同(例如命名模块
regex
Regex
和函数regex
导致#NAME!错误)。 -
在中间的大文本窗口中插入以下内容:
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
-
保存并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的答案 。
- 打开Excel工作簿。
- Alt + F11打开VBA /macros窗口。
- 在工具然后引用添加引用正则expression式
- 并selectMicrosoft VBScript正则expression式5.5
- 插入一个新的模块(代码需要驻留在模块中,否则不能工作)。
- 在新插入的模块中,
-
添加下面的代码:
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
-
正则expression式模式放置在其中一个单元格中,并使用绝对引用 。 函数将被绑定到其创build的工作簿。
如果需要在不同的工作簿中使用它,请将该函数存储在Personal.XLSB中
我需要使用这个单元格函数(如SUM或VLOOKUP),并发现很容易:
- 确保您处于启用macros的Excel文件(另存为xlsm)。
- 打开开发人员工具
ALT+F11
- 在其他答案中添加Microsoft VBScript正则expression式5.5
-
在工作簿或其自己的模块中创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
-
那么你可以在单元格中使用
=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