Почему Perl эта программа не может вывести «Success», когда совпадение с регулярным выражением успешно? - PullRequest
0 голосов
/ 16 октября 2010

Я все еще начинающий с Perl, поэтому, пожалуйста, потерпите меня. Это ситуация, с которой я сталкиваюсь:

$var = "AB1234567";
$num = "1234567";
next if $var =~ /$num/;
print "Success!\n";

Теперь я понимаю, что должно быть напечатано «Удачи! \ N», но на самом деле это не так. Однако, если я изменю регулярное выражение на next if $var =~ /"$num"/;, на самом деле будет напечатано «Success! \ N».

Однако, если я изменю его на $var = "AB123456";, исходное регулярное выражение будет работать нормально.

Я понимаю, что при заключении строк в двойные кавычки разыменование интерполирует переменную. Однако разве это не должно быть правдой в случае регулярных выражений? Я сделал регулярное выражение, используя переменные без кавычек, и он работал нормально.

Спасибо за вашу помощь!

EDIT:

Я пропустил точку с запятой в моем примере, но моя первоначальная проблема все еще остается.

EDIT:

Я действительно должен был просто скопировать / вставить. Я сделал опечатку и использовал continue if вместо next if. Опять же, моя проблема все еще существует.

Ответы [ 5 ]

4 голосов
/ 16 октября 2010

Давайте посмотрим на ваш код:

$var = "AB1234567";
$num = "1234567";
next if $var =~ /$num/;
print "Success!\n";

Я предполагаю, что это в теле некоторой петли. Когда вы говорите

next if $var =~ /$num/;

Вы говорите "вернитесь назад и выполните тело цикла для следующей итерации, пропустив все следующие операторы в теле взгляда , если $var соответствует /$num/". Когда $var действительно соответствует /$num/, программа делает именно то, что вы просили, и пропускает оператор print.

С другой стороны, когда вы используете $var =~ /"$num"/, рисунок с правой стороны становится /"1234567"/. Теперь условие в next if $var =~ /"$num"/ не может быть успешным. И ваша программа печатает "Success", потому что совпадение не удалось.

#!/usr/bin/perl

use strict; use warnings;
use re 'debug';

my $num = "1234567";

for my $var ( qw( AB1234567 ) ) {
    next if $var =~ /$num/;
    print "Success!\n";
}

Выход:

Compiling REx "1234567"
Final program:
   1: EXACT  (4)
   4: END (0)
anchored "1234567" at 0 (checking anchored isall) minlen 7
Guessing start of match in sv for REx "1234567" against "AB1234567"
Found anchored substr "1234567" at offset 2...
Starting position does not contradict /^/m...
Guessed: match at offset 2
Freeing REx: "1234567"

Теперь давайте используем /"$num"/ в качестве шаблона:

#!/usr/bin/perl

use strict; use warnings;
use re 'debug';

my $num = "1234567";

for my $var ( qw( AB1234567 ) ) {
    next if $var =~ /"$num"/;
    print "Success!\n";
}

Выход:

Compiling REx "%"1234567%""
Final program:
   1: EXACT  (5)
   5: END (0)
anchored "%"1234567%"" at 0 (checking anchored isall) minlen 9
Guessing start of match in sv for REx "%"1234567%"" against "AB1234567"
Did not find anchored substr "%"1234567%""...
Match rejected by optimizer
Success!
Freeing REx: "%"1234567%""

Ваш код печатает Успех! , когда совпадение не удается.

См. Также perldoc perlsyn :

Команда next запускает следующую итерацию цикла:

    LINE: while (<STDIN>) {
    next LINE if /^#/;  # discard comments
    ...
    }
4 голосов
/ 16 октября 2010

Я думаю, вы не понимаете, что делает continue. Я не совсем уверен, что вы пытаетесь сделать здесь, но обычно continue выйдет из блока if или перейдет к следующей итерации цикла for, цикла while и т. Д. Когда шаблон match continue фактически пропускает оператор печати. Когда вы изменяете значение $var, оно больше не совпадает и выполняется оператор печати. ​​

Попробуйте это:

$var = "AB1234567"
$num = "1234567"
print "Success!\n" if $var =~ /$num/;

Randy

4 голосов
/ 16 октября 2010

Я так не думаю. Это работает для меня:

$var = "AB1234567";
$num = "1234567";
print "Success!\n" if $var =~ /$num/;

Это либо что-то из вашего оператора continue, либо из-за того, что вы пропускаете точки с запятой в присваиваниях переменных (ваш пример даже не работает для меня ....).

1 голос
/ 16 октября 2010

http://perldoc.perl.org/functions/index.html

C:>perl -e "$x='abc'; $y='bc'; print 'yes' if index($x,$y)>0;"
yes
C:>perl -e "$x='abc'; $y='bc'; print 'yes' if $x =~ /$y/"
yes

Если (как подразумевается) код находится в цикле, вас может заинтересовать qr{} в http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators

0 голосов
/ 16 октября 2010

Ваш код говорит: «Если эта переменная соответствует этому регулярному выражению, ничего не делать. В противном случае выведите Success!.».Я сомневаюсь, что это то, что вы хотели для этого сделать.

Добавление кавычек не влияет на интерполяцию переменной вообще.То, что делает , - это приводит к сбою совпадения с регулярным выражением.Поскольку сопоставление не удается, next [1] не выполняется, и выполнение достигает оператора print и печатается Success!.

Проблема с вашим кодом вовсе не связана с регулярными выражениями или переменнымиинтерполяция в регулярные выражения или кавычки, появляющиеся внутри регулярных выражений.Это простая логическая ошибка инвертированного условного выражения.

Попробуйте заменить третью строку на

next unless $var =~ /$num/;

, чтобы увидеть, что происходит, когда вы просто инвертируете логику своего кода в то, что вы, вероятно, намеревались.

[1]: или continue, в зависимости от того, какую версию вашего кода просматриваете

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