在Perl / Tk代码中,我找到了一个条件语句,如下所示
if (s/^\+//)
{
#do something
}
elsif (/^-/)
{
#do another thing
}
似乎已经完成了一些模式匹配。但我无法理解。任何人都可以帮我理解这种模式匹配吗?
答案 0 :(得分:11)
它们都是正则表达式。您可以在perlre和perlretut阅读相关信息。您可以在http://www.rubular.com上使用它们。
他们都隐含地对$_
做了些什么。您的代码行周围可能没有while
或foreach
而没有循环变量。在这种情况下,$_
成为该循环变量。例如,它可能包含正在读取的文件的当前行。
$_
的当前值包含+
(加号)符号作为字符串开头的第一个字符#do somehting
。 -
(减号),#do another thing
。 在案例1中,它也用任何内容替换+
符号(即删除它)。它不会删除2.中的-
。
让我们看一下YAPE::Regex::Explain的解释。
use YAPE::Regex::Explain;
print YAPE::Regex::Explain->new(qr/^\+/)->explain();
在这里。在我们的案例中并没有真正帮助,但仍然是一个很好的工具。请注意,(?-imsx
和)
部分是Perl暗示的默认内容。除非你改变它们,否则它们总是在那里。
The regular expression:
(?-imsx:^\+)
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
^ the beginning of the string
----------------------------------------------------------------------
\+ '+'
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
更新:正如Mikko L在评论中指出的那样,你应该重构/改变这段代码。虽然它可能会做到它应该做的,但我相信让它更具可读性是个好主意。谁写了它显然并不关心你作为后来的维护者。我建议你这样做。您可以将其更改为:
# look at the content of $_ (current line?)
if ( s/^\+// )
{
# the line starts with a + sign,
# which we remove!
#do something
}
elsif ( m/^-/ )
{
# the line starts witha - sign
# we do NOT remove the - sign!
#do another thing
}
答案 1 :(得分:5)
这些是正则表达式,用于模式匹配和替换。
你应该阅读这个概念,但至于你的问题:
s/^\+//
如果字符串以加号开头,则删除该加号(“s”表示“替换”),然后返回true。
/^-/
如果字符串以减号开头,则为真。
答案 2 :(得分:3)
此代码相当于
if ($_ =~ s/^\+//) { # s/// modifies $_ by default
#do something
}
elsif ($_ =~ m/^-/) { # m// searches $_ by default
#do another thing
}
s///
和m//
是regexp类似报价的运算符。您可以在perlop中了解它们。
答案 3 :(得分:2)
其他答案总结了代码是如何工作的,但并不是为什么。这是一个简单的例子,说明为什么人们会使用这种逻辑。
#!/usr/bin/env perl
use strict;
use warnings;
my $args = {};
for ( @ARGV ) {
if ( s/^no// ) {
$args->{$_} = 0;
} else {
$args->{$_} = 1;
}
}
use Data::Dumper;
print Dumper $args;
当你像
那样调用脚本时./test.pl hi nobye
你得到了
$VAR1 = {
'hi' => 1,
'bye' => 0
};
键是字符串,但如果前面有no
,则将其删除(以获取相关密钥),然后将值设置为0
。
OP的例子涉及更多,但遵循相同的逻辑。
+
开头,请将其删除并执行某些操作-
开头,请不要将其删除并执行其他操作