文章背景: 最近在看同事写的VBA正则表达式,发现其中用到了非捕获组(?:Expression)。因此,本文对非捕获组的用法做了一些研究。
1 捕获组2 非捕获组3 非捕获组的应用场景
捕获是指在正则表达式中使用括号来匹配和提取一部分文本。这个被括号包裹的部分被称为捕获组,可以通过VBA代码访问和处理。例如,正则表达式(foo)\d+
会匹配以foo开头,后面跟着一个或多个数字的字符串。其中(foo)
是一个捕获组,表示我们要匹配和提取的是以foo开头的部分。
代码示例:
Sub TestRegExp()
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
Dim inputString As String
inputString = "123-45"
' 设置正则表达式模式
regex.Pattern = "(\d{3})-(\d{2})"
' 执行匹配
Dim matches As Object
Set matches = regex.Execute(inputString)
' 输出捕获组的内容
If matches.Count > 0 Then
MsgBox "捕获组 1: " & matches(0).SubMatches(0) & vbCrLf & "捕获组 2: " & matches(0).SubMatches(1)
Else
MsgBox "没有匹配"
End If
End Sub
对于正则表达式:(\d{3})-(\d{2})
,有两个捕获组,分别是 (\d{3})
和 (\d{2})
。这两个捕获组分别匹配三个数字和两个数字的模式。
代码运行结果:
非捕获是指在正则表达式中使用括号来分组,但不会创建一个新的捕获组。非捕获组以问号冒号加圆括号的形式表示,例如(?:foo)\d+
。这个正则表达式会匹配以foo开头,后面跟着一个或多个数字的字符串,但不会创建一个新的捕获组。在VBA中,我们无法访问或处理非捕获组。
代码示例:
Sub TestNonCapturingGroup()
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
Dim inputString As String
inputString = "a1234b"
' 设置正则表达式模式
regex.Pattern = "a(\d{2})(?:\d{2})b"
' 执行匹配
Dim matches As Object
Set matches = regex.Execute(inputString)
' 输出捕获组的内容
If matches.Count > 0 Then
MsgBox "捕获组 1: " & matches(0).SubMatches(0)
Else
MsgBox "没有匹配"
End If
End Sub
对于正则表达式:a(\d{2})(?:\d{2})b,(\d{2})
是一个捕获组,匹配两个数字,并且 (?:\d{2})
是一个非捕获组,也匹配两个数字。整个模式匹配的字符串是以 "a" 开头,两个数字,再加两个数字,最后是字母 "b"。
代码运行结果:
3 非捕获组的应用场景
(1) 不需要保留分组内容
当你需要对正则表达式进行分组,但不需要在后续的代码中访问或引用这些分组的内容时,非捕获组是一个好的选择。这有助于保持匹配结果的简洁性,避免生成不必要的捕获组。
(2) 提高性能
在某些情况下,使用非捕获组可以提高正则表达式的性能。捕获组需要额外的处理来存储和维护捕获的内容,而非捕获组则不需要这样的处理。如果性能是一个关键因素,可以考虑使用非捕获组来减少处理开销。
(3) 避免混淆
在某些情况下,正则表达式中可能存在多个嵌套的捕获组,如果你只关心其中的一些组,而不想引入额外的捕获组,可以使用非捕获组来避免混淆。
举例:假设我们想匹配一段文本中的日期,但只关心年份和月份,而不关心具体的日。在这种情况下,可以使用非捕获组来排除日的匹配。
正则表达式:(\d{4})-(\d{2})(?:-\d{2})?
1)在这个例子中,我们使用非捕获组 (?:-\d{2})?
来表示日的部分,但并不生成一个独立的捕获组。
2) 这个正则表达式可以匹配类似于 "2022-01" 或 "2022-01-15" 的日期格式,但我们只关心年份和月份。
参考资料:
[1] 正则表达式中 (?:)到底是什么意思(https://segmentfault.com/q/1010000010302799)
[2] 正则基础之——非捕获组(https://blog.csdn.net/lxcnn/article/details/4464908)
[3] vba捕获 非捕获(https://juejin.cn/s/vba%E6%8D%95%E8%8E%B7%20%E9%9D%9E%E6%8D%95%E8%8E%B7)
[4] Open AI