Можно и безо всяких регулярок.
Реализация упрощена, можете ее доработать сами с учетом возможных ошибок - пропущен символ "|" внутри шорткода или отсутствие открывающей/закрывающецй скобки.
function replaceShortcodesWithLinks($text) {
$shotcodeQuantity = min([substr_count($text, "["), substr_count($text, "]")]);
$offset = 0;
for ($i=0; $i<$shotcodeQuantity; $i++) {
$openBracePos = strpos($text, "[", $offset);
$closeBracePos = strpos($text, "]", $openBracePos);
$shortcode = substr($text, $openBracePos+1, $closeBracePos-$openBracePos-1);
list($id, $title) = explode("|", $shortcode);
$link = "<a href='https://vk.com/{$id}'>{$title}</a>";
$text = substr($text, 0, $openBracePos) . $link . substr($text, $closeBracePos+1);
$offset = $closeBracePos + strlen($link);
}
return $text;
}