【发布时间】:2015-06-13 08:55:26
【问题描述】:
这是一个小问题,但我担心我在做傻事。我正在使用 Regexp::Common 来匹配匹配的括号正则表达式,但我需要括号的 contents,而不是整个表达式。所以我最终存储了一个临时字符串,对该字符串执行匹配后替换以摆脱括号,然后继续前进。所以想象一下我在“sphincter(arg1,arg2)”这一行上运行以下脚本(我正在写一个最小的例子,所以我希望它是可以理解的)。
use Regexp::Common;
$PAREN_EXP = $RE{balanced}{-parens=>'()'};
$line =~ /foo$PAREN_EXP/;
$temp = $1; temp now stores (arg1,arg2)
$temp =~ s/\((.*)\)/$1/; # temp is now arg1,arg2
$line =~/(.*)\($temp\)/close\($1,$temp\)/;
结果该行现在是“close(sphinter, arg1, arg2)”,加上或减去我在执行示例时所犯的任何错误。现在这对我来说没问题,但我经常这样做,我想知道是否有更简单的方法?有没有办法让 Regexp::Common 库只给我内容?有没有办法让我定义 $PAREN_EXP 让它给我我喜欢的东西?有人看到更好的方法吗?
更好是指更小而不变成只写代码。
【问题讨论】:
-
这感觉像是一个 XY 问题。你想达到什么目的? meta.stackexchange.com/questions/66377/what-is-the-xy-problem
-
Regexp::Common::balanced 当您可以嵌套括号时会有所帮助,但您的示例只有一对:
(arg1,arg2)如果您的数据不包含嵌套括号,我会这样做使用单个替换,例如:s/ (.*) \( (.*) \) /close($1,$2)/x。您可以使用x修饰符来忽略 LHS 上的空格,这样您就可以将内容隔开以提高可读性,甚至可以将它们拆分为多行并添加 cmets。您还可以使用命名捕获来阐明每个捕获组的作用,例如s/ (?<func> .*) \( (?<args> .*) \) /close($+{func},$+{args})/x; -
我的例子只是我能想出的最简单的例子来说明我的问题。我认为很明显,我只在有意义的情况下才对这样做感兴趣。显然情况并非如此。我正在替换复杂的 C++ 表达式,例如 foo(几个参数经常与嵌套括号的任意深度),而我正在做的事情解决了这个问题——我还可以编写递归解析或递归正则表达式,但到目前为止,这已被证明是最方便的。
-
@Spacemoose 请edit您的问题包括您实际使用的输入示例和预期输出。
-
@ThisSuitsBlackNot:是的,我可能不会——你为什么不从不同的角度考虑这个问题:Perl 有一个我觉得在很多情况下都非常有用的模块。如果我可以使用与非常稀疏的文档提供的稍微不同的方式,我会发现它会更好,我想知道是否有人知道如何做我想做的事情。不知道的人不要担心,这个问题不是针对你的。