Как игнорировать любые пустые значения в perl grep? - PullRequest
6 голосов
/ 09 июля 2011

Я использую следующее для подсчета количества вхождений шаблона в файле:

my @lines = grep /$text/, <$fp>;
print ($#lines + 1);

Но иногда он печатает на единицу больше, чем фактическое значение.Я проверил, и это потому, что последний элемент @lines является нулевым, и это тоже считается.

Как последний элемент результата grep иногда может быть пустым?Кроме того, как можно решить эту проблему?

Ответы [ 4 ]

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

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

my @lines = grep { not /^\s*$/ and /$test/ } <$fp>;

Помните, что если в содержимое $ test входят специальные метасимволы регулярных выражений, то они либо должны быть предназначены для целей метасимволов, либо стерилизованы с помощью quotemeta().

Моя теория состоит в том, что у вас может быть строка, оканчивающаяся на \ n, которая каким-то образом соответствует вашему регулярному выражению $ text, или ваше регулярное выражение $ text содержит метасимволы, которые влияют на совпадение без вашего ведома. В любом случае предоставленный мною фрагмент, по крайней мере, вызовет отклонение «пустых строк», где «пустой» может означать полностью пустой (маловероятный), перевод новой строки, но в противном случае пустой (вероятный), или пробел, содержащий (возможные) строки, которые при печати выглядят пустыми.

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

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

use Data::Dumper;
$Data::Dumper::Useqq = 1;
print Dumper \@lines;
2 голосов
/ 09 июля 2011

Регулярное выражение, совпадающее с пустой строкой, будет соответствовать undef. Perl предупредит об этом, но применит undef к '' перед тем, как попытаться сопоставить его, и в этот момент grep будет весьма счастливо продвигать undef к его результатам. Если вы не хотите выбирать пустую строку (или что-либо, что будет сопоставлено, как если бы это была пустая строка), вам нужно переписать ваше регулярное выражение, чтобы оно не совпадало с ним.

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

Хорошо, поскольку больше информации о содержании $text (регулярное выражение) не ожидается, я предполагаю, что выкину некоторую общую информацию.

Рассмотрим следующий пример:

use Data::Dumper;

my @array = (' ', 1, 2, 'a', '');
print Dumper [ grep /\s*/, @array ];

Получаем:

$VAR1 = [
          ' ',
          1,
          2,
          'a',
          ''
        ];

Все значения совпадают.Зачем?Потому что они также соответствуют пустой строке.Чтобы получить то, что мы хотим, нам нужно \s или \s+.(Между ними не будет практической разницы)

У вас может быть такая проблема.

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