Perl: Несколько глобальные “или” - разделили regex условия в том, в то время как блок приводит к бесконечному циклу?

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

#!/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.

Спасибо!

Tom

5
задан Svante 26 June 2010 в 12:23
поделиться

1 ответ

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

  1. pos ($ hivar) равно 0, / this / соответствует позиции 0 и сбрасывает pos ($ hivar) на 4. Второе совпадение не выполняется, потому что оператор или уже верен. $ & становится "этим" и печатается.
  2. pos ($ hivar) равно 4, / this / не соответствует, потому что нет «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 при неудачном сопоставлении) решает проблему в примере кода, который вы предоставили, но может или не может быть идеальным решением более сложной проблемы.

16
ответ дан 18 December 2019 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: