Я весь день бился об кирпичную стену, пытаясь заставить необязательную группу работать в регулярном выражении preg_match_all ().Необязательная версия прекрасно анализирует данные, но как только я сделаю одну часть регулярного выражения необязательной, эта необязательная часть никогда не будет использоваться для анализа данных, даже если в данных присутствует целевая строка.
Это оригинальное регулярное выражение, которое работает:
$regex = "~:begin(.*)[\r\n]+:desc(.*)[\r\n]+(.*)[\r\n]+:end(?:.*)[\r\n]+~msU";
preg_match_all($regex, $text, $matches);
Это текст, который анализируется:
:begin test
:desc testing
some code
more code
last code
:end test
:begin test2
:desc testing2
some code2
last code2
:end test2
Это регулярное выражение правильно анализирует строки, начинающиеся с ": desc", в егособственной группы, но когда я делаю строку ": desc" необязательной, эта же группа всегда пуста, и вместо этого строка добавляется в следующую группу в начале блока "code".
Этоскорректированное регулярное выражение с необязательной группой для desc:
$regex = "~:begin(.*)[\r\n]+(:desc(.*)[\r\n]+)?(.*)[\r\n]+:end(?:.*)[\r\n]+~msU";
Мне кажется, я понимаю, что происходит, но не то, почему или как решить проблему.Понятно, что поскольку в начале блока кода нет какого-то определенного маркера, когда предыдущая строка становится необязательной, регулярное выражение обходит необязательную группу и объединяет все это с последующим блоком кода.Я пытался играть с флагами, меняя группы на все виды комбинаций жадных / не жадных, но не вставляя что-то вроде префикса ": code", чтобы указать начало следующего блока, я просто не могу остановитьсярегулярное выражение от размещения необязательной строки в блоке кода после него.
Я просто хочу иметь возможность сделать необязательный оператор однострочный: desc без добавления дополнительных тегов или разделителей к данным.
На данный момент я застрял, и мне нужен какой-то опытный эксперт по регулярным выражениям, чтобы объяснить, что происходит и как это исправить (если это возможно).