Arm*_*oot 8 regex substring match capture-group
(如果你厌倦了介绍,你可以跳到怎么办)
这个问题并不是针对VBScript的(我只是在这种情况下使用它):我想找到一般正则表达式用法的解决方案(包括编辑器).
这开始于我想要创建示例4的改编,其中3个捕获组用于在MS Excel中跨3个单元分割数据.我需要捕获一个完整的模式,然后在其中捕获3个其他模式.然而,在同一个表达式中,我还需要捕获另一种模式并再次捕获其中的3种其他模式(是的,我知道......但在指向nutjob手指之前,请完成阅读).
我首先考虑了命名捕获组,然后我意识到我不应该"混合命名和编号的捕获组",因为它不推荐«因为风格与组的编号方式不一致».
然后我查看了VBScript SubMatches和«non- capture »组,我得到了针对特定案例的工作解决方案:
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
Run Code Online (Sandbox Code Playgroud)
这是一个正则表达式的Rubular演示.在这些:
124; 12; 3
我的id1:213我的id2:232我的话:ins4yanrgx
:8587459:18254182540215:dcpt
0; 1; 2
它返回带有数字的前2个单元格,带有数字或单词的3 rd.基本上我使用了具有2个"父"模式的非捕获组("父母"=我要检测其他子模式的宽模式).如果1个ST父图案具有匹配子图案(1 ST捕获组),那么我将其值与在3个细胞这个图案的剩余捕获基团.如果没有,我检查第4 个捕获组(属于第二个父模式)是否匹配,并将剩余的子模式放在相同的3个单元格中.
而不是像这样的东西:
(?:^(\d+);(\d+);(\d+)$|^.*:(\d+)\s.*:(\d+).*:(\w+)$|what(ever))
Run Code Online (Sandbox Code Playgroud)
这样的事情是可能的:
(#:^(\d+);(\d+);(\d+)$)|(#:^.*:(\d+)\s.*:(\d+).*:(\w+)$)|(#:what(ever))
Run Code Online (Sandbox Code Playgroud)
在(#:不创建非捕获组的情况下,将创建"父"编号的捕获组.通过这种方式,我可以做类似于例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")
Run Code Online (Sandbox Code Playgroud)
它将搜索父模式,直到它找到子模式中的匹配(第一个匹配将被返回,理想情况下,不会搜索剩余的模式).
有没有这样的东西?或者我是否完全遗漏了可以执行此操作的正则表达式?
其他可能的变化:
#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它将匹配:特殊
请告诉我,如果你发现这个逻辑中有任何错误或缺陷,我会尽快编辑.
小智 5
这通常是要捕获大部分相同数据的情况。
唯一的区别是形式。
有一个名为 Branch Reset 的正则表达式构造。
它在大多数 Perl 兼容引擎上提供。不是 Java 也不是 Dot Net。
它主要只是节省了正则表达式资源并使处理匹配变得更容易。
您提到的替代方案无济于事,它实际上只是使用了
更多资源。您仍然必须查看匹配的内容才能看到您的位置。
但是您只需要检查集群中的一个组就可以知道哪些其他
组是有效的(<- 如果使用分支重置,这是不必要的)。
(下面是使用 RegexFormat 6构建的)
这是分支重置版本:
# (?|^(\d+);(\d+);(\d+)$|^.*:(\d+)\s.*:(\d+).*:(\w+)$|what(ever)()())
(?|
^
( \d+ ) # (1)
;
( \d+ ) # (2)
;
( \d+ ) # (3)
$
|
^ .* :
( \d+ ) # (1)
\s .* :
( \d+ ) # (2)
.* :
( \w+ ) # (3)
$
|
what
( ever ) # (1)
( ) # (2)
( ) # (3)
)
Run Code Online (Sandbox Code Playgroud)
这是你的两个正则表达式。注意“父”捕获实际上增加了组的数量(这会减慢引擎的速度):
# (?:^(\d+);(\d+);(\d+)$|^.*:(\d+)\s.*:(\d+).*:(\w+)$|what(ever))
(?:
^
( \d+ ) # (1)
;
( \d+ ) # (2)
;
( \d+ ) # (3)
$
|
^ .* :
( \d+ ) # (4)
\s .* :
( \d+ ) # (5)
.* :
( \w+ ) # (6)
$
|
what
( ever ) # (7)
)
Run Code Online (Sandbox Code Playgroud)
和
# (#:^(\d+);(\d+);(\d+)$)|(#:^.*:(\d+)\s.*:(\d+).*:(\w+)$)|(#:what(ever))
( # (1 start)
\#: ^
( \d+ ) # (2)
;
( \d+ ) # (3)
;
( \d+ ) # (4)
$
) # (1 end)
|
( # (5 start)
\#: ^ .* :
( \d+ ) # (6)
\s .* :
( \d+ ) # (7)
.* :
( \w+ ) # (8)
$
) # (5 end)
|
( # (9 start)
\#:what
( ever ) # (10)
) # (9 end)
Run Code Online (Sandbox Code Playgroud)