perl平衡结构

时间:2018-03-22 23:02:03

标签: regex perl pcre

给出以下输入:

$ cat liltester
      if ((ret = utMemAlloc(
                   pManeuverObj->util.hMemory,
                   1,
                   (usTxtLen + 1),
                   (void **)&pMnvr->Context.pDestinationString
                 )) < 0)

以下产生预期的输出(它剥去了外部parens之外的所有内容)

$ perl -0 -ne 'print $1 if /((?:\((?>[^()]|(?R))*\)))/g' liltester

顺便说一句,我从https://www.regular-expressions.info/recurse.html抓住了这个。但是,它被修改为1)捕获,并且“平衡”部分位于非捕获组内。这个想法是我可以做到这一点

$ perl -0 -ne 'print $1 if /(utMemAlloc(?:\((?>[^()]|(?R))*\)))/g' liltester

没有修改(被视为我的开场白。 (显然,尝试将utMemAlloc()匹配效果不佳。)

但是,输出是一个空行。预期产出是:

utMemAlloc(
                   pManeuverObj->util.hMemory,
                   1,
                   (usTxtLen + 1),
                   (void **)&pMnvr->Context.pDestinationString
                 )

我的最终目标是,在参数列表中找到utMemAlloc使用pDestinationString的实例。

顺便提一下,下面会产生预期的输出,但是我宁愿避免它出于几个原因(其中一个原因是$RE{balanced}似乎在我使用它的时候为整个shell实例炸毁了perl错误):

perl -MRegexp::Common -0 -ne 'print $1 if /(utMemAlloc$RE{balanced}{-parens=>'"'"'()'"'"'})/g' liltester

可选阅读

我更喜欢避免Regexp::Common的另一个原因是我经常在git UI提供的mingw终端中使用perl ..基本上避免将代码通过git推送到linux盒子。我最终得到的实际代码(感谢当前的答案)是:

$ git grep -l 'pDestinationString' | 
xargs perl -0 -lne 'print for /(utMemAlloc\s*(\((?>[^()]|(?-1))*\)))/g' | 
perl -0 -ne 'print "$_\n\n\n" if /utMemAlloc[\s\S]*pDestinationString/'

对于utMemAlloc的第二次测试是必要的,因为第一个表达式中有两个捕获组,当我尝试使内部捕获组成为非捕获组时,整个表达式再次停止工作。这很有效,但这太可怕了。

1 个答案:

答案 0 :(得分:1)

With $^R you recurse to the beginning of the whole pattern, apparently this is not what you want.
If you recurse to the paren character you will get the desired result:

perl -0 -ne 'print $1 if /(utMemAlloc(\((?>[^()]|(?-1))*\)))/g' liltester


utMemAlloc(
               pManeuverObj->util.hMemory,
               1,
               (usTxtLen + 1),
               (void **)&pMnvr->Context.pDestinationString
             )