2009-06-18 53 views
1

我期待通过Perl代码,我看到:Perl的for循环的解释

sub html_filter { 
    my $text = shift; 
    for ($text) { 
     s/&/&/g; 
     s/</&lt;/g; 
     s/>/&gt;/g; 
     s/"/&quot;/g; 
    } 
    return $text; 
} 

什么的for循环在这种情况下做的,为什么你会做这种方式?

回答

5

没有明确的循环变量,for循环使用称为$_的特殊变量。循环中的替换语句使用特殊的$_变量,因为没有指定其他变量,所以这只是缩短源代码的一个技巧。我可能会写这个函数为:

sub html_filter { 
    my $text = shift; 
    $text =~ s/&/&amp;/g; 
    $text =~ s/</&lt;/g; 
    $text =~ s/>/&gt;/g; 
    $text =~ s/"/&quot;/g; 
    return $text; 
} 

这将不会带来任何性能影响,并且可以被Perl以外的人阅读。

+0

你喜欢样板吗? – Svante 2009-06-18 22:22:04

+0

你是否暗示原作不可读? – 2009-06-19 16:31:12

2

它只是用来将$ text替换为默认变量$ _。完成是因为他们懒得使用显式变量或不想浪费宝贵的周期来创建新的标量。

2

它的清理&,<,>和引用字符,并用适当的HTML实体字符替换它们。

8

for循环会将列表中的每个元素别名循环到$_。在这种情况下,只有一个元素$text

在体内,这允许一个写

s/&/&amp;/g; 

等,而不必编写

$text =~ s/&/&amp;/g; 

反复。另见perldoc perlsyn

+1

但是,这种编码正是你想要的。该功能使用未编码的数据并对其进行编码。如果字符串“&”出现在未编码的文本中,则编码结果肯定应该是“& amp;”。 – 2009-06-18 21:51:12

+0

将&转换为& amp;有时候是你想要的。 html_filter将转义xml/html/xhtml,以便浏览器以您可以阅读的方式呈现xml,对代码示例很有用,例如, – 2009-06-18 21:51:56

1

它通过循环文字和替代符号(&)与&放大器,<与& LT,>与& GT和“与& QUOT。你会输出这样做是为了一个html的文件......那些是正确的实体字符

1

原代码可以通过使用wantarray测试所需的环境下更灵活。

sub html_filter { 
    my @text = @_; 
    for (@text) { 
     s/&/&amp;/g; 
     s/</&lt;/g; 
     s/>/&gt;/g; 
     s/"/&quot;/g; 
    } 
    return wantarray ? @text: "@text"; } 

这样,你可以把它在列表环境或标量上下文,并获得BAC k是正确的结果,例如:

my @stuff = html_filter('"','>'); 
print "$_\n" for @stuff; 

my $stuff = html_filter('&'); 
print $stuff; 
5

由于Hewgill先生所指出的,该代码示例是隐式定位和混叠$ _,神奇的隐含变量。

他提供了一个替代品,代价是样板代码更易读。

为简洁起见,没有理由牺牲可读性。只需更换隐含的定位和分配有明确的版本:

sub html_filter { 
    local $_ = shift; 

    s/&/&amp;/g; 
    s/</&lt;/g; 
    s/>/&gt;/g; 
    s/"/&quot;/g; 

    return $_; 
} 

如果我不知道的Perl那么好和跨越这些代码来了,我就知道,我需要看看文档为$_local - 作为perlvar的奖励,有几个examples of localizing $_

对于任何使用Perl的人来说,上面应该很容易理解。

所以在这里没有理由为了简洁而牺牲可读性。