perl 平衡结构

perl balanced constructs

给定以下输入:

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

以下产生了预期的输出(它去掉了外括号之外的所有内容)

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

顺便说一下,我从 https://www.regular-expressions.info/recurse.html 那里抓到了那个。但是,它已被修改为 1) 捕获,并且 "balanced" 部分位于非捕获组中。这个想法是我可以做到的

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

不修改(被认为是我的开场白。 (因为显然尝试将 utMemAlloc() 匹配不会很好地工作。)

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

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

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

顺便说一下,下面的命令产生了预期的输出,但出于几个原因我宁愿避免它(其中之一是 $RE{balanced} 似乎在整个 shell 实例,每当我用错它时):

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

选读

我更愿意避免 Regexp::Common 的另一个原因是我经常在 git UI 提供的 mingw 终端中使用 perl。基本上是为了避免必须通过推送代码git 到 linux 框。我最终得到的 actual 代码(感谢当前答案)是:

$ 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 的第二次测试是必要的,因为在第一个表达式中有两个捕获组,当我试图将内部的捕获组设为非捕获组时,整个表达式再次停止工作。这行得通,但是太丑了。

使用 $^R 你递归到整个模式的开头,显然这不是你想要的。
如果递归到括号字符,您将获得所需的结果:

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


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