非捕获子程序

时间:2017-06-15 16:28:45

标签: regex regex-group boost-regex

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

例如,假设我想以递归方式匹配并捕获平衡括号{}结构,如

  

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

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

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

第一组是我想捕捉的。

然而我对'nest'的定义:

(?'nest' ... )

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

(?&nest)

也在捕捉群组。我想通过不捕获这些组来提高我的正则表达式效率并节省空间。有没有办法做到这一点?

编辑:我希望不能捕获子程序定义,因为需要捕获其模式以供其他地方使用。

EDIT2:

我正在使用boost :: regex以及notepad ++ 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: \1 \n \\2: \2 \n 3: \3 \n 4: \4

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

然而boost :: regex_match返回一个有6个位置的对象:

0:匹配的元数据

1:整场比赛

2:整场比赛

3:来自notepad ++的group1

4:来自notepad ++的group2

5:来自notepad ++的group3

我仍然试图发送第1和第2位。

EDIT3

我误解了另一块难题......

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

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

3 个答案:

答案 0 :(得分:1)

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

在子程序调用中不使用捕获组的唯一方法是使用整个模式的快捷方式, (?R) 。但是,当您需要递归模式的部分时,它不是一个选项(在您的情况下,您希望匹配字符串的开头,并且仅在{{1}之后递归模式部分}。

答案 1 :(得分:1)

放入(?(DEFINE)。)构造的任何子程序都不会捕获任何东西。

如果你只是想避免任何捕获,那就像这样做了

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

请注意 -

  

子模式定义构造(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
  可能只用于定义函数。此组中没有匹配。

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

既然你有那个BOS锚点^,这是唯一的方法 即(?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

答案 2 :(得分: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)

你想用它做什么?