Следующее регулярное выражение захватывает необходимые части, такие как текст и URL:
\[@url\|([^|]+)\|(\d+)\](?=(?>.*\R+)+^\[\2]:\s+(\S+))
Regex демо здесь
Разбивка:
\[@url\|([^|]+)\|(\d+)\]
Совпадение блока @url и захват текста и индекса
(?=
Начало позитивного взгляда
(?>
Начало атомной (не захватывающей) группы
.*\R+
Совпадение строки и следующих за ней разрывов строки
)+
Конец группы, повторите хотя бы один раз
^\[\2]:\s+(\S+)
Сопоставьте индекс в соответствии с нашим указанным выше номером и введите URL
)
Конец позитивного взгляда
и следующие индексы совпадений в конце:
^\[\d+]:\h+\S+
Здесь мы будем использовать preg_replace_callback
, чтобы заменить эти блоки соответствующими тегами привязки и удалить индексы:
$re = '/\[@url\|([^|]+)\|(\d+)\](?=(?>.*\R+)+^\[\2]:\s+(\S+))|^\[\d+]:\h+\S+/m';
echo preg_replace_callback($re, function($match) {
if (isset($match[1])) {
return "<a href=\"{$match[3]}\">{$match[1]}</a>";
}
}, $str);
PHP демо здесь