perl 平衡结构 [英] perl balanced constructs

查看:44
本文介绍了perl 平衡结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下输入:

$ 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
                 )

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

My end goal, for what it's worth, is to find instances of utMemAlloc that use pDestinationStringin 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆