Ответ 1
user178551 абсолютно прав, рекомендуя использовать конструкцию ветки reset. В вашем исходном регулярном выражении принципиально ничего плохого (кроме того, что он имеет длину более 300 символов и ВСЕ НА ОДИН ЛИНИИ!), И что он не может поставить одну из двух альтернатив в одну группу захвата). Нетривиальное (мягко говоря) выражение, подобное этому, должно быть записано в режиме свободного пробела с отступом, чтобы вы могли его прочитать. Вот ваше исходное регулярное выражение с добавленным разумным пробелом:
$re_OP1 = '%
( # $1:
(?!
.*?<!--\s*?InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->
.*?<!--\s*?InstanceEndEditable\s*?-->
)
<!--\s*?InstanceBeginEditable\s*?name=\x22doctitle\x22\s*?-->\s*?
<title>(.*?)<\/title>\s*? # $2:
<!--\s*?InstanceEndEditable\s*?-->
| <!-- InstanceBeginEditable\s*?name=\x22pagetitle\x22\s*?-->
(.*?) # $3;
<!--\s*?InstanceEndEditable\s*?-->
)
%six';
Теперь, посмотрев на это регулярное выражение, вы можете увидеть, где у вас есть жестко закодированное пространство на строке с оператором OR (т.е. |<!-- InstanceBegin...
). Это приведет к тому, что regex не сможет соответствовать модификатору 'x'
. Итак, заменив это пространство на \s*
и запустив его в тестовых данных, вот результат, который я получаю (php-5.2.14):
Array
(
[0] => <!-- InstanceBeginEditable name="pagetitle" --><strong>Citing Your Sources</strong><!-- InstanceEndEditable -->
[1] => <!-- InstanceBeginEditable name="pagetitle" --><strong>Citing Your Sources</strong><!-- InstanceEndEditable -->
[2] =>
[3] => <strong>Citing Your Sources</strong>
)
Эти результаты аналогичны тем, которые вы опубликовали (но почему-то ваши результаты показывают только 2 группы захвата???). Теперь нам нужно применить предложение user178551 branch reset, а решение regex будет выглядеть следующим образом:
$re_jmr = '%
(?| # Branch reset construct. (restart counting for each alternative)
(?!
.*?<!--\s*InstanceBeginEditable\s*name="pagetitle"\s*-->
.*?<!--\s*InstanceEndEditable\s*-->
)
<!--\s*InstanceBeginEditable\s*name="doctitle"\s*-->\s*
<title>(.*?)<\/title>\s* # $1: Group 1A
<!--\s*InstanceEndEditable\s*-->
| <!--\s*InstanceBeginEditable\s*name="pagetitle"\s*-->
(.*?) # $1: Group 1B
<!--\s*InstanceEndEditable\s*-->
)
%six';
Я пошел вперед и изменил все ленивые \s*?
на жадные (потому что жадный - это то, что вы хотите здесь). Я также изменил все \x22
на "
- более короткое и читаемое IMHO. И вот результаты работы с этим новым ветвь reset regex:
Array
(
[0] => <!-- InstanceBeginEditable name="pagetitle" --><strong>Citing Your Sources</strong><!-- InstanceEndEditable -->
[1] => <strong>Citing Your Sources</strong>
)
Что, (если я не ошибаюсь), именно то, что вы ищете. (Вы не представили тестовый пример для другой альтернативы, так что еще не были протестированы.) Кроме этого, ваше исходное регулярное выражение было довольно близко.