Я пытаюсь получить из текста все вхождения фрагмента кода и 3 параметра. Я делаю это с помощью функций PHP регулярное выражение и preg_match_all.
Он отлично работает, если у меня есть только одно вхождение фрагмента в тексте. Если их два или более, я получаю странный результат.
Я не очень хорошо разбираюсь в регулярных выражениях, поэтому мне трудно понять, что я упускаю.
Функция
public function getGallerySnippetOccurrences($text) {
$ptn = '/{# +gallery +(src|width|height)=\[(.*)\] +(src|width|height)=\[(.*)\] +(src|width|height)=\[(.*)\] +#}/';
if (preg_match_all($ptn,$text,$matches)){
$turnedMatches = $this->turn_array($matches);
return $turnedMatches;
}
else {
return null;
}
}
Текст 1 (в данном случае работает как аспектированный)
Lorem ipsum {# gallery src=[holiday_images/london] width=[400] height=[300] #} sid amet.
Возвращает:
array(1) {
[0] =>
array(7) {
[0] =>
string(66) "{# gallery src=[holiday_images/london] width=[400] height=[300] #}"
[1] =>
string(3) "src"
[2] =>
string(21) "holiday_images/london"
[3] =>
string(5) "width"
[4] =>
string(3) "400"
[5] =>
string(6) "height"
[6] =>
string(3) "300"
}
}
Текст 2 (неконтролируемое поведение)
Lorem ipsum {# gallery src=[holiday_images/london] width=[400] height=[300] #} sid amet {# gallery src=[holiday_images/paris] width=[400] height=[300] #}
Возвращает
array(1) {
[0] =>
array(7) {
[0] =>
string(141) "{# gallery src=[holiday_images/london] width=[400] height=[300] #} sid amet {# gallery src=[holiday_images/paris] width=[400] height=[300] #}"
[1] =>
string(3) "src"
[2] =>
string(96) "holiday_images/london] width=[400] height=[300] #} sid amet {# gallery src=[holiday_images/paris"
[3] =>
string(5) "width"
[4] =>
string(3) "400"
[5] =>
string(6) "height"
[6] =>
string(3) "300"
}
}
Что я делаю неправильно?
смотри мой ответ ниже






В вашем шаблоне вы используете жадные совпадения, используя (.), который следует заменить нежадным шаблоном (.?). Пожалуйста, найдите образец ниже
$ptn = '/{# +gallery +(src|width|height)=\[(.*?)\] +(src|width|height)=\[(.*?)\] +(src|width|height)=\[(.*?)\] +#}/';
Как указано в моем комментарии ниже вашего ответа, создание нежадного квантификатора заставит его работать. Однако это по-прежнему оставляет ваше регулярное выражение повторяющимся и неэффективным.
Вы можете рассмотреть этот подход для обеих точек:
$re = '/{\#
\h+gallery
\h+(src|width|height)=\[([^]]*)]
\h+((?1))=\[([^]]*)]
\h+((?1))=\[([^]]*)]
\h*\#}/x';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Демонстрация регулярных выражений
(?1), чтобы избежать повторений.[^]]* вместо неэффективного .*? для захвата значений.
Сделайте это не жадным:
/{# +gallery +(src|width|height)=\[(.*?)] +(src|width|height)=\[(.*?)] +(src|width|height)=\[(.*?)] +#}/