Perl: Несколько глобальных "или" разделенных условий регулярных выражений в блоке while приводят к бесконечному циклу? - PullRequest
5 голосов
/ 26 июня 2010

Я изучаю Perl и заметил довольно странную причуду - попытка сопоставить одно из нескольких условий регулярного выражения в цикле while приводит к тому, что цикл продолжается бесконечность:

#!/usr/bin/perl

my $hivar = "this or that";

while ($hivar =~ m/this/ig || $hivar =~ m/that/ig) {
        print "$&\n";
}

Вывод этогоПрограмма:

this
that
that
that
that
[...]

Мне интересно, почему это так?Существуют ли какие-либо обходные пути, которые являются менее неуклюжими, чем это:

#!/usr/bin/perl

my $hivar = "this or that";

while ($hivar =~ m/this|that/ig) {
        print "$&\n";
}

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

Спасибо!

Том

1 Ответ

16 голосов
/ 26 июня 2010

Дело в том, что есть скрытое значение, связанное с каждой строкой , а не с каждым совпадением , которое определяет, где совпадение /g будет пытаться продолжить, и доступно через pos($string). Что происходит:

  1. pos($hivar) равно 0, /this/ соответствует позиции 0 и сбрасывает pos($hivar) в 4. Второе совпадение не было предпринято, поскольку оператор или уже задан. $& становится «этим» и печатается.
  2. pos($hivar) равно 4, /this/ не соответствует, потому что нет «этого» в позиции 4 или за ее пределами. Неудачное совпадение сбрасывает pos($hivar) в 0.
  3. /that/ соответствует позиции 6 и сбрасывает pos($hivar) в 10. $& становится «тем» и печатается.
  4. pos($hivar) равно 10, /this/ не соответствует, потому что нет «this» в позиции 10 или выше. Неудачное совпадение сбрасывает pos($hivar) в 0.
  5. /that/ соответствует позиции 6 и сбрасывает pos($hivar) в 10. $& становится «тем» и печатается.

и шаги 4 и 5 повторяются бесконечно.

Добавление флага регулярного выражения c (который сообщает движку не сбрасывать pos при неудачном сопоставлении) решает проблему в приведенном вами примере кода, но это может или не может быть идеальным решением для более сложного проблема.

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