BBCode Parser. This isn't just a quick regex; it parses the message into a tree, and so supports bbcodes with values, like [url]. Unfortunately I had to strip out most of my code for handling invalid…
sr=/\[[^\/][^\[\]]*\]/;
function m(d){for(var h={ch:[]},f,e,g,i,j;sr.test(d);){f=sr.exec(d)[0];e=d.search(sr);j=e+f.length;0<e&&h.ch.push({a:"t",c:d.substring(0,e)});e=f.search("=");i=0<e?f.substring(0,e)+"]":f;a:{g=d.substr(j);for(var l=1,k=0;k<g.length;k++)if(t=g.substr(k),l+=(0==t.search(sr))-(0==t.search(/\[\/[^\[\]]+\]/)),0==l){g=k;break a}g=!1}g+=j;h.ch.push({a:i.substr(1,i.length-2),d:f.substring(e+1,f.length-1),c:m(d.substring(j,g))});d=d.substr(g+i.length+1)}h.ch.push({a:"t",c:d});return h}
function n(d){var h="",f={b:"<b>^</b>",i:"<i>^</i>",u:"<u>^</u>",quote:"<div class=quote>^</div>",img:"<img src=^>",url:"<a href=&>^</a>",size:'<a style="font-size: &%">^</a>',t:"^"};if("t"==d.a)return d.c;for(var d=d.ch?d.ch:d.c.ch,e=0;e<d.length;e++)h+=d[e].a in f?f[d[e].a].replace("&",d[e].d).replace("^",n(d[e]).replace(/\n/g,"<br>")):d[e].a;return h}z="[size=180]Type BBCode.[/size]";
b.innerHTML="<div id=i>"+n(m(z))+'</div><br><textarea cols=80 rows=10 onkeyup="b.firstChild.innerHTML=n(m(this.value))">'+z;
c3I9L1xbW15cL11bXlxbXF1dKlxdLzsNCmZ1bmN0aW9uIG0oZCl7Zm9yKHZhciBoPXtjaDpbXX0sZixlLGcsaSxqO3NyLnRlc3QoZCk7KXtmPXNyLmV4ZWMoZClbMF07ZT1kLnNlYXJjaChzcik7aj1lK2YubGVuZ3RoOzA8ZSYmaC5jaC5wdXNoKHthOiJ0IixjOmQuc3Vic3RyaW5nKDAsZSl9KTtlPWYuc2VhcmNoKCI9Iik7aT0wPGU/Zi5zdWJzdHJpbmcoMCxlKSsiXSI6ZjthOntnPWQuc3Vic3RyKGopO2Zvcih2YXIgbD0xLGs9MDtrPGcubGVuZ3RoO2srKylpZih0PWcuc3Vic3RyKGspLGwrPSgwPT10LnNlYXJjaChzcikpLSgwPT10LnNlYXJjaCgvXFtcL1teXFtcXV0rXF0vKSksMD09bCl7Zz1rO2JyZWFrIGF9Zz0hMX1nKz1qO2guY2gucHVzaCh7YTppLnN1YnN0cigxLGkubGVuZ3RoLTIpLGQ6Zi5zdWJzdHJpbmcoZSsxLGYubGVuZ3RoLTEpLGM6bShkLnN1YnN0cmluZyhqLGcpKX0pO2Q9ZC5zdWJzdHIoZytpLmxlbmd0aCsxKX1oLmNoLnB1c2goe2E6InQiLGM6ZH0pO3JldHVybiBofQ0KZnVuY3Rpb24gbihkKXt2YXIgaD0iIixmPXtiOiI8Yj5ePC9iPiIsaToiPGk+XjwvaT4iLHU6Ijx1Pl48L3U+IixxdW90ZToiPGRpdiBjbGFzcz1xdW90ZT5ePC9kaXY+IixpbWc6IjxpbWcgc3JjPV4+Iix1cmw6IjxhIGhyZWY9Jj5ePC9hPiIsc2l6ZTonPGEgc3R5bGU9ImZvbnQtc2l6ZTogJiUiPl48L2E+Jyx0OiJeIn07aWYoInQiPT1kLmEpcmV0dXJuIGQuYztmb3IodmFyIGQ9ZC5jaD9kLmNoOmQuYy5jaCxlPTA7ZTxkLmxlbmd0aDtlKyspaCs9ZFtlXS5hIGluIGY/ZltkW2VdLmFdLnJlcGxhY2UoIiYiLGRbZV0uZCkucmVwbGFjZSgiXiIsbihkW2VdKS5yZXBsYWNlKC9cbi9nLCI8YnI+IikpOmRbZV0uYTtyZXR1cm4gaH16PSJbc2l6ZT0xODBdVHlwZSBCQkNvZGUuWy9zaXplXSI7DQpiLmlubmVySFRNTD0iPGRpdiBpZD1pPiIrbihtKHopKSsnPC9kaXY+PGJyPjx0ZXh0YXJlYSBjb2xzPTgwIHJvd3M9MTAgb25rZXl1cD0iYi5maXJzdENoaWxkLmlubmVySFRNTD1uKG0odGhpcy52YWx1ZSkpIj4nK3o7
a = a
b = b
c = c
sr = /\[[^\/][^\[\]]*\]/
function create_tree(_working_string){
var _output = {ch: []}
var _t, _tp, _tep, _ts, _twa, _to;
while(sr.test(_working_string)){
//Find out what the first tag in the string is
_t = sr.exec(_working_string)[0]
//Find out where exactly it is.
_tp = _working_string.search(sr)
_to = _tp + _t.length
//If there's text between the start of this tag, and the end of the last one, parse it.
if (_tp > 0) _output.ch.push({t: 't', c: _working_string.substring(0, _tp)})
//If the bbcode has an attribute, retreive it. (Like [url=http://artvoyagers.com]this[/url])
_ts = _t.search("=")
_twa = _ts > 0 ? _t.substring(0, _ts) + "]" : _t
//Check for an end tag
_tep = find_end_tag(_working_string.substr(_to)) + _to
//Recursively parse the children of the tag
_output.ch.push({t: _twa.substr(1,_twa.length-2), v: _t.substring(_ts + 1, _t.length - 1), c: create_tree(_working_string.substring(_to, _tep))})
//Remove the parsed section from the working string
_working_string = _working_string.substr(_tep + _twa.length + 1)
}
_output.ch.push({t: 't', c: _working_string})
return _output;
}
function find_end_tag(input){
var _level = 1
for (var _i = 0; _i < input.length; _i++){
t = input.substr(_i)
_level += (t.search(sr) == 0) - (t.search(/\[\/[^\[\]]+\]/) == 0)
if (_level == 0) return _i
}
return false;
}
function parse_tree(tree){
var _html = "";
var b_ = {"b": "<b>^</b>","i": "<i>^</i>","u": "<u>^</u>","quote": '<div class=quote>^</div>',"img" : '<img src=^>', "url":'<a href=&>^</a>',"size":'<a style="font-size: &%">^</a>',"t" : "^"}
if (tree.t == "t") return tree.c
var _t = tree.ch ? tree.ch : tree.c.ch
for (var _i = 0; _i < _t.length; _i++) {
_html += (_t[_i].t in b_ ? b_[_t[_i].t].replace("&", _t[_i].v).replace("^", parse_tree(_t[_i]).replace(/\n/g, "<br>")) : _t[_i].t);
}
return _html;
}
z = "[size=180]Type BBCode.[/size]"
b.innerHTML = ("<div id=i>" + parse_tree(create_tree(z)) + "</div><br><textarea cols=80 rows=10 onkeyup=\"b.firstChild.innerHTML=n(m(this.value))\">" + z + "");