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
)
我的最终目标是在参数列表中找到使用 pDestinationString
的 utMemAlloc
实例。
顺便说一下,下面的命令产生了预期的输出,但出于几个原因我宁愿避免它(其中之一是 $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
)
给定以下输入:
$ 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
)
我的最终目标是在参数列表中找到使用 pDestinationString
的 utMemAlloc
实例。
顺便说一下,下面的命令产生了预期的输出,但出于几个原因我宁愿避免它(其中之一是 $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
)