【问题标题】:perl balanced constructsperl 平衡结构
【发布时间】: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
                 )

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

顺便说一下,下面会产生预期的输出,但我宁愿避免它有几个原因(其中一个原因是$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。

标签: regex perl pcre


【解决方案1】:

使用$^R 你递归到整个模式的开头,显然这不是你想要的。
如果您递归到括号字符,您将获得所需的结果:

perl -0 -ne 'print $1 if /(utMemAlloc(\((?&gt;[^()]|(?-1))*\)))/g' liltester


utMemAlloc(
               pManeuverObj->util.hMemory,
               1,
               (usTxtLen + 1),
               (void **)&pMnvr->Context.pDestinationString
             )

【讨论】:

  • 这回答了我的问题。好奇您是否对编辑有任何想法(底部)。还想知道如果我将utMemAlloc( 更改为utMemAlloc(?:(非捕获),为什么这会停止工作
  • 还有,祝福你curl -sN https://www.kingjamesbibleonline.org/Psalms-23-4/ | perl -0 -ne 'print $1 if /(&lt;p class='"'"'pspace'"'"'&gt;.*?&lt;\/p&gt;)/' | perl -lpe 's/\&lt;.*?\&gt;//g; s/\b\d?\K(the lord|thou\b|he\b)/Perl/gi; s/thy/Perl'"'"'s/gi; s/his/its/gi; s/(\d)/\n$1 /g'
  • @zzxyz,谢谢你的祝福,很搞笑。至于更新,您可能已经知道(?-1) 指的是最新的捕获子组,而(?: 则使子组不捕获。
  • @wolkrevokcats - 我实际上不知道(?-1)..我找不到任何提到它的参考资料。我终于开始使用它来弄清楚它指的是捕获组,这就是为什么使用非捕获组不起作用的原因。
  • 查找相关文档就像运行perldoc perlre 和搜索?R 一样简单。您甚至可以通过目录找到它 - perldoc toc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-31
  • 2018-10-07
  • 2014-10-16
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 2018-10-16
相关资源
最近更新 更多