perl 平衡结构 [英] perl balanced constructs
问题描述
给定以下输入:
$ cat liltester
if ((ret = utMemAlloc(
pManeuverObj->util.hMemory,
1,
(usTxtLen + 1),
(void **)&pMnvr->Context.pDestinationString
)) < 0)
以下产生预期的输出(它去除了外括号之外的所有内容)
The following produces the expected output (it strips out everything outside the outer parens)
$ perl -0 -ne 'print $1 if /((?:\((?>[^()]|(?R))*\)))/g' liltester
我从 https://www.regular-expressions.info/recurse.html 中获取了它 顺便说一下.但是,它已被修改为 1) 捕获,并将平衡"部分置于非捕获组内.我的想法是我可以做到这一点
I grabbed that from https://www.regular-expressions.info/recurse.html , by the way. However, it's been modified to 1) capture, and have the "balanced" portion be inside a non-capturing group. The idea being I can do this
$ perl -0 -ne 'print $1 if /(utMemAlloc(?:\((?>[^()]|(?R))*\)))/g' liltester
不修改 (
被认为是我的开场白.(显然试图将 utMemAlloc(
与 )
匹配起来效果不佳.)
without modifying (
being considered as my opening paren. (As obviously trying to match utMemAlloc(
with )
is not going to work well.)
然而,输出是一个空行.预期输出为:
However, the output is a blank line. Expected output is:
utMemAlloc(
pManeuverObj->util.hMemory,
1,
(usTxtLen + 1),
(void **)&pMnvr->Context.pDestinationString
)
我的最终目标是在参数列表中找到使用 pDestinationString
的 utMemAlloc
实例.
My end goal, for what it's worth, is to find instances of utMemAlloc
that use pDestinationString
in the parameter list.
顺便说一句,以下产生了预期的输出,但我更愿意避免它有几个原因(其中一个是 $RE{balanced}
似乎炸毁了 perl每当我使用错误时,整个 shell 实例):
The following produces the expected output, by the way, but I'd prefer to avoid it for several reasons (one of which is that $RE{balanced}
seems to blow up perl for an entire shell instance whenever I use it wrong):
perl -MRegexp::Common -0 -ne 'print $1 if /(utMemAlloc$RE{balanced}{-parens=>'"'"'()'"'"'})/g' liltester
选读
我更喜欢避免 Regexp::Common
的另一个原因是我经常在 git UI 提供的 mingw 终端中使用 perl..基本上是为了避免必须通过 git 将代码推送到 linux盒子.我最终得到的实际代码(感谢当前的答案)是:
The other reason I prefer to avoid Regexp::Common
is that I often use perl in a mingw terminal provided by a git UI..Basically to avoid having to push code through git to a linux box. The actual code I ended up with (thanks to the current answer) is:
$ 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 的第二次测试是必要的,因为第一个表达式中有两个捕获组,当我尝试将内部的组设为非捕获组时,整个表达式再次停止工作.这行得通,但太丑了.
The 2nd test for utMemAlloc was necessary because there are two capture groups in the first expression, and when I tried to make the inner one a non-capturing group, the whole expression stopped working again. This works, but it's damn ugly.
推荐答案
使用 $^R
你递归到整个模式的开头,显然这不是你想要的.
如果您递归到括号字符,您将获得所需的结果:
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
)
这篇关于perl 平衡结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!