递归地提取给定字符串中引号之间的字符串

时间:2019-06-10 14:15:34

标签: string perl extract quotes

给出一个带引号的字符串,提取所有这些子字符串

我已经编写了以下代码,但是有些东西告诉我它很丑(尽管确实可以解决问题)

my $str = 'printf ("hellp;world", and "this is ; also" and )';

loop:
if ($str =~ /"(.*?)"/) {
    my $substr = $1;
    $str =~ s/"$substr"//;
    print "$substr\n";
}
if ($str =~ /"/) {
    goto loop;
}
perl quotes.pl
hellp;world
this is ; also

因此它确实按预期工作。

1 个答案:

答案 0 :(得分:2)

您可以通过在任意一个标量上下文中使用/g regex标志直接完成此操作:

while ($str =~ /"([^"]*)"/g) {
    print "$1\n";
}

...或列表上下文:

for my $match ($str =~ /"([^"]*)"/g) {
    print "$match\n";
}

我也将.*?更改为[^"]*,因为最好明确要匹配的内容。

/g记录在perldoc perlop中:

  

/g修饰符指定全局模式匹配-也就是说,在字符串内尽可能多地匹配。它的行为取决于上下文。 在列表上下文中,它返回与正则表达式中的任何捕获括号匹配的子字符串的列表。如果没有括号,则返回所有匹配的字符串的列表,就像周围有括号一样整个模式。

     

在标量上下文中,每次执行m//g都会找到下一个匹配项;如果匹配,则返回true;如果没有其他匹配项,则返回false。最后一个匹配项之后的位置可以是使用pos()函数进行读取或设置;参见"pos" in perlfunc。匹配失败通常会将搜索位置重置为字符串的开头,但是您可以通过添加/c修饰符(例如m//gc)来避免这种情况。修改目标字符串还会重置搜索位置。

(强调我的。)