给出以下输入:
$ 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的第二次测试是必要的,因为第一个表达式中有两个捕获组,当我尝试使内部捕获组成为非捕获组时,整个表达式再次停止工作。这很有效,但这太可怕了。
答案 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
)