perl Регулярные выражения скалярные переменные с включенным `#use warnings;` - PullRequest
0 голосов
/ 15 июля 2011

Я пытаюсь выполнить задание по колледжу в Perl, и наш профессор сказал нам:

use strict;
use warnings;

С use strict; мой код работает отлично.однако при use warnings; мой код выдает все это на SDOUT, и я не знаю, почему (или как его отключить).Мой соответствующий код:

while($diff =~ /^(\d+)((,){1}(\d+))?([adc])(\d+)((,){1}(\d+))?/mgi) {
    # This line is used for debugging the $diff regular expression scalars.
    # print "\n1: $1\t2: $2\t 3: $3\t4: $4\t5: $5\t6: $6\t7: $7\t8: $8\t9: $9\n";

    $difflinestotal += ($4 - $1) unless $4 == "";
    $difflinestotal += ($9 - $6) unless $9 == "";
    $difflinestotal += 1 if (($4 == "") && ($9 == ""));
}

С предупреждениями, он выплевывает это в середине моего вывода:

Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 145.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 145.
Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 146.
Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 147.
Argument "" isn't numeric in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $9 in numeric eq (==) at ./partc.pl line 146.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 145.
Use of uninitialized value $9 in numeric eq (==) at ./partc.pl line 146.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $9 in numeric eq (==) at ./partc.pl line 147.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 145.
Use of uninitialized value $4 in numeric eq (==) at ./partc.pl line 147.

... и это портит мое форматирование (я генерируюстол в консоли).Я пытался «объявить» скаляры, но тогда (конечно) они были по ошибке.Как я могу заставить свой скрипт Perl замолчать с этими предупреждениями (тем более что все равно работает)

Ответы [ 3 ]

6 голосов
/ 15 июля 2011

Это идет в STDERR, а не в STDOUT.

Переменные захвата не всегда установлены; если они не будут, они будут неопределенными. Например, ваше регулярное выражение имеет ((,){1}(\d+))? (где (\d+) - 4-й захват). ? делает всю группу необязательной. Если он не используется при сопоставлении строки, $ 3 и $ 4 останутся неопределенными.

Где вы тестируете unless $4 == "" вы должны тестировать if defined $4.

Пара других заметок: {1} ничего не делает; он говорит, что предыдущая часть регулярного выражения должна совпадать ровно один раз - что было бы и без {1}. Может быть проще отслеживать, какие переменные захвата вы используете, если вы используете группы без захвата ((?: ... )) для группировок, которые вам не нужны для захвата.

2 голосов
/ 15 июля 2011

Работает, только если случайно. То, что захватывает это регулярное выражение,

  • $1 ((\d+)) - это первое число

  • $2 (((,){1}(\d+))) - это ваша довольно многословная запятая ($3), за которой следует другое число ($4). Это будет неопределенным, если оно не соответствует

  • $3 ((,){1}) - запятая. Что ты намеревался с этим? (,) захватывает запятую, а {1} повторяет это один раз (что не допускается). Если $2 не совпадает, то это будет неопределенным.

  • $4 ((\d+)) - номер, следующий сразу за запятой. Если $2 не совпадает, то это будет неопределенным.

  • $5 (([adc])) захватывает один из a, d или c.

  • $6 ((\d+)) захватывает другое число.

  • $7 до $9 повтор $2 до $4, включая все они неопределенные, если $7 не соответствует.

Как выглядят данные, с которыми вы пытаетесь сопоставить?

Помимо вышесказанного, часто полезно использовать группы без захвата ((?:...)), когда вам на самом деле что-то не нужно, чтобы переменные захвата были более согласованными (также есть некоторые незначительные улучшения производительности и памяти) , В этом случае я бы предположил, что $2 и $7 выше не обязательно должны быть захвачены ... хотя это будет зависеть от того, какими на самом деле должны быть бессмысленные $3 и $8.

0 голосов
/ 15 июля 2011

Во-первых, при изучении Perl вы всегда должны использовать предупреждения и строгие правила.

Когда вы выполняете сопоставление с регулярным выражением, вы сопоставляете подстроки внутри строк, поэтому ваши совпадения являются строками. Тем не менее, Perl преобразует строки в числа, если контекст требует этого. Например, если вы напишите:

$ 4 - $ 1

$ 4 и $ 1 должны быть числами, потому что для строк нет оператора -, поэтому perl преобразует строки $ 4 и $ 1 в их числовые эквиваленты, а затем perl выполняет вычитание. Аналогично, если вы напишите:

$ 4 == ""

оператор == работает только с числами, поэтому perl конвертирует $ 4 в число --- но perl не решается конвертировать "" в число. Если вы пишете строковый литерал, такой как «собака» или «» в своем коде, где вызывается число, тогда Perl подозревает, что вы, возможно, допустили ошибку, и использует предупреждения, чтобы Perl предупредил вас о возможной ошибке, а не просто слепо совершая обращение.

Для сравнения строк в Perl вы используете оператор eq.

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