帮助理解Perl中的全局标志

11
据我所知,在 Perl 中,全局'/g'标志意味着搜索将替换/返回字符串中的所有匹配项。但是我无法理解它在匹配过程中对全局变量产生的影响,有人能够解释一下为什么这两个示例程序的输出有所不同吗:

版本1:

my $text = 'This is sample float value 3.2 ';

getFloat();
getFloat();

sub getFloat(){
    if ($text =~ /([0-9]+?)(.?)([0-9]+?)/is){
        print "matched> $1$2$3 ";
    }
}

输出: 匹配成功> 3.2 匹配成功> 3.2

版本2:(带有全局标志)

my $text = 'This is sample float value 3.2 ';

getFloat();
getFloat();

sub getFloat(){
    if ($text =~ /([0-9]+?)(.?)([0-9]+?)/gis){
        print "matched> $1$2$3 ";
    }
}

输出: matched> 3.2

从输出可以看出,使用全局标志(matching)只会匹配一次。有人能解释这种行为吗?


你应该查看perldoc perlretut - TLP
你期望什么?你希望它一直匹配,直到不匹配为止吗?那不意味着 if 条件将永远为假吗?简而言之,if (/.../g) 没有意义。 - ikegami
2个回答

12
使用 g 修饰符,字符串会记住上一次匹配的位置,因此您可以在 while 循环中使用 g 请求一个匹配并找到所有的匹配。
没有 g,每次都会重新开始查找,并且总是找到第一个匹配项。
在您的情况下,使用 g 时,第一次匹配了 3.2,但第二次尝试匹配时,就没有更多的匹配项了。
没有 g,您可以调用 getFloat() 无数次,并始终找到第一个匹配项。

9
/g 用于列表上下文时,=~ 返回所有匹配项。当在标量上下文中使用 /g 时,=~ 每次只返回一个匹配项,当没有更多匹配项时则失败(返回 undef),然后再从字符串开头重新开始。您可以通过使用 /gc 来防止这种情况的发生。您还可以使用 pos($text) 函数来查找或设置匹配开始的位置。
如果没有 /g=~ 每次都返回相同的匹配项。这相当于每次将 pos($text) 设置为 undef。在列表上下文中,=~ 返回捕获的列表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接