To find out if user-agent pertains to Safari, one must look for the presence of Safari but not the presence of Chrome. I am also assuming that this needs to be case-insensitive.
I am trying to do this using regular expressions in Python without subsequently needing to traverse groups to match strings.
One way to solve this is :
r1 = re.compile ("Safari", re.I)
r2 = re.compile ("Chrome", re.I)
if len(r1.findall (userAgentString)) > 0 and len(r2.findall(userAgentString)) <=0):
print "Found Safari"
I have also tried to attempt using
r = re.compile ("(?P<s>Safari)|(?P<c>Chrome)", re.I)
m = r.search (userAgentString)
if (m.group('s') and not m.group('c')):
print "Found Safari"
This does not work because search will stop after finding the first instance of one of 'Chrome' or 'Safari' (probably obvious to the Regex-Gurus..).
I can get it to work slightly efficiently using the re.finditer() funciton as follows :
r = re.compile ("(?P<s>Safari)|(?P<c>Chrome)", re.I)
safari = chrome = False
for i in r.finditer (userAgentString):
if i.group('s'):
safari = True
if i.group('c'):
chrome = True
if safari and not chrome:
print "Found Safari"
Is there a more efficient way to do this ? (Please note I am looking for efficiency not convenience). Thanks.
Sample User-agents :
Safari : "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25"
Chrome : "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"
For it's worth, I timed it and jwodder is on the mark with the efficiency of a simple 'lower()' and an 'in'. Came out to be about 10 times faster than a precompiled regex. Unless I did something wrong in setup/timeit..
import timeit
setup = '''
import re
r = re.compile ('(?P<m>MSIE)|(?P<c>Chrome)|(?P<s>Safari)', re.I)
def strictBrowser (userAgentString):
c=s=m=False
for f in r.finditer(userAgentString):
if f.group('m'):
m = True
if f.group('c'):
c = True
if f.group('s'):
s = True
# msie or (safari but not chrome)
# all chromes us will have safari in them..
return m or (s and not c)
'''
print timeit.timeit(
'strictBrowser ("Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.2")',
setup=setup, number=100000
)
setup = '''
def strictBrowser (userAgentString):
userAgentString = userAgentString.lower()
if (
'msie' in userAgentString or
('safari' in userAgentString and 'chrome' not in userAgentString)
):
return True
return False
'''
print timeit.timeit(
'strictBrowser ("Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.2")',
setup=setup, number=100000
)
Output :
0.0778814506637
0.00664118263765