【问题标题】:Perl - Problem with "]" in a regular expressionPerl - 正则表达式中的“]”问题
【发布时间】:2019-03-16 13:50:01
【问题描述】:

我有一个字符串:

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

【问题讨论】:

  • "但它不返回任何内容" - 您显示的正则表达式不关心除括号外的任何特定字符;它应该捕获函数名称和所有带有或不带有[] 的参数。然后你可以在下一步解析参数,这是我推荐的(而不是单个怪物正则表达式)
  • @zdim 我想这样做,但是对于字符串包含“[”或“]”的行,没有匹配项。更令人惊讶的是,当只有“[”或“]”时,匹配是可以的,但是当它们都存在时,我没有得到任何匹配

标签: regex perl


【解决方案1】:

您显示的正则表达式捕获了函数名称以及字符串中的所有其他参数,这是非常合理的第一步。然后从第二个字符串中解析出参数。我扩展了您的$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 参数1 arg2 arg5 arg3,arg4 arg6,arg7

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

然后您可以继续从括号中的列表中提取单个参数,方法是将@arg_list 中的每个字符串再次拆分为,。


上面的主要部分可以,就问题而言,进入一个语句

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

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

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

【讨论】:

  • 数组@m 也可以使用@m = split(/\)|\(/,$s); 获得对吧?
  • @stack0114106 是的,就像@p 在最后完成。我没有特殊原因使用正则表达式(我使用了 split recently
【解决方案2】:

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

解释:

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

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

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

\(, \) 0 匹配 (, ) 字面意思

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

Demo

更新:

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

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

Updted demo

【讨论】:

  • 谢谢你的解释,很清楚。但是我应该提供更多细节:我的 $string 语法可以是各种不同的:name_of_my_function(arg1,arg2,arg3) 或 name_of_my_function(arg1,arg2,[arg3,arg4]) 或 name_of_my_function("arg1")。参数也可以是字符串或数字(双精度或整数)......所以你的解决方案对我不起作用,但我应该更清楚抱歉
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多