If I have an iOS user-agent like
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
or
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/7D11
How would I detect the iOS version using regular expressions so that it would return e.g.
4.0
for the above user agent?
The RegEx that is working for me is:
/OS ((\d+_?){2,3})\s/
An iPad 5.1.1 has an HTTP_USER_AGENT
like this:
"Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3"
So 3 numbers in the iOS version and not iPhone OS present.
A possible Ruby implementation could be:
def version_from_user_agent(user_agent)
version = user_agent.match(/OS ((\d+_?){2,3})\s/)
version = version[1].gsub("_",".") if version && version[1]
end
It returns nil if not iOS version found
This regular expression should do what you want :
/iPhone OS (\d+)_(\d+)\s+/
you have to capture the two matching group values, how to do it depends on the language you use ...
With php you can do it in this way :
$txt = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7';
$reg = '/iPhone OS (\d+)_(\d+)\s+/';
$a = array();
preg_match($reg, $txt, $a);
$str_version = $a[1].'.'.$a[2]; // This variable should now contain : 4.0
This regex will match 2 and 3 segments like 4.0 or 6.1.3
/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/
Javascript Example:
> navigator.userAgent
"Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_2 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B146"
> navigator.userAgent.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/);
["6_1_2"]
Note that this may also match other devices, so make sure you test this on a iOS device.
This will return the OS X version on a Mac.
> navigator.userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1"
> navigator.userAgent.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/);
["10_8_4"]
You also may want to replace the _
by .
using .replace(/_/g,'.');
or even convert it to a array using .split('_');
.
_iOSDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);
if(_iOSDevice)
_iOSVersion = (navigator.userAgent.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/)||[''])[0].replace(/_/g,'.');
I found the existing answers didn't have a good success rate when tested against the possible user agent strings on this web page of example user agent strings:
http://www.webapps-online.com/online-tools/user-agent-strings/dv/operatingsystem51849/ios
I have created the following regex which has more success when tested against these examples:
(iPad|iPhone|iphone|iPod).*?(OS |os |OS\_)(\d+((_|\.)\d)?((_|\.)\d)?)
The fourth group contains the ios version number which is in the format x_y_z or x.y.z where y and z are optional.
There are 7 examples user agent strings which do not contain any version number so those particular ones are not matched. There is one example string where the ios version is "7.1" but the regex matches only the major version number "7" (this was good enough for my use case)
As well as the tests on the above page its also been tested against the ios10 agent strings listed on this page:
https://myip.ms/view/comp_browsers/1983/Safari_10.html