(oops, too slow again)
I wonder where you get stuck with this? Anyway, let's do it step by step:
1st part: [link= would be matched by [link=, you only need to escape the square bracket.
2nd: this is the url that may very. I don't think you want to validate the url in any way, so we can simple say [] ]+ (which means a sequence of characters that are not the closing bracket)
3rd: ] (again, don't forget to escape)
4th: as 2nd, but limited by the next opening bracket [[]+
5th: [/link] (see 1 and 3)
Now, put it all together, and put parts you need to re-use in parenthesis, and don't forget to escape the sign you use as delimiter:
/[link=([] ]+)]([[]+)[\/link] / now, that's our pattern - starts looking nasty, eh 😉?
okay, and the replacement argument. Here we can use $1 and $2 to get what was matched by the subpattern in the 1st and 2nd (), and the i-modifier to match case-insensitive:
preg_replace("/[link=([] ]+)]([[]+)[\/link] /i", "<a href=\"$1\">$2</a>", $string);
Hope there are no typos, but once you get into it you should be able to modify it according to your needs anyway.