在 Perl/Tk 代码中,我发现了如下条件语句
if (s/^\+//)
{
#do something
}
elsif (/^-/)
{
#do another thing
}
似乎已经完成了一些模式匹配。但我无法理解。谁能帮我理解这种模式匹配?
它们都是正则表达式。您可以在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
}
这些是正则表达式,用于模式匹配和替换。
你应该阅读这个概念,但至于你的问题:
s/^\+//
如果字符串以加号开头,则删除该加号(“s”表示“替换”),并返回 true。
/^-/
如果字符串以减号开头,则为真。
这段代码相当于
if ($_ =~ s/^\+//) { # s/// modifies $_ by default
#do something
}
elsif ($_ =~ m/^-/) { # m// searches $_ by default
#do another thing
}
s///
并且m//
是 regexp 类似引号的运算符。您可以在perlop中了解它们。
其他答案总结了代码的工作原理,但并没有说明原因。这是一个简单的例子,说明为什么人们可能会使用这种逻辑。
#!/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 的示例涉及更多一点,但遵循相同的逻辑。
+
,请将其删除并执行某些操作-
,请不要删除它并执行其他操作