Как соответствовать & или;или <или> или |в регулярном выражении? - PullRequest
1 голос
/ 28 августа 2011

Следующее регулярное выражение работает, чтобы подтвердить, содержит ли вход, переданный в него, строку ping

elsif($RunCommand =~ m/^\s*ping\s+(.+)/)

Теперь я хочу подтвердить, содержит ли переданный вход команду pipe |Кажется, что следующее работает неправильно:

elsif($RunCommand =~ m/^\s*|\s+(.+)/)

Для контекста у меня есть следующее условие if, elseif.Я просто добавил 5 утверждений, которые проверяют наличие & или;или <или> или |.Но он работает неправильно ... теперь он всегда идет к & PrintPageHeaderBC ("c");и попытки, содержащие ping, nslookup и т. д. (допустимые команды), теперь не выполняют то, что они должны делать.Я считаю, что проблема должна заключаться в том, что 5 добавленных мной регулярных выражений не соответствуют друг другу, и введенный текст содержит & или;или <или> или |.Любая помощь?Я уверен, что 5 отдельных утверждений, которые я сделал (возможно, неправильно), можно было бы также объединить в одно утверждение.

# First discard command attempts that contain & ; < > |, then acceptable commands are executed, then final else to non-functional command

 if($RunCommand =~ m/^\s*&\s+(.+)/)
    {
            # Print PageHeaderBC that informs of non-functional command
            &PrintPageHeaderBC("c");

    }

 elsif($RunCommand =~ m/^\s*;\s+(.+)/)
    {
            # Print PageHeaderBC that informs of non-functional command
            &PrintPageHeaderBC("c");

    }

 elsif($RunCommand =~ m/^\s*<\s+(.+)/)
    {
            # Print PageHeaderBC that informs of non-functional command
            &PrintPageHeaderBC("c");

    }

 elsif($RunCommand =~ m/^\s*>\s+(.+)/)
    {
            # Print PageHeaderBC that informs of non-functional command
            &PrintPageHeaderBC("c");

    }

 elsif($RunCommand =~ m/^\s*|\s+(.+)/)
    {
            # Print PageHeaderBC that informs of non-functional command
            &PrintPageHeaderBC("c");

    }

# Now start acceptable commands

# PING
elsif($RunCommand =~ m/^\s*ping\s+(.+)/)
{
    &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";

}
# TELNET
elsif($RunCommand =~ m/^\s*telnet\s+(.+)/)
{
    &PrintPageHeader("c");
    #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
    $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
    print "<code>$Prompt $RunCommand</code><xmp>";
    $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
    if(!$WinNT)
    {
        $SIG{'ALRM'} = \&CommandTimeout;
        alarm($CommandTimeoutDuration);
    }
    if($ShowDynamicOutput) # show output as it is generated
    {
        $|=1;
        $Command .= " |";
        open(CommandOutput, $Command);
        while(<CommandOutput>)
        {
            $_ =~ s/(\n|\r\n)$//;
            print "$_\n";
        }
        $|=0;
    }
    else # show output after command completes
    {
        print `$Command`;
    }
    if(!$WinNT)
    {
        alarm(0);
    }
    print "</xmp>";
}
#DIG
elsif($RunCommand =~ m/^\s*dig\s+(.+)/)
    {
            &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";
    }
#NSLOOKUP
elsif($RunCommand =~ m/^\s*nslookup\s+(.+)/)
    {
            &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";
    }

#HOST
elsif($RunCommand =~ m/^\s*host\s+(.+)/)
    {
            &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";
    }

#NMAP
elsif($RunCommand =~ m/^\s*nmap\s+(.+)/)
    {
            &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";
    }

#TRACEROUTE
    elsif($RunCommand =~ m/^\s*traceroute\s+(.+)/)
    {
            &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";
    }

#WHOIS
    elsif($RunCommand =~ m/^\s*whois\s+(.+)/)
    {
            &PrintPageHeader("c");
            #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ ";
            $Prompt = $WinNT ? "$CurrentDir> " : "\$ ";
            print "<code>$Prompt $RunCommand</code><xmp>";
            $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector;
            if(!$WinNT)
            {
                    $SIG{'ALRM'} = \&CommandTimeout;
                    alarm($CommandTimeoutDuration);
            }
            if($ShowDynamicOutput) # show output as it is generated
            {
                    $|=1;
                    $Command .= " |";
                    open(CommandOutput, $Command);
                    while(<CommandOutput>)
                    {
                            $_ =~ s/(\n|\r\n)$//;
                            print "$_\n";
                    }
                    $|=0;
            }
            else # show output after command completes
            {
                    print `$Command`;
            }
            if(!$WinNT)
            {
                    alarm(0);
            }
            print "</xmp>";
    }

else
{
            # Print PageHeaderBC that informs of non-functional command
    &PrintPageHeaderBC("c");

    }
&PrintCommandLineInputForm;
&PrintPageFooter;

}

Ответы [ 6 ]

6 голосов
/ 28 августа 2011

Символ | используется для чередования в регулярном выражении.Вам нужно избежать этого, если вы хотите сопоставить буквальный символ |:

m/^\s*\|\s+(.+)/

Кроме того, если я собираюсь рискнуть предположением, я бы сказал, что причина всегда сводится к "провалу"подпрограмма из-за этого регулярного выражения.С чередованием (как написано) оно соответствует любой строке, которая начинается с \s* ИЛИ \s+(.+), что буквально является любой строкой из-за оператора звездочки в \s*.

Редактировать: Что касается вашего комментария, эти примеры не будут сопоставлены ни с одним из ваших регулярных выражений из-за привязки (^).Если мы возьмем, например, строку ping 4.2.2.2; pwd, то получится, что механизм регулярных выражений начинает сопоставлять начало строки, потому что она привязана.Начальный \s* совпадает правильно, повторяя ноль раз, фактически ничего не делая в этом случае.Затем он ищет совпадение ;, но следующий символ - 4, таким образом, он терпит неудачу.То же самое относится и ко второй строке, которую вы указали.Это также сломалось бы, если бы после ; не было пробела, так как вы использовали \s+.

Честно говоря, если вы действительно хотите просто запретить любую строку, даже содержащую символы <, >, ;, | или &, проще всего было бы просто вставить их всех в класс персонажа и сравнить с ним, используя m/[&;|<>]/g.Поскольку это регулярное выражение не занято, оно будет соответствовать в любой точке строки.Это полностью запретило бы эти символы, означая, что они не могут появляться в строках или в чем-либо подобном.Возможно, это не то, что вам нужно, но это применимо к правилам, которые вы в настоящее время сформулировали («Предполагается, что пять регулярных выражений соответствуют любому тексту, который содержит & или; или <или> или |»).

3 голосов
/ 28 августа 2011
elsif($RunCommand =~ m/^\s*|\s+(.+)/)

должно быть:

elsif($RunCommand =~ m/^\s*\|\s+(.+)/)

| является логическим оператором 'или' в регулярном выражении, поэтому вам нужно избегать его, если вы пытаетесь сопоставить его

2 голосов
/ 28 августа 2011

Вам нужно экранировать специальные символы с \.Например, чтобы найти |, выделите его следующим образом: \|.Таким образом, ваше совпадение с регулярным выражением становится:

m/^\s*\|\s+(.+)/

Следующие символы имеют специальное значение в регулярном выражении и должны быть экранированы, если вы хотите, чтобы их интерпретировали буквально:

* ? + [ ] ( ) { } ^ $ | \
1 голос
/ 29 августа 2011

Используйте "класс символов" и один if.

. * В конце ничего полезного не делает, поэтому его там не должно быть.

Разрешение "одного или нескольких" конечных пробелов также не приносит никакой пользы, поэтому также следует опустить:

if ($RunCommand =~ m/^\s*[&;<>|]\s/)
0 голосов
/ 28 августа 2011

Это помогает, если вы используете модификатор / x для разметки ваших RE:

m/^ \s* \& \s+ (.+) /x
0 голосов
/ 28 августа 2011

Тебе нужно убежать от трубочного персонажа, как сказал Эльдарерат. Вы также можете объединить первые 5 случаев в класс символов:

if($RunCommand =~ m/^\s*[&;><\|]\s+(.+)/) {
    PrintPageHeaderBC("c");
}

Это сэкономит вам много места и времени для дальнейшего обслуживания.

Это [&;><\|] будет соответствовать любому из указанных символов.

Читать Классы символов в скобках для более:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...