Perl регулярное выражение, совпадающее с необязательной фразой в длинном предложении
Я пытаюсь сопоставить необязательную (возможно, присутствующую) фразу в предложении:
perl -e '$_="word1 word2 word3"; print "1:$1 2:$2 3:$3\n" if m/(word1).*(word2)?.*(word3)/'
Выход:
1:word1 2: 3:word3
Я знаю, что первый «. *» - это жадный и сопоставляющий все до «word3». Не жадность не помогает:
perl -e '$_="word1 word2 word3"; print "1:$1 2:$2 3:$3\n" if m/(word1).*?(word2)?.*(word3)/'
Выход:
1:word1 2: 3:word3
Кажется, здесь есть конфликт интересов. Я бы подумал, что Perl будет соответствовать (word2)? если возможно и все же насытить не-жадных. * ?. По крайней мере, это мое понимание «?». На странице регулярных выражений Perl написано '?' делает 1 или ноль раз, поэтому он не должен предпочесть один матч, а не ноль?
Еще более запутанно, если я поймаю. *?
perl -e '$_="word1 word2 word3"; print "1:$1 2:$2 3:$3 4:$4\n" if m/(word1)(.*?)(word2)?.*(word3)/'
Выход:
1:word1 2: 3: 4:word3
Все группы здесь являются группами захвата, поэтому я не знаю, почему они пусты.
Просто чтобы убедиться, что межсловное пространство не захвачено:
perl -e '$_="word1_word2_word3"; print "1:$1 2:$2 3:$3 4:$4\n" if m/(word1)(.*?)(word2)?.*(word3)/'
Выход:
1:word1 2: 3: 4:word3
Учитывая, что единственное совпадение, которое не фиксируется, - это совпадение между word2 и word3, я могу только предположить, что оно совпадает. Конечно же:
perl -e '$_="word1_word2_word3"; print "1:$1 2:$2 3:$3 4:$4 5:$5\n" if m/(word1)(.*?)(word2)?(.*)(word3)/'
Выход:
1:word1 2: 3: 4:_word2_ 5:word3
Таким образом, жадное сопоставление работает в обратном направлении, и Perl рад сопоставить нулевой (а не один) экземпляр word2. Сделать его не жадным тоже не поможет.
Итак, мой вопрос: как я могу написать свое регулярное выражение, чтобы сопоставить и зафиксировать возможную фразу в предложении? Мои примеры, приведенные здесь, упрощены; Фактическое предложение, которое я анализирую, намного длиннее, со многими словами между теми, с которыми я сопоставляюсь, поэтому я не могу предположить какую-либо длину или композицию промежуточного текста.
Большое спасибо, Скотт