我有一个字符串:
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
答案 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个字面上匹配(
,)
进一步处理-提取括号()
之间的内容以便以编程方式提取参数列表-使用复杂的正则表达式会更容易
更新:
尝试模式:https://regex101.com/r/wBcJZ0/3
我省略了解释,因为它与以前的模式非常相似。