非捕获子程序

Non-capturing subroutines

我想知道是否可以调用子例程但不捕获该调用的结果。

例如,假设我想递归匹配并捕获一个平衡的括号{}结构,例如

{dfsdf{sdfdf{ {dfsdf} }}dfsf}

我可以使用这个正则表达式:

(^(?'nest'\{(?>[^{}]|(?&nest))*\}))

第一组是我要拍的

但是我对'nest'的定义是:

(?'nest' ... )

和我对 'nest' 子例程的递归调用:

(?&nest)

也在捕获组。我想让我的正则表达式更有效率并通过不捕获这些组来节省 space 。有什么办法吗?

编辑:我预计不可能不捕获子例程定义,因为它的模式需要被捕获以用于其他地方。


编辑2:

我正在用 boost::regex 以及记事本++正则表达式测试这个正则表达式。他们实际上似乎定义了不同的捕获组,这对我来说很奇怪。我的印象是他们都默认使用 Perl 正则表达式。

无论如何,在问这个问题时,我有正则表达式:

^\w+\s+[^\s]+\s+(?'header'(?'nest'\{(?>[^{}]|(?&nest))*\}))(?>\s+[^\s]+){5}\s+(?'data'(?>\{(?>[^{}]|(?&nest))*\}))\s+(?'class'(?>\{(?>[^{}]|(?&nest))*\}))

我后来意识到它包含 'nest' 已经封装的不必要的字符。我现在有:

^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))

当我执行替换语句时,Notepad++ 为我提供了 3 个捕获组

\1:  \n \2:  \n 3:  \n 4: 

它告诉我“第 1 个已被替换,下一个未找到”。替换在 4: 之后没有文本,让我相信第 4 个捕获组不存在。

然而 boost::regex_匹配 returns 具有 6 个位置的对象:

0:比赛的元数据

1:整场比赛

2:整场比赛

3: 来自记事本++的group1

4: 来自记事本++的group2

5: 来自记事本++的group3

我仍在尝试发送位置 1 和 2。


edit3

我又误解了一块拼图...

boost::cmatch.m_subs[i] != boost::cmatch[i]

我以为他们是平等的。经过更多调试后,事实证明索引到对象的工作方式与文档中所说的完全一样。但我错误地认为该对象将包含一个反映 boost::cmatch[i] 返回内容的结构。 boost::cmatch[i] 似乎首先从 m_subs 中删除所有匹配 == false 的条目。其余条目与 boost::cmatch[i] returns 对齐。

子例程调用是一种递归 子模式 的机制。正则表达式引擎必须知道要递归哪个组,这就是为什么它需要它的 ID(如果该组是 编号 )或名称(如果它是一个命名组,就像您的情况一样) ). 非捕获组 不要存储对这些组模式的引用,因此,您不能在子例程调用中引用它们。

在子例程调用中不使用捕获组的唯一方法是使用 整个模式的快捷方式(?R)。但是,当您需要递归模式的 部分 时,这不是一个选项(在您的情况下,您想要匹配字符串的开头,并且只在 ^.

放入 (?(DEFINE).) 构造中的任何子例程都不会捕获任何内容。

如果你只是想避免被捕获,可以这样做

https://regex101.com/r/aT4TlM/1

注意 -

Subpattern definition construct (?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
May only be used to define functions. No matching is done in this group.

^(?&nest)(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))

因为你有那个 BOS 锚 ^ 这是唯一的方法。
IE。 (?R) 不是一个选项。

展开

 ^ 
 (?&nest) 

 (?(DEFINE)

      (?'nest'                      # (1 start)
           \{
           (?>
                [^{}] 
             |  (?&nest) 
           )*
           \}
      )                             # (1 end)
 )

输出

  **  Grp 0        -  ( pos 0 , len 29 ) 
 {dfsdf{sdfdf{ {dfsdf} }}dfsf}  
  **  Grp 1 [nest] -  NULL 

指标

----------------------------------
 * Format Metrics
----------------------------------
Atomic Groups       =   1

Capture Groups      =   1
       Named        =   1

Recursions          =   2

Conditionals        =   1
       DEFINE       =   1

Character Classes   =   1

回复:Edit2

这个正则表达式 ^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))

格式化为仅包含 3 个组时可以看到。

 ^ \w+ \s+ [^\s]+ \s+ 
 (?'nest'                      # (1 start)
      \{
      (?>
           [^{}] 
        |  (?&nest)
      )*
      \}
 )                             # (1 end)
 (?> \s+ [^\s]+ ){5}
 \s+ 
 ( (?&nest) )                  # (2)
 \s+ 
 ( (?&nest) )                  # (3)

你想用这个做什么?