介绍
(你可以跳到如果……如果你厌倦了介绍)
这个问题并不是特别针对 VBScript(我只是在这种情况下使用它):我想找到一个通用正则表达式使用的解决方案(包括编辑器)。
这开始于我想创建示例 4 的改编版本,其中 3 个捕获组用于在 MS Excel 中的 3 个单元格之间拆分数据。我需要捕获一个完整的模式,然后在其中捕获 3 个其他模式。但是,在同一个表达式中,我还需要捕获另一种模式,并再次捕获其中的 3 个其他模式(是的,我知道……但在指向 nutjob 手指之前,请完成阅读)。
我首先想到了命名捕获组,然后我意识到我不应该“混合命名和编号的捕获组”,因为它“不推荐,因为这些组的编号方式不一致”。
然后我查看了VBScript SubMatches和«non-capturing»组,我得到了针对特定情况的有效解决方案:
For Each C In Myrange
strPattern = "(?:^([0-9]+);([0-9]+);([0-9]+)$|^.*:([0-9]+)\s.*:([0-9]+).*:([a-zA-Z0-9]+)$)"
If strPattern <> "" Then
strInput = C.Value
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
Set rgxMatches = regEx.Execute(strInput)
For Each mtx In rgxMatches
If mtx.SubMatches(0) <> "" Then
C.Offset(0, 1) = mtx.SubMatches(0)
C.Offset(0, 2) = mtx.SubMatches(1)
C.Offset(0, 3) = mtx.SubMatches(2)
ElseIf mtx.SubMatches(3) <> "" Then
C.Offset(0, 1) = mtx.SubMatches(3)
C.Offset(0, 2) = mtx.SubMatches(4)
C.Offset(0, 3) = mtx.SubMatches(5)
Else
C.Offset(0, 1) = "(Not matched)"
End If
Next
End If
Next
124;12;3
我的 id1:213 我的 id2:232 我的话:ins4yanrgx
:8587459 :18254182540215 :dcpt
0;1;2
它返回带有数字的前 2 个单元格和带有数字或单词的第3个单元格。基本上,我使用了一个具有 2 个“父”模式的非捕获组(“父”= 我想检测其他子模式的广泛模式)。如果第一个父模式具有匹配的子模式(第一个捕获组),那么我将其值和该模式的剩余捕获组放在 3 个单元格中。如果不是,我检查第 4个捕获组(属于第 2 个父模式)是否匹配,并将剩余的子模式放在相同的 3 个单元格中。
如果什么...
而不是这样的:
(?:^(\d+);(\d+);(\d+)$|^.*:(\d+)\s.*:(\d+).*:(\w+)$|what(ever))
这样的事情是可能的:
(#:^(\d+);(\d+);(\d+)$)|(#:^.*:(\d+)\s.*:(\d+).*:(\w+)$)|(#:what(ever))
与其(#:
创建非捕获组,不如创建一个“父”编号的捕获组。通过这种方式,我可以执行类似于示例 4的操作:
C.Offset(0, 1) = regEx.Replace(strInput, "#$1")
C.Offset(0, 2) = regEx.Replace(strInput, "#$2")
C.Offset(0, 3) = regEx.Replace(strInput, "#$3")
它将搜索父模式,直到在子模式中找到匹配项(将返回第一个匹配项,理想情况下,不会搜索其余匹配项)。
已经有这样的事情了吗?还是我完全从正则表达式中遗漏了一些允许这样做的东西?
其他可能的变化:
- 直接引用父子模式,例如:(
#2$3
这在我的示例中相当于$6
); - 在其他人中根据需要创建尽可能多的捕获组(我想这会更复杂,但也是最有趣的部分),例如:使用正则表达式(相同语法),
(#:^_(?:(#:(\d+):\w+-(\d))|(#:\w+:(\d+)-(\d+)))_$)|(#:^\w+:\s+(#:(\w+);\d-(\d+))$)
并以如下模式获取##$1
:_123:smt-4_
它会匹配:123
_ott:432-10_
它会匹配:432
yant: special;3-45235
它会匹配:特殊
如果您发现此逻辑中有任何错误或缺陷,请告诉我,我会尽快编辑。