В Perl, что означает if (s/^\+//)?

В коде Perl/Tk я нашел условное выражение, как показано ниже

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

Похоже, какое-то сопоставление с образцом было сделано. Но я не могу этого понять. Может ли кто-нибудь помочь мне понять это сопоставление с образцом?

4 ответа

Они оба регулярные выражения. Вы можете прочитать о них в perlre и perlretut. Вы можете поиграть с ними на http://www.rubular.com/r/CEtqZ3YUIi.

Они оба косвенно делают что-то с $_, Там, вероятно, есть while или же foreach вокруг ваших строк кода без переменной цикла. В таком случае, $_ становится этой переменной цикла. Например, он может содержать текущую строку файла, который читается.

  1. Если текущее значение $_ содержит + (плюс) знак в качестве первого символа в начале строки, #do somehting,
  2. Иначе, если он содержит - (минус) знак, #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.

/^-/

True, если строка начинается с минуса.

Этот код эквивалентен

if ($_ =~ s/^\+//) {  # s/// modifies $_ by default
   #do something
}
elsif ($_ =~ m/^-/) {  # m// searches $_ by default
   #do another thing
}

s/// а также m// являются кавычками операторов регулярного выражения. Вы можете прочитать о них в 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 немного сложнее, но следует той же логике.

  • если ключ начинается с +, удали его и сделай что-нибудь
  • если ключ начинается с -, не удаляй это и делай что-то еще
Другие вопросы по тегам