使用Regexp :: Common获取匹配的括号,不带括号

时间:2015-06-11 19:48:51

标签: regex perl

这是一个小问题,但我担心我做的很傻。我使用Regexp :: Common来匹配匹配括号的正则表达式,但我需要括号的内容,而不是整个表达式。所以我最终存储了一个临时字符串,在该字符串上执行匹配后替换以消除parens,并继续前进。因此,想象一下我在线上运行以下脚本" 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\)/; 

结果是行现在"关闭(sphinter,arg1,arg2)",加上或减去我做这个例子的任何错误。现在这对我来说没问题,但我经常这样做,我想知道是否有更简单的方法吗?有没有办法让Regexp :: Common库给我内容?有没有办法让我定义$ PAREN_EXP,以便它能给我我喜欢的东西?有人看到更好的方法吗?

更好,我的意思是更小而不会成为只写代码。

1 个答案:

答案 0 :(得分:1)

你不能用Regexp::Common::balanced执行此操作,因为它生成的正则表达式只包含一个捕获组,它包含最外面的一组括号:

$ perl -MRegexp::Common=balanced -E 'say $RE{balanced}{-parens=>"()"}'
(?^:((?:\((?:(?>[^\(\)]+)|(?-1))*\))))
    ^                               ^
    |                               |
    +-------------HERE--------------+

幸运的是,Regexp::Common允许您define your own regexes,因此您可以使用方便的$RE{foo}语法:

use strict;
use warnings;
use 5.010;

use Regexp::Common qw(pattern);

pattern name   => [qw(inside_parens)],
        create => q/(?x: ( \( ( (?: (?> [^()]+ ) | (?-2) )* ) \) ) )/
        ;

say $2 if 'foo(bar(baz,bat), qux())' =~ /foo$RE{inside_parens}/;

输出:

bar(baz,bat), qux()

整个括号表达式存储在$1中,而括号的内容存储在$2中。

此正则表达式是perldoc perlre Uri orgUri = new Uri("https://xxx.api.crm.dynamics.com/XRMServices/2011/Organization.svc"); ClientCredentials cc = new ClientCredentials(); cc.UserName.UserName = "abc123@xxx.onmicrosoft.com"; cc.UserName.Password = "abc123"; //GetDeviceCredentials is from the SDK helper class OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(orgUri, null, cc, GetDeviceCredentials()); orgProxy.Authenticate(); 中描述的版本的略微修改版本。