У меня нет ответа, но у меня есть другой способ сформулировать проблему, используя более простые и, возможно, более реалистичные регулярные выражения.
Первые два примера ведут себя точно так, как я ожидал: .*
потребляет всю строку, а регулярное выражение возвращает список только с одним элементом. Но третье регулярное выражение возвращает список из 2 элементов.
use strict;
use warnings;
use Data::Dumper;
$_ = "foo";
print Dumper( [ /^(.*)/g ] ); # ('foo') As expected.
print Dumper( [ /.(.*)/g ] ); # ('oo') As expected.
print Dumper( [ /(.*)/g ] ); # ('foo', '') Why?
Многие ответы до сих пор подчеркивали, что .*
будет соответствовать чему угодно. Хотя этот ответ верен, он не затрагивает сути вопроса, а именно: почему механизм регулярных выражений продолжает охотиться после того, как .*
поглотил всю строку? При других обстоятельствах (таких как первые два примера), .*
не добавляет дополнительную пустую строку для хорошей меры.
Обновление после полезных комментариев от Час. Owens . При первой оценке любого из трех примеров .*
соответствует всей строке. Если бы мы могли вмешаться и вызвать pos()
в этот момент, двигатель действительно был бы в конце строки (по крайней мере, когда мы воспринимаем строку; см. Комментарии Chas. Для более полного понимания этого). Однако опция /g
указывает Perl попытаться снова сопоставить регулярное выражение whole . Эта вторая попытка потерпит неудачу в примерах № 1 и № 2, и этот сбой приведет к остановке двигателя. Однако с помощью регулярного выражения # 3 движок получит другое совпадение: пустую строку. Затем опция /g
говорит движку попробовать еще раз весь шаблон. Теперь действительно нечего сопоставлять - ни обычные символы, ни завершающая пустая строка - поэтому процесс останавливается.