Просто для удовольствия, вот регулярное выражение, которое будет работать с одним preg_match_all
:
'%(?:Filed under:\s*+|\G</a>)[^<>]*+<a[^<>]*+>\K[^<>]*%`
Или в более читаемом формате:
'%(?:
Filed under: # your sentinel string
|
\G # NEXT MATCH POSITION
</a> # an end tag
)
[^<>]*+ # some non-tag stuff
<a[^<>]*+> # an opening tag
\K # RESET MATCH START
[^<>]+ # the tag's contents
%x'
\G
соответствует положению, с которого должна начинаться следующая попытка матча, обычно это точка, где закончился предыдущий успешный матч (но если предыдущий матч был нулевой длины, он поднимается вперед еще на одну). Это означает, что регулярное выражение не будет совпадать с подстрокой, начинающейся с </a>
до после , и совпадает с подстрокой, начинающейся с Filed under:
хотя бы один раз.
После того, как сторожевая строка или конечный тег были сопоставлены, [^<>]*+<a[^<>]*+>
потребляет все, вплоть до следующего начального тега. Затем \K
подменяет начальную позицию, так что совпадение (если оно есть) начинается после тега <a>
(это похоже на позитивный взгляд сзади, но более гибкий). Наконец, [^<>]+
соответствует содержимому тега и переносит позицию соответствия до конечного тега, так что \G
может соответствовать.
Но, как я уже сказал, это просто для развлечения. Если у вас нет для выполнения работы в одном регулярном выражении, вам лучше использовать многоэтапный подход, такой как используемый @codaddict; он более читабелен, более гибок и удобен в обслуживании.
\K
ссылка
\G
ссылка
РЕДАКТИРОВАТЬ: Хотя ссылки, которые я дал, относятся к документации по Perl, эти функции также поддерживаются PHP - или, точнее, библиотекой PCRE. Я думаю, что документы на Perl немного лучше, но вы также можете прочитать об этом в руководстве PCRE .