Почему оператор Perl "не соответствует" здесь не работает? - PullRequest
1 голос
/ 05 марта 2020

У меня есть следующий Perl код:

my $athCombined = "$athSymbol $athExpiration $athStrike $athType";
if (($instrumentType eq "STOCK" && $cbSymbol ne $athSymbol) ||
    ($instrumentType eq "OPTION" && $cbSymbol !~ /^$athSymbol.*$athExpiration $athStrike $athType$/) ||
    ($instrumentType eq "FUTURESOPTION" && $cbSymbol !~ /^$athCombined$/)) {
    print "ERROR: Symbols on lines $cbLineNum and $athLineNum don't match.  ABORTING.\n";
    print "instrumentType    =$instrumentType\n";
    print "cbSymbol          =$cbSymbol\n";
    print "athCombined       =$athCombined\n";
    print "length cbSymbol   =" . length($cbSymbol) . "\n";
    print "length athCombined=" . length($athCombined) . "\n";
    if ($instrumentType eq "FUTURESOPTION") {
        print "YES1\n";
    }
    if ($cbSymbol !~ /^$athCombined$/) {
        print "YES2\n";
    }
    if ($cbSymbol eq $athCombined) {
        print "they are the same\n";
    }
    exit;
}

Я получаю следующий вывод:

ERROR: Symbols on lines 434 and 1906 don't match.  ABORTING.
instrumentType    =FUTURESOPTION
cbSymbol          =/ESM19 1/50 JUN 19 (Monday) (Wk1) /E1AM19 2745 CALL
athCombined       =/ESM19 1/50 JUN 19 (Monday) (Wk1) /E1AM19 2745 CALL
length cbSymbol   =51
length athCombined=51
YES1
YES2
they are the same

Условное $cbSymbol !~ /^$athCombined$/ возвращает true, хотя $cbSymbol и $athCombined одинаковы. Если я изменю условное выражение на cbSymbol ne $athCombined, то оно будет работать правильно, но я хотел бы знать, почему оно не работает как есть.

Интересно, что я не могу воспроизвести это в простой тестовой программе :

my $a = "1";
my $b = "2";
my $c = "3";
my $abc = "1 2 3";
my $def = "$a $b $c";
if ($abc !~ /^$def$/) {
    print "something is wrong\n";
}

"что-то не так" не распечатывается.

1 Ответ

9 голосов
/ 05 марта 2020

$foo !~ /^$bar$/ не эквивалентно проверке неравенства строк, как в $foo ne $bar. Он проверяет, соответствует ли $foo регулярному выражению ^$bar$, что отличается, особенно, если $bar содержит метасимволы регулярных выражений, но также и в том, что $ может соответствовать перед (разрешить) завершающим символом новой строки, а не только в конце строка. (\z является эквивалентом $, который не допускает завершающий перевод строки.)

$athCombined в вашей программе равен /ESM19 1/50 JUN 19 (Monday) (Wk1) /E1AM19 2745 CALL, который содержит метасимволы регулярных выражений ( и ) (в этом случае они образуют группы захвата и, таким образом, буквенные скобки в вашей другой строке ничем не соответствуют). Вы можете решить эту проблему с помощью модификаторов цитирования :

$cbSymbol !~ /^\Q$athCombined\E\z/

, но лучше было бы просто использовать операторы равенства строк eq или ne, если вы пытаетесь это сделать тест.

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