preg_replace('/web[\/web]/','<a href="\1">\1</a>',$article);
What this does:
/web[\/web]/ is the regular expression we're searching for. Because you can attach things to the end of the expression to change its behaviour, such as if you want it to be case-insensitive, it needs to be delimited by something (usually '/'). Because of this, the / in [/web] needs to be escaped or the regular expression engine will go odd.
To start with, we look for a bit that says "[web]". Once we find it we start matching any old characters until we find the corresponding "[/web]". That's what the ".*" bit does.
The question mark is added so that the matching stops as soon as a "[/web]" is found, otherwise it would get gobbled up in the "matching any old characters" bit and you'll be in trouble - everything from the first [web] to the last [/web] in the entire $article will turn into one big bogus link!
The .*? is wrapped in parentheses because we want to record the stuff it matches for later - it's the URL we're looking for!
One more '/' and we can move on to the replacement expression.
What do we replace all this stuff we matched by? Well, we replace it with this:
<a href="\1">\1</a>
which says '<a href="' followed by the bit we recorded. It's a reference to "the contents of the first set of parentheses". Which is of course our URL.
A backslash is used to identify such a so-called backreference, and because PHP treats backslashes specially, it has to be escaped - hence the double backslash.
With our URL written out, we close off the quotes and finish the tag. Then we write the URL again (so's people actually have something to click on) and then the ending tag for the link.