在Perl中,if(s / ^ \ + //)的含义是什么?

时间:2012-11-22 12:09:35

标签: regex perl perltk

在Perl / Tk代码中,我找到了一个条件语句,如下所示

if (s/^\+//)
{
   #do something
}
elsif (/^-/)
{
   #do another thing
}

似乎已经完成了一些模式匹配。但我无法理解。任何人都可以帮我理解这种模式匹配吗?

4 个答案:

答案 0 :(得分:11)

它们都是正则表达式。您可以在perlreperlretut阅读相关信息。您可以在http://www.rubular.com上使用它们。

他们都隐含地对$_做了些什么。您的代码行周围可能没有whileforeach而没有循环变量。在这种情况下,$_成为该循环变量。例如,它可能包含正在读取的文件的当前行。

  1. 如果$_的当前值包含+(加号)符号作为字符串开头的第一个字符#do somehting
  2. 否则,如果它包含-(减号),#do another thing
  3. 在案例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的例子涉及更多,但遵循相同的逻辑。

  • 如果密钥以+开头,请将其删除并执行某些操作
  • 如果密钥以-开头,请不要将其删除并执行其他操作