3

I came here searching for an answer to sniffing for iOS 6 via the useragent and found a wonderful answer here: How to detect iOS 6 and all minor versions by user agent?

All regular expressions I've worked with previously have been pretty simple and I'm banging my head against a wall trying to get this one working properly. Unfortunately the PHP parser isn't giving me any errors!

I know for a fact I'm doing something wrong, since I'm getting a match for the code below while running firefox on my laptop.

I would appreciate if anyone could point me in the right direction here, I can't figure out what I'm doing wrong.

$subject = $_SERVER['HTTP_USER_AGENT'];
$pattern = '~^(?:(?:(?:Mozilla/\d.\d\s*()+|Mobile\s*Safari\s*\d+.\d+(.\d+)?\s*)(?:iPhone(?:\s+Simulator)?|iPad|iPod);\s*(?:U;\s*)?(?:[a-z]+(?:-[a-z]+)?;\s*)?CPU\s* (?:iPhone\s*)?(?:OS\s*\d+\d+(?:\d+)?\s*)?(?:like|comme)\s*Mac\s*O?S?\s*X(?:;\s*[a-z]+(?:-[a-z]+)?)?)\s*)?(?:AppleWebKit/\d+(?:.\d+(?:.\d+)?|\s*+)?\s*)?(?:(KHTML,\s*(?:like|comme)\s*Gecko\s*)\s*)?(?:Version/\d+.\d+(?:.\d+)?\s*)?(?:Mobile/\w+\s*)?(?:Safari/\d+.\d+(.\d+)?)?.*$~';

if (preg_match($pattern,$subject))
{
    echo "match";
}
5
  • What does var_dump( $_SERVER['HTTP_USER_AGENT']); output? Commented Oct 12, 2012 at 14:41
  • @nickb Obviously depends on what device/browser I'm using, but in Firefox on my laptop: string(83) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1" It's not supposed to match that! Commented Oct 12, 2012 at 14:42
  • 2
    Obviously. The point is the regex is faulty - It does indeed match that user agent, when clearly it is not the correct behavior. Commented Oct 12, 2012 at 14:44
  • @nickb Ack, I figured with the detail and instructions the guy put into his reply that it worked properly! Commented Oct 12, 2012 at 14:46
  • @nickb especially as that user had checked it as a correct answer Commented Oct 12, 2012 at 14:48

2 Answers 2

3

Try this instead :

^(?:(?:(?:Mozilla/\d\.\d\s*\()+|Mobile\s*Safari\s*\d+\.\d+(\.\d+)?\s*)(?:iPhone(?:\s+Simulator)?|iPad|iPod);\s*(?:U;\s*)?(?:[a-z]+(?:-[a-z]+)?;\s*)?CPU\s*(?:iPhone\s*)?(?:OS\s*\d+_\d+(?:_\d+)?\s*)?(?:like|comme)\s*Mac\s*O?S?\s*X(?:;\s*[a-z]+(?:-[a-z]+)?)?\)\s*)?(?:AppleWebKit/\d+(?:\.\d+(?:\.\d+)?|\s*\+)?\s*)?(?:\(KHTML,\s*(?:like|comme)\s*Gecko\s*\)\s*)?(?:Version/\d+\.\d+(?:\.\d+)?\s*)?(?:Mobile/\w+\s*)?(?:Safari/\d+\.\d+(\.\d+)?.*)?$

Demo : http://gskinner.com/RegExr/?32eou

A even more generic solution : http://code.google.com/p/php-mobile-detect/

Sign up to request clarification or add additional context in comments.

10 Comments

Warning: preg_match() [function.preg-match]: Compilation failed: range out of order in character class at offset 243
@nmford: Did you add the delimiters?
The script parses now, but it still matches for firefox on my laptop which it shouldn't. Starting to think that perhaps I should just put something simpler together myself!
@nmford: Matches Firefox because of the Mozilla and since everything else is optional... You should use atomic groups. Or better yet, don't reinvent the wheel: code.google.com/p/php-mobile-detect.
@AlixAxel I have updated the demo. It runs fine now. I noticed that the original cut/paste regex in your answer had some meta characters left out.
|
3

The regex had some error. Some metachars has gone because of SO character escaping system.

Here is the PHP code of your question updated :

$subject = $_SERVER['HTTP_USER_AGENT'];
$pattern = '~^(?:(?:(?:Mozilla/\d\.\d\s*\()+|Mobile\s*Safari\s*\d+\.\d+(\.\d+)?\s*)(?:iPhone(?:\s+Simulator)?|iPad|iPod);\s*(?:U;\s*)?(?:[a-z]+(?:-[a-z]+)?;\s*)?CPU\s*(?:iPhone\s*)?(?:OS\s*\d+_\d+(?:_\d+)?\s*)?(?:like|comme)\s*Mac\s*O?S?\s*X(?:;\s*[a-z]+(?:-[a-z]+)?)?\)\s*)?(?:AppleWebKit/\d+(?:\.\d+(?:\.\d+)?|\s*\+)?\s*)?(?:\(KHTML,\s*(?:like|comme)\s*Gecko\s*\)\s*)?(?:Version/\d+\.\d+(?:\.\d+)?\s*)?(?:Mobile/\w+\s*)?(?:Safari/\d+\.\d+(?:\.\d+)?.*)?$~';

if (preg_match($pattern,$subject))
{
    echo "match";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.