如何在Excel中使用正则表达式并利用Excel强大的网格设置进行数据操作?
我的理解正则表达式是不理想的许多情况下(使用或不使用正则表达式?),因为Excel可以使用Left,Mid,Right,Instr类型相似的操作命令.
Por*_*ner 894
正则表达式用于模式匹配.
要在Excel中使用,请执行以下步骤:
步骤1:将VBA引用添加到"Microsoft VBScript Regular Expressions 5.5"
第2步:定义您的模式
基本定义:
- 范围.
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,aa,aaa,等? 匹配零或之前定义的模式之一.
[a-z]?匹配空字符串或任何单个小写字母.* 匹配在其之前定义的模式的零个或多个. - 例如,可能存在或不存在的模式的通配符.- 例如[a-z]*匹配空字符串或小写字母串.
. 匹配除换行符之外的任何字符 \n
a.匹配以a开头并以除外的任何内容结尾的两个字符串\n| OR运算符
a|b意味着要么a或b可以被匹配.red|white|orange恰好匹配其中一种颜色.^ NOT运算符
[^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 |
Run Code Online (Sandbox Code Playgroud)
预定义字符缩写:
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
Run Code Online (Sandbox Code Playgroud)
示例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
Run Code Online (Sandbox Code Playgroud)
示例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
Run Code Online (Sandbox Code Playgroud)
将字符串("12abc")放入单元格中A1.=simpleCellRegex(A1)在单元格中输入此公式,B1结果将为"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
Run Code Online (Sandbox Code Playgroud)
示例4:拆分不同的模式
此示例循环遍历范围(A1,A2&A3)并查找以三位数字开头的字符串,后跟单个字母字符,然后是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
Run Code Online (Sandbox Code Playgroud)
结果:

附加模式示例
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
Run Code Online (Sandbox Code Playgroud)
Pat*_*ker 192
要直接在Excel公式中使用正则表达式,以下UDF(用户定义的函数)可能会有所帮助.它或多或少直接将正则表达式功能公开为excel函数.
它需要2-3个参数.
$0,$1,$2,等等.$0是整个匹配,$1并且up对应于正则表达式中的相应匹配组.默认为$0.提取电子邮件地址:
=regex("Peter Gordon: some@email.com, 47", "\w+@\w+\.\w+")
=regex("Peter Gordon: some@email.com, 47", "\w+@\w+\.\w+", "$0")
Run Code Online (Sandbox Code Playgroud)
结果是: some@email.com
提取几个子串:
=regex("Peter Gordon: some@email.com, 47", "^(.+): (.+), (\d+)$", "E-Mail: $2, Name: $1")
Run Code Online (Sandbox Code Playgroud)
结果是: 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)
Run Code Online (Sandbox Code Playgroud)
结果:Peter Gordon some@email.com...
要使用此UDF,请执行以下操作(大致基于此Microsoft页面.它们有一些很好的附加信息!):
ALT+F11以打开Microsoft Visual Basic for Applications Editor.
单击" 插入模块".如果你给你的模块不同的名称,确保该模块不具有相同的名称,下面的UDF(如命名的模块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
Run Code Online (Sandbox Code Playgroud)保存并关闭Microsoft Visual Basic for Applications Editor窗口.
SAm*_*SAm 55




添加以下代码:
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
Run Code Online (Sandbox Code Playgroud)正则表达式模式放在其中一个单元格中,并在其上使用绝对引用.
函数将与其创建的工作簿绑定.
如果需要在不同的工作簿中使用它,请将该函数存储在Personal.XLSB中
Vik*_*tam 25
这是我的尝试:
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
Run Code Online (Sandbox Code Playgroud)
小智 14
这不是一个直接的答案,但可能会提供一个更有效的替代方案供您考虑。也就是 Google Sheets 有几个内置的Regex 函数,这些函数非常方便,有助于绕过 Excel 中的一些技术程序。显然,在您的 PC 上使用 Excel 有一些优势,但对于绝大多数用户而言,Google 表格将提供相同的体验,并可能在可移植性和文档共享方面提供一些好处。
他们提供
REGEXEXTRACT:根据正则表达式提取匹配的子字符串。
REGEXREPLACE:使用正则表达式用不同的文本字符串替换文本字符串的一部分。
SUBSTITUTE:用字符串中的新文本替换现有文本。
REPLACE:用不同的文本字符串替换文本字符串的一部分。
你可以像这样直接将这些输入到一个单元格中,并会产生你想要的任何东西
=REGEXMATCH(A2, "[0-9]+")
Run Code Online (Sandbox Code Playgroud)
它们与其他函数(例如IF语句)结合使用时也能很好地工作,如下所示:
=IF(REGEXMATCH(E8,"MiB"),REGEXEXTRACT(E8,"\d*\.\d*|\d*")/1000,IF(REGEXMATCH(E8,"GiB"),REGEXEXTRACT(E8,"\d*\.\d*|\d*"),"")
Run Code Online (Sandbox Code Playgroud)
希望这为那些被 Excel 的 VBS 组件嘲笑的用户提供了一个简单的解决方法。
为了增加有价值的内容,我想创建一个关于为什么有时 VBA 中的 RegEx 并不理想的提醒。并非所有表达式都受支持,而是可能会抛出一个Error 5017并可能让作者猜测(我是自己的受害者)。
虽然我们可以找到一些资源什么是支持的,这将是有益的知道哪些元字符等的不支持。更深入的解释可以在这里找到。在这个来源中提到:
“虽然”VBScript 的正则表达式... 5.5 版实现了许多基本的正则表达式功能,而这些功能在以前的 VBScript 版本中是缺失的。... JavaScript 和 VBScript 实现 Perl 风格的正则表达式。但是,它们缺乏 Perl 和其他现代正则表达式风格中可用的许多高级功能:”
所以,不支持的是:
\A,或者使用^插入符号匹配字符串中第一个字符之前的位置\Z,或者使用$美元符号匹配字符串中最后一个字符之后的位置(?<=a)b(同时阳性预读的支持)(?<!a)b(同时排除模式的支持)\{uFFFF}/i区分大小写)或/g(全局)等。通过RegExp对象属性 >RegExp.Global = True以及RegExp.IgnoreCase = True如果可用进行设置。'在脚本中使用常规注释添加这些我已经不止一次在 VBA 中使用正则表达式了。通常使用LookBehind但有时我什至忘记了修饰符。我自己没有经历过上述所有这些背景,但我想我会尝试广泛参考一些更深入的信息。随意评论/更正/添加。对regular-expressions.info的大量信息大喊大叫。
PS您提到了常规的 VBA 方法和函数,我可以确认它们(至少对我自己而言)在 RegEx 失败的情况下以自己的方式有所帮助。
我需要将其用作单元函数(如SUM或VLOOKUP),发现很容易:
在工作簿中或在其自己的模块中创建以下函数:
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
Run Code Online (Sandbox Code Playgroud)然后,您可以在单元格中使用=REGPLACE(B1, "(\w) (\d+)", "$1$2")(例如:“ A 243”至“ A243”)
Here is a regex_subst() function. Examples:
=regex_subst("watermellon", "[aeiou]", "")
---> wtrmlln
=regex_subst("watermellon", "[^aeiou]", "")
---> aeeo
Run Code Online (Sandbox Code Playgroud)
Here is the simplified code (simpler for me, anyway). I couldn't figure out how to build a suitable output pattern using the above to work like my examples:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
819131 次 |
| 最近记录: |