I've used this little ditty in the past (excerpted) :
var browsers = [{
browser : "Opera",
css : "o",
engine : "Presto",
rex : {
eng : /(?:Gecko|Presto)\/([0-9.]*)/,
brw : /.+(?:Opera|Version).([0-9\.]+)/
},
ever : 0,
bver : 0
},{}]
var UA = function(p_ua) {
var curr, i;
for (i in browsers) {
var r = new RegExp(browsers[i].browser);
if (p_ua.match(r) && (!!browsers[i].rex)) {
curr = browsers[i];
curr.ever = curr.rex.eng.exec(p_ua)[1] || curr.rex.eng.exec(p_ua)[0];
curr.bver = curr.rex.brw.exec(p_ua)[1] || curr.rex.brw.exec(p_ua)[0];
break;
}
}
return curr;
}
(See jsfiddle). It's not complete, but it was sufficient for my needs at the time. Outside of something like that, capability detection on the client side is definitely the way to go - whether it's css, html OR javascript (ie http://www.sitepoint.com/detect-css3-property-browser-support/, 1/3 of the way down). I love using regular expressions - but the browser vendors can't be depended on to keep the UA string the same from version to version (let alone follow an actual standard! see : useragentstring.com/pages/useragentstring.php).