给出一个带引号的字符串,提取所有这些子字符串
我已经编写了以下代码,但是有些东西告诉我它很丑(尽管确实可以解决问题)
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
因此它确实按预期工作。
答案 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
)来避免这种情况。修改目标字符串还会重置搜索位置。
(强调我的。)