【发布时间】:2018-03-22 23:02:03
【问题描述】:
给定以下输入:
$ cat liltester
if ((ret = utMemAlloc(
pManeuverObj->util.hMemory,
1,
(usTxtLen + 1),
(void **)&pMnvr->Context.pDestinationString
)) < 0)
以下产生预期的输出(它去掉了外部括号之外的所有内容)
$ 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
)
我的最终目标是在参数列表中找到使用 pDestinationString 的 utMemAlloc 实例。
顺便说一下,下面会产生预期的输出,但我宁愿避免它有几个原因(其中一个原因是$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 的第二次测试是必要的,因为第一个表达式中有两个捕获组,当我尝试使内部的一个非捕获组时,整个表达式再次停止工作。这行得通,但是太丑了。
【问题讨论】:
-
你考虑过核心Text::Balanced吗?它不会炸毁任何东西。参见例如this post
-
@zdim - 下次我会检查它。我不确定学习这种语法是否值得。 (另请参阅我的问题底部的编辑)
-
@zdim - 抱歉,“this”是指我尝试使用的语法,而不是您的建议。
-
Aaand,我发现内存错误。万岁 perl。