正则表达式:捕获组中的捕获组

臂足

介绍

如果您对介绍无聊,可以跳到如果......,该怎么办

这个问题不是特别针对VBScript的(在这种情况下,我只是使用了它):我想找到一种解决常规正则表达式用法的方法(包括编辑器)。

当我想创建示例4的改编版本时,它开始了,其中3个捕获组用于在MS Excel中将数据拆分为3个单元格我需要捕获一个完整的模式,然后在其中捕获其他三个模式。但是,在同一个表达式中,我还需要捕获另一种模式,并再次捕获其中的3种其他模式(是的,我知道...但是在指着裸露的手指之前,请先完成阅读)。

我首先想到了命名捕获组,然后我意识到我不应该“混合命名和编号的捕获组”,因为不建议使用“混合命名和编号的风味,因为它们的编号方式不一致”

然后,我研究了VBScript子匹配“非捕获”组,并得到了针对特定情况的有效解决方案:

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

这是正则表达式的Rubular中的演示在这些:

124; 12; 3
我的id1:213我的id2:232我的词:ins4yanrgx
:8587459:18254182540215:dcpt
0; 1; 2

它返回前两个带有数字的单元格,第三个返回带有数字或单词的单元格。基本上,我使用了一个非捕获组,该组具有2个“父”模式(“父” =我要检测其他子模式的广泛模式)。如果1个ST父图案具有匹配子图案(1个ST捕获组),那么我将其值与在3个细胞这个图案的剩余捕获基团。如果不匹配,则检查第四捕获组(属于第二个父模式)是否匹配,并将其余的子模式放在相同的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在我的示例中是等效的);
  • 根据需要在其他对象之间创建尽可能多的捕获组(我想这会更复杂,但同时也是最有趣的部分),例如:使用regex(相同的语法),(#:^_(?:(#:(\d+):\w+-(\d))|(#:\w+:(\d+)-(\d+)))_$)|(#:^\w+:\s+(#:(\w+);\d-(\d+))$)##$1以类似的方式获取

    _123:smt-4_它会匹配:123
    _ott:432-10_它会匹配:432
    yant: special;3-45235它会匹配:特殊

如果您发现此逻辑中有任何错误或缺陷,请告诉我,我将尽快进行编辑。

用户名

通常是要捕获几乎相同的数据的情况。
唯一的区别在于形式。

有一个用于分支重置的正则表达式构造。
它在大多数与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)
 )

这是您的两个正则表达式。请注意,“父级”捕获实际上增加了组的数量(这降低了引擎的速度):

 # (?:^(\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)
 )

    # (#:^(\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)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

正则表达式捕获:将整个匹配项包含在捕获组中

来自分类Dev

Javascript正则表达式中的非捕获组

来自分类Dev

正则表达式:捕获组?

来自分类Dev

正则表达式非捕获组-没用吗?

来自分类Dev

正则表达式非捕获组ins Scala

来自分类Dev

正则表达式在Visual Studio中捕获组

来自分类Dev

正则表达式可选部分中的捕获组

来自分类Dev

正则表达式从红宝石中的非捕获组捕获

来自分类Dev

Vim中的正则表达式以匹配组捕获

来自分类Dev

重复正则表达式捕获组的捕获部分

来自分类Dev

正则表达式中捕获组的奇怪行为

来自分类Dev

R正则表达式中的非捕获组

来自分类Dev

在捕获的组正则表达式上修剪空间

来自分类Dev

gsub中的Ruby正则表达式捕获组

来自分类Dev

Scala正则表达式中的多个捕获组

来自分类Dev

Grep非捕获组和同一正则表达式中的捕获组。仅打印捕获组

来自分类Dev

正则表达式中的非捕获组

来自分类Dev

如何捕获正则表达式中的可选组?

来自分类Dev

捕获MS Word正则表达式中的组

来自分类Dev

使用Python正则表达式在非捕获组中的多个捕获组

来自分类Dev

正则表达式捕获:将整个匹配项包含在捕获组中

来自分类Dev

正则表达式,捕获组

来自分类Dev

正则表达式捕获捕获组中的第二个单词

来自分类Dev

正则表达式捕获组

来自分类Dev

正则表达式从红宝石中的非捕获组捕获

来自分类Dev

正则表达式:捕获组中的替代字符

来自分类Dev

从 bash 脚本中的正则表达式捕获组

来自分类Dev

捕获组中的正则表达式捕获组

来自分类Dev

仅在正则表达式中捕获重复组