Geek moment: I matched my first pattern today
Updated 2006-11-09 to fix some formatting issues
On the Georgia Tech site, we’re serving a different style sheet to visitors who are using Netscape 7.1 and Mozilla 1.4 because those browsers mis-handle overflow:hidden.
Serving that stylesheet to Netscape 7.1 was easy. The browser name and version are at the end of its user agent string (which is similar to Mozilla’s).
Mozilla 1.4 however, was a bit harder. The user agent string for 1.4 is very similar to 1.7 (and other Mozilla/Netscape versions). They go something like this:
Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4) Gecko/20040616
That rv:1.4 stuff is the version number. Every thing in between describes the operating system and language. That last little bit is the rendering engine name (Gecko) and the release date.
Now if we just wanted to serve that style sheet to all visitors running Mozilla 1.4 on Mac OS X we could just use that entire string. But Mozilla also runs on Unix and Windows sytems. So how can we make
Mozilla 1.4 get that other style sheet? Enter PHP‘s preg_match() function.
Let’s look at the code below:
preg_match("/(Mozilla\/5\.0)?(rv:1\.4)/",$_SERVER['HTTP_USER_AGENT'])
The first bit of code— /(Mozilla\/5\.0) — begins the pattern. That first ‘/’ is the pattern delimeter. It lets PHP know where the pattern starts. You can use almost any character to delimit a pattern. But things like / or ~ tend to be easier to figure out when you revisit code. The parentheses groups those characters together.
Next is the question mark. That’s regexregex = regular expression-speak for “match any character.” It’s a wildcard of sorts.
That next bit— (rv:1\.4)/— ends the pattern. Note the final / which tells PHP that it has reached the end of the pattern.
The last bit of code $_SERVER['HTTP_USER_AGENT']); is the string that may or may not contain the pattern.
We’re basically saying: Look for a pattern in the user agent information that starts with “Mozilla 5.0″ and has “rv:1.4″ somewhere in there — nevermind what’s between those two bits of text.
How to make that code serve a different style sheets? Like this:
if(preg_match("/(Mozilla\/5\.0)?(rv:1\.4)/", $_SERVER['HTTP_USER_AGENT'])) {
print '<link rel="stylesheet" type="text/css" href="style_sheet_name_here" />';
}
else{
print '<link rel="stylesheet" type="text/css" href="the_other_style_sheet" />';
}
Need more info on regular expressions and pattern matching? Check the following (they helped me)
- Using Regular Expressions by Stephen Ramsay
- Regular Expression HOWTO by A.M. Kuchling (Python-specific, but the concepts are portable)