Perl-正则表达式中带有“]”的问题

时间:2019-03-15 07:14:08

标签: regex perl

我有一个字符串:

my $string = "name_of_my_function(arg1,arg2,[arg3,arg4])";

我想提取函数“ name_of_my_function”的名称和参数:

$arg1 = "arg1"
$arg2 = "arg2"
@arg_list = ("arg3", "arg4")

我用来提取函数的代码是:

$row =~ m/^([^\(]*)\(([^\)]*)\)/;
$function = $1;

但是,当字符串没有任何"]"时,它就可以工作,例如:

my $string = "name_of_my_function(arg1,arg2,arg3)";

但是当有"]"

时不会返回任何内容

有什么主意吗?

谢谢

SLP

2 个答案:

答案 0 :(得分:4)

您显示的正则表达式捕获函数名称以及字符串中的所有其他参数,这是非常合理的第一步。然后从第二个字符串中解析出参数。我将您的$string扩展为具有多个带括号的参数列表,这些列表与非带括号的参数交织在一起

perl -wE'
    $s = "name_of_my_function(arg1,arg2,[arg3,arg4],arg5,[arg6,arg7])"; 
    @m = $s =~ /^([^\(]*)\(([^\)]*)\)/; 
    @p = grep { $_ } split /\s*,\s*|\[(.*?)\]/, $m[1];
    for (@p) { 
        if (/,/) { push @arg_list, $_ }
        else     { push @args, $_ }
    }
    say $m[0];
    say for @args; 
    say for @arg_list
'

此打印

name_of_my_function
arg1
arg2
arg5
arg3,arg4
arg6,arg7

split是在其中提取各个参数以及带括号的参数列表(每个参数都作为字符串)的位置。这可能返回空元素,因此grep { $_ }会将其过滤掉。

然后,您可以通过再次将@arg_list中的每个字符串除以,来从方括号中的列表中提取单个参数。


上面的的主要部分可以,按照问题所在,只用一条语句

@p = grep { $_ } split /\( | \) | \[(.*?)\] |,/x, $s;

我在其中添加了/x修饰符,以便能够将其隔开以提高可读性。这样会向@p提供函数名称,各个参数以及每个[]中带有参数列表(以逗号分隔)的字符串。

但是,我认为将其分解为几步更为明智。

答案 1 :(得分:2)

好吧,如果参数的数目是可变的,那么仅使用rgex进行操作就不是那么简单(参数将与+量词匹配,因此它们不会存储在捕获组中,易于提取)。考虑到上述情况,您可以使用此模式(\w+)\(((\w+|\[(\w+,?)+\]),?)+\)

说明:

(\w+)-匹配一个或多个单词字符(函数名称)并将其存储在第一个捕获组中,

(\w+|\[(\w+,?)+\])-交替:匹配\w+(与上面相同)或\[(\w+,?)+\]\[-匹配[(\w+,?)+-匹配一次或多次\w+,模式,该模式是一个或多个单词字符,后跟一个或零个逗号(,?\]-从字面上匹配]

((\w+|\[(\w+,?)+\]),?)+-匹配上述整个模式,并可选地后跟一个或多个逗号(,?)。这将与参数列表匹配。

\(\) 0个字面上匹配()

进一步处理-提取括号()之间的内容以便以编程方式提取参数列表-使用复杂的正则表达式会更容易

Demo

更新

尝试模式:https://regex101.com/r/wBcJZ0/3

我省略了解释,因为它与以前的模式非常相似。

Updted demo