user_agent_parser 2.5.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd4b7259791194e0dfdd38e5a9fe5f0316f055eb94d21578fa542a8913c6834b
4
- data.tar.gz: 1682d5ac3c9ff1e10b896846f215e7c487d83a58ded86ebbed073213156699f8
3
+ metadata.gz: f36ea17c827ff0d9a4a57841e491bafed8ae2c3a5caea5af858d6cdbb580d897
4
+ data.tar.gz: 48cce3afc9daaf42f180ce5564c9fc37c5fb288c115e93bb20b6291d43ae452f
5
5
  SHA512:
6
- metadata.gz: f0306cab9fe8e6213f339a061a5683cea62de9a8f06ea5c96e756da014d0cfcffb90d82ff8be66da7c83726fe18ac0161f6eea817e4c211a1ebcb632538bbb38
7
- data.tar.gz: be503613c609542a66750d169d0f7a52caa36baa12aeca16739984476edc50a58479d7e537cc3b572c5845d4f13ecbaf5f642953b2ac0b3bf72b532ed110d770
6
+ metadata.gz: 4c695d6238bb7542309a94daaea5149109aca5c0f4a1205d7a078f5182eb2d02ea768bf0884803d59a0d2f4f4f57a5ddbb8750d523469f028fcdc0b88f3f56c4
7
+ data.tar.gz: 39fa0993955155d19eabb8f31356173bfda97b2e430ce469d895713421c793ad047d327a50f1165e64861064ded84ae977a782fdbef078b6229f1c347b8f2113
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -2,12 +2,14 @@
2
2
 
3
3
  module UserAgentParser
4
4
  class Device
5
+ DEFAULT_FAMILY = 'Other'
6
+
5
7
  attr_reader :family, :model, :brand
6
8
 
7
9
  alias name family
8
10
 
9
11
  def initialize(family = nil, model = nil, brand = nil)
10
- @family = family || 'Other'
12
+ @family = family || DEFAULT_FAMILY
11
13
  @model = model || @family
12
14
  @brand = brand
13
15
  end
@@ -2,11 +2,13 @@
2
2
 
3
3
  module UserAgentParser
4
4
  class OperatingSystem
5
+ DEFAULT_FAMILY = 'Other'
6
+
5
7
  attr_reader :family, :version
6
8
 
7
9
  alias name family
8
10
 
9
- def initialize(family = 'Other', version = nil)
11
+ def initialize(family = DEFAULT_FAMILY, version = nil)
10
12
  @family = family
11
13
  @version = version
12
14
  end
@@ -2,12 +2,14 @@
2
2
 
3
3
  module UserAgentParser
4
4
  class UserAgent
5
+ DEFAULT_FAMILY = 'Other'
6
+
5
7
  attr_reader :family, :version, :os, :device
6
8
 
7
9
  alias name family
8
10
 
9
11
  def initialize(family = nil, version = nil, os = nil, device = nil)
10
- @family = family || 'Other'
12
+ @family = family || DEFAULT_FAMILY
11
13
  @version = version
12
14
  @os = os
13
15
  @device = device
@@ -1,17 +1,63 @@
1
1
  user_agent_parsers:
2
2
  #### SPECIAL CASES TOP ####
3
3
 
4
+ # ESRI Server products
5
+ - regex: '(GeoEvent Server) (\d+)(?:\.(\d+)(?:\.(\d+)|)|)'
6
+
7
+ # ESRI ArcGIS Desktop Products
8
+ - regex: '(ArcGIS Pro)(?: (\d+)\.(\d+)\.([^ ]+)|)'
9
+
10
+ - regex: 'ArcGIS Client Using WinInet'
11
+ family_replacement: 'ArcMap'
12
+
13
+ - regex: '(OperationsDashboard)-(?:Windows)-(\d+)\.(\d+)\.(\d+)'
14
+ family_replacement: 'Operations Dashboard for ArcGIS'
15
+
16
+ - regex: '(arcgisearth)/(\d+)\.(\d+)(?:\.(\d+)|)'
17
+ family_replacement: 'ArcGIS Earth'
18
+
19
+ - regex: 'com.esri.(earth).phone/(\d+)\.(\d+)(?:\.(\d+)|)'
20
+ family_replacement: 'ArcGIS Earth'
21
+
22
+ # ESRI ArcGIS Mobile Products
23
+ - regex: '(arcgis-explorer)/(\d+)\.(\d+)\.(\d+)'
24
+ family_replacement: 'Explorer for ArcGIS'
25
+
26
+ - regex: 'arcgis-(collector|aurora)/(\d+)\.(\d+)\.(\d+)'
27
+ family_replacement: 'Collector for ArcGIS'
28
+
29
+ - regex: '(arcgis-workforce)/(\d+)\.(\d+)\.(\d+)'
30
+ family_replacement: 'Workforce for ArcGIS'
31
+
32
+ - regex: '(Collector|Explorer|Workforce)-(?:Android|iOS)-(\d+)\.(\d+)(?:\.(\d+)|)'
33
+ family_replacement: '$1 for ArcGIS'
34
+
35
+ - regex: '(Explorer|Collector)/(\d+) CFNetwork'
36
+ family_replacement: '$1 for ArcGIS'
37
+
38
+ # ESRI ArcGIS Runtimes
39
+ - regex: 'ArcGISRuntime-(Android|iOS|NET|Qt)/(\d+)\.(\d+)(?:\.(\d+)|)'
40
+ family_replacement: 'ArcGIS Runtime SDK for $1'
41
+
42
+ - regex: 'ArcGIS\.?(iOS|Android|NET|Qt)(?:-|\.)(\d+)\.(\d+)(?:\.(\d+)|)'
43
+ family_replacement: 'ArcGIS Runtime SDK for $1'
44
+
45
+ - regex: 'ArcGIS\.Runtime\.(Qt)\.(\d+)\.(\d+)(?:\.(\d+)|)'
46
+ family_replacement: 'ArcGIS Runtime SDK for $1'
47
+
4
48
  # CFNetwork Podcast catcher Applications
49
+ - regex: '^(Luminary)[Stage]+/(\d+) CFNetwork'
5
50
  - regex: '(ESPN)[%20| ]+Radio/(\d+)\.(\d+)\.(\d+) CFNetwork'
6
51
  - regex: '(Antenna)/(\d+) CFNetwork'
7
52
  family_replacement: 'AntennaPod'
8
53
  - regex: '(TopPodcasts)Pro/(\d+) CFNetwork'
9
54
  - regex: '(MusicDownloader)Lite/(\d+)\.(\d+)\.(\d+) CFNetwork'
10
- - regex: '^(.*)-iPad/(\d+)\.?(\d+)?.?(\d+)?.?(\d+)? CFNetwork'
11
- - regex: '^(.*)-iPhone/(\d+)\.?(\d+)?.?(\d+)?.?(\d+)? CFNetwork'
12
- - regex: '^(.*)/(\d+)\.?(\d+)?.?(\d+)?.?(\d+)? CFNetwork'
55
+ - regex: '^(.*)-iPad\/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)(?:\.(\d+)|) CFNetwork'
56
+ - regex: '^(.*)-iPhone/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)(?:\.(\d+)|) CFNetwork'
57
+ - regex: '^(.*)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)(?:\.(\d+)|) CFNetwork'
13
58
 
14
59
  # Podcast catchers
60
+ - regex: '^(Luminary)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
15
61
  - regex: '(espn\.go)'
16
62
  family_replacement: 'ESPN'
17
63
  - regex: '(espnradio\.com)'
@@ -23,16 +69,23 @@ user_agent_parsers:
23
69
  - regex: ' (Rivo) RHYTHM'
24
70
 
25
71
  # @note: iOS / OSX Applications
26
- - regex: '(CFNetwork)(?:/(\d+)\.(\d+)\.?(\d+)?)?'
72
+ - regex: '(CFNetwork)(?:/(\d+)\.(\d+)(?:\.(\d+)|)|)'
27
73
  family_replacement: 'CFNetwork'
28
74
 
29
75
  # Pingdom
30
- - regex: '(Pingdom.com_bot_version_)(\d+)\.(\d+)'
76
+ - regex: '(Pingdom\.com_bot_version_)(\d+)\.(\d+)'
31
77
  family_replacement: 'PingdomBot'
32
78
  # 'Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) PingdomTMS/0.8.5 Safari/534.34'
33
79
  - regex: '(PingdomTMS)/(\d+)\.(\d+)\.(\d+)'
34
80
  family_replacement: 'PingdomBot'
35
81
 
82
+ # PTST / WebPageTest.org crawlers
83
+ - regex: ' (PTST)/(\d+)(?:\.(\d+)|)$'
84
+ family_replacement: 'WebPageTest.org bot'
85
+
86
+ # Datanyze.com spider
87
+ - regex: 'X11; (Datanyze); Linux'
88
+
36
89
  # New Relic Pinger
37
90
  - regex: '(NewRelicPinger)/(\d+)\.(\d+)'
38
91
  family_replacement: 'NewRelicPingerBot'
@@ -41,6 +94,10 @@ user_agent_parsers:
41
94
  - regex: '(Tableau)/(\d+)\.(\d+)'
42
95
  family_replacement: 'Tableau'
43
96
 
97
+ # Adobe CreativeCloud
98
+ - regex: 'AppleWebKit/\d+\.\d+.* Safari.* (CreativeCloud)/(\d+)\.(\d+).(\d+)'
99
+ family_replacement: 'Adobe CreativeCloud'
100
+
44
101
  # Salesforce
45
102
  - regex: '(Salesforce)(?:.)\/(\d+)\.(\d?)'
46
103
 
@@ -57,49 +114,73 @@ user_agent_parsers:
57
114
  family_replacement: 'GooglePlusBot'
58
115
 
59
116
  # Gmail
60
- - regex: 'via ggpht.com GoogleImageProxy'
117
+ - regex: 'via ggpht\.com GoogleImageProxy'
61
118
  family_replacement: 'GmailImageProxy'
62
119
 
63
120
  # Yahoo
64
- - regex: 'YahooMailProxy; https://help.yahoo.com/kb/yahoo-mail-proxy-SLN28749.html'
121
+ - regex: 'YahooMailProxy; https://help\.yahoo\.com/kb/yahoo-mail-proxy-SLN28749\.html'
65
122
  family_replacement: 'YahooMailProxy'
66
123
 
67
124
  # Twitter
68
125
  - regex: '(Twitterbot)/(\d+)\.(\d+)'
69
- family_replacement: 'TwitterBot'
126
+ family_replacement: 'Twitterbot'
70
127
 
71
- # Bots Pattern '/name-0.0'
72
- - regex: '/((?:Ant-)?Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \-](\d+)(?:\.(\d+)(?:\.(\d+))?)?'
73
- # Bots Pattern 'name/0.0'
74
- - regex: '\b(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?'
128
+ # Bots Pattern 'name/0.0.0'
129
+ - regex: '/((?:Ant-|)Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \-](\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
130
+ # Bots Pattern 'name/0.0.0'
131
+ - regex: '\b(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|OgScrper|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
75
132
 
76
133
  # MSIECrawler
77
- - regex: '(MSIE) (\d+)\.(\d+)([a-z]\d?)?;.* MSIECrawler'
134
+ - regex: '(MSIE) (\d+)\.(\d+)([a-z]\d|[a-z]|);.* MSIECrawler'
78
135
  family_replacement: 'MSIECrawler'
79
136
 
80
137
  # DAVdroid
81
- - regex: '(DAVdroid)/(\d+)\.(\d+)(?:\.(\d+))?'
138
+ - regex: '(DAVdroid)/(\d+)\.(\d+)(?:\.(\d+)|)'
82
139
 
83
140
  # Downloader ...
84
- - regex: '(Google-HTTP-Java-Client|Apache-HttpClient|Go-http-client|scalaj-http|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp|aihttp|reqwest)(?:[ /](\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
141
+ - regex: '(Google-HTTP-Java-Client|Apache-HttpClient|Go-http-client|scalaj-http|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp|aihttp|reqwest|axios|unirest-(?:java|python|ruby|nodejs|php|net))(?:[ /](\d+)(?:\.(\d+)|)(?:\.(\d+)|)|)'
85
142
 
86
143
  # Pinterestbot
87
- - regex: '(Pinterest(?:bot)?)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?[;\s\(]+\+https://www.pinterest.com/bot.html'
144
+ - regex: '(Pinterest(?:bot|))/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)[;\s(]+\+https://www.pinterest.com/bot.html'
88
145
  family_replacement: 'Pinterestbot'
89
146
 
90
147
  # Bots
91
- - regex: '(1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]+-Agent|AdsBot-Google(?:-[a-z]+)?|altavista|AppEngine-Google|archive.*?\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]+)*|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader(?: [A-Za-z]+)*|boitho.com-dc|BotSeer|BUbiNG|\b\w*favicon\w*\b|\bYeti(?:-[a-z]+)?|Catchpoint(?: bot)?|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher)?|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]+-)?Googlebot(?:-[a-zA-Z]+)?|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile)?|IconSurf|IlTrovatore(?:-Setaccio)?|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]+Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .*? Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media *)?|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]*|^NING|Nutch[^/]*|Nymesis|ObjectsSearch|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|Tiny Tiny RSS|TwitterBot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]+|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s)? Link Sleuth|Xerka [A-z]+Bot|yacy(?:bot)?|Yahoo[a-z]*Seeker|Yahoo! Slurp|Yandex\w+|YodaoBot(?:-[A-z]+)?|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
148
+ - regex: '(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\/\$BotVersion|123metaspider-Bot|1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\b\w{0,30}favicon\w{0,30}\b|\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg|ArcGIS Hub Indexer)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+)|)|)|)'
92
149
 
93
150
  # AWS S3 Clients
94
151
  # must come before "Bots General matcher" to catch "boto"/"boto3" before "bot"
95
- - regex: '\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|java|nodejs|ruby2?))|s3fs)/(\d+)\.(\d+)(?:\.(\d+))?'
152
+ - regex: '\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|java|nodejs|ruby2?|dotnet-(?:\d{1,2}|core)))|s3fs)/(\d+)\.(\d+)(?:\.(\d+)|)'
153
+
154
+ # SAFE FME
155
+ - regex: '(FME)\/(\d+\.\d+)\.(\d+)\.(\d+)'
156
+
157
+ # QGIS
158
+ - regex: '(QGIS)\/(\d)\.?0?(\d{1,2})\.?0?(\d{1,2})'
159
+
160
+ # JOSM
161
+ - regex: '(JOSM)/(\d+)\.(\d+)'
162
+
163
+ # Tygron Platform
164
+ - regex: '(Tygron Platform) \((\d+)\.(\d+)\.(\d+(?:\.\d+| RC \d+\.\d+))'
165
+
166
+ # Facebook
167
+ # Must come before "Bots General matcher" to catch OrangeBotswana
168
+ # Facebook Messenger must go before Facebook
169
+ - regex: '\[(FBAN/MessengerForiOS|FB_IAB/MESSENGER);FBAV/(\d+)(?:\.(\d+)(?:\.(\d+)|)|)'
170
+ family_replacement: 'Facebook Messenger'
171
+ # Facebook
172
+ - regex: '\[FB.*;(FBAV)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
173
+ family_replacement: 'Facebook'
174
+ # Sometimes Facebook does not specify a version (FBAV)
175
+ - regex: '\[FB.*;'
176
+ family_replacement: 'Facebook'
96
177
 
97
178
  # Bots General matcher 'name/0.0'
98
- - regex: '(?:\/[A-Za-z0-9\.]+)? *([A-Za-z0-9 \-_\!\[\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*))/(\d+)(?:\.(\d+)(?:\.(\d+))?)?'
99
- # Bots General matcher 'name 0.0'
100
- - regex: '(?:\/[A-Za-z0-9\.]+)? *([A-Za-z0-9 _\!\[\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*)) (\d+)(?:\.(\d+)(?:\.(\d+))?)?'
101
- # Bots containing spider|scrape|bot(but not CUBOT)|Crawl
102
- - regex: '((?:[A-z0-9]+|[A-z\-]+ ?)?(?: the )?(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[A-Za-z0-9-]*(?:[^C][^Uu])[Bb]ot|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]*)(?:(?:[ /]| v)(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
179
+ - regex: '(?:\/[A-Za-z0-9\.]+|) {0,5}([A-Za-z0-9 \-_\!\[\]:]{0,50}(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]{0,50}))[/ ](\d+)(?:\.(\d+)(?:\.(\d+)|)|)'
180
+ # Bots containing bot(but not CUBOT)
181
+ - regex: '((?:[A-Za-z][A-Za-z0-9 -]{0,50}|)[^C][^Uu][Bb]ot)\b(?:(?:[ /]| v)(\d+)(?:\.(\d+)|)(?:\.(\d+)|)|)'
182
+ # Bots containing spider|scrape|Crawl
183
+ - regex: '((?:[A-z0-9]{1,50}|[A-z\-]{1,50} ?|)(?: the |)(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]{0,50})(?:(?:[ /]| v)(\d+)(?:\.(\d+)|)(?:\.(\d+)|)|)'
103
184
 
104
185
  # HbbTV standard defines what features the browser should understand.
105
186
  # but it's like targeting "HTML5 browsers", effective browser support depends on the model
@@ -107,30 +188,47 @@ user_agent_parsers:
107
188
  - regex: '(HbbTV)/(\d+)\.(\d+)\.(\d+) \('
108
189
 
109
190
  # must go before Firefox to catch Chimera/SeaMonkey/Camino/Waterfox
110
- - regex: '(Chimera|SeaMonkey|Camino|Waterfox)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)?'
191
+ - regex: '(Chimera|SeaMonkey|Camino|Waterfox)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*|)'
111
192
 
112
- # Social Networks
113
- # Facebook
114
- - regex: '\[FB.*;(FBAV)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?'
115
- family_replacement: 'Facebook'
193
+ # must be before Firefox / Gecko to catch SailfishBrowser properly
194
+ - regex: '(SailfishBrowser)/(\d+)\.(\d+)(?:\.(\d+)|)'
195
+ family_replacement: 'Sailfish Browser'
196
+
197
+ # Social Networks (non-Facebook)
116
198
  # Pinterest
117
199
  - regex: '\[(Pinterest)/[^\]]+\]'
118
- - regex: '(Pinterest)(?: for Android(?: Tablet)?)?/(\d+)(?:\.(\d+)(?:\.(\d+))?)?'
200
+ - regex: '(Pinterest)(?: for Android(?: Tablet|)|)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
119
201
  # Instagram app
120
202
  - regex: 'Mozilla.*Mobile.*(Instagram).(\d+)\.(\d+)\.(\d+)'
121
- # Flipbaord app
203
+ # Flipboard app
122
204
  - regex: 'Mozilla.*Mobile.*(Flipboard).(\d+)\.(\d+)\.(\d+)'
123
- # Flipbaord-briefing app
205
+ # Flipboard-briefing app
124
206
  - regex: 'Mozilla.*Mobile.*(Flipboard-Briefing).(\d+)\.(\d+)\.(\d+)'
125
207
  # Onefootball app
126
208
  - regex: 'Mozilla.*Mobile.*(Onefootball)\/Android.(\d+)\.(\d+)\.(\d+)'
209
+ # Snapchat
210
+ - regex: '(Snapchat)\/(\d+)\.(\d+)\.(\d+)\.(\d+)'
211
+ # Twitter
212
+ - regex: '(Twitter for (?:iPhone|iPad)|TwitterAndroid)(?:\/(\d+)\.(\d+)|)'
213
+ family_replacement: 'Twitter'
214
+
215
+ # aspiegel.com spider (owned by Huawei)
216
+ - regex: 'Mozilla.*Mobile.*AspiegelBot'
217
+ family_replacement: 'Spider'
218
+ brand_replacement: 'Spider'
219
+ model_replacement: 'Smartphone'
220
+
221
+ - regex: 'AspiegelBot'
222
+ family_replacement: 'Spider'
223
+ brand_replacement: 'Spider'
224
+ model_replacement: 'Desktop'
127
225
 
128
226
  # Basilisk
129
227
  - regex: '(Firefox)/(\d+)\.(\d+) Basilisk/(\d+)'
130
228
  family_replacement: 'Basilisk'
131
229
 
132
230
  # Pale Moon
133
- - regex: '(PaleMoon)/(\d+)\.(\d+)\.?(\d+)?'
231
+ - regex: '(PaleMoon)/(\d+)\.(\d+)(?:\.(\d+)|)'
134
232
  family_replacement: 'Pale Moon'
135
233
 
136
234
  # Firefox
@@ -142,22 +240,22 @@ user_agent_parsers:
142
240
  family_replacement: 'Firefox Mobile'
143
241
  - regex: '(?:Mobile|Tablet);.*(Firefox)/(\d+)\.(\d+)'
144
242
  family_replacement: 'Firefox Mobile'
145
- - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)\.(\d+(?:pre)?)'
243
+ - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)\.(\d+(?:pre|))'
146
244
  family_replacement: 'Firefox ($1)'
147
245
  - regex: '(Firefox)/(\d+)\.(\d+)(a\d+[a-z]*)'
148
246
  family_replacement: 'Firefox Alpha'
149
247
  - regex: '(Firefox)/(\d+)\.(\d+)(b\d+[a-z]*)'
150
248
  family_replacement: 'Firefox Beta'
151
- - regex: '(Firefox)-(?:\d+\.\d+)?/(\d+)\.(\d+)(a\d+[a-z]*)'
249
+ - regex: '(Firefox)-(?:\d+\.\d+|)/(\d+)\.(\d+)(a\d+[a-z]*)'
152
250
  family_replacement: 'Firefox Alpha'
153
- - regex: '(Firefox)-(?:\d+\.\d+)?/(\d+)\.(\d+)(b\d+[a-z]*)'
251
+ - regex: '(Firefox)-(?:\d+\.\d+|)/(\d+)\.(\d+)(b\d+[a-z]*)'
154
252
  family_replacement: 'Firefox Beta'
155
- - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)([ab]\d+[a-z]*)?'
253
+ - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)([ab]\d+[a-z]*|)'
156
254
  family_replacement: 'Firefox ($1)'
157
255
  - regex: '(Firefox).*Tablet browser (\d+)\.(\d+)\.(\d+)'
158
256
  family_replacement: 'MicroB'
159
- - regex: '(MozillaDeveloperPreview)/(\d+)\.(\d+)([ab]\d+[a-z]*)?'
160
- - regex: '(FxiOS)/(\d+)\.(\d+)(\.(\d+))?(\.(\d+))?'
257
+ - regex: '(MozillaDeveloperPreview)/(\d+)\.(\d+)([ab]\d+[a-z]*|)'
258
+ - regex: '(FxiOS)/(\d+)\.(\d+)(\.(\d+)|)(\.(\d+)|)'
161
259
  family_replacement: 'Firefox iOS'
162
260
 
163
261
  # e.g.: Flock/2.0b2
@@ -173,7 +271,7 @@ user_agent_parsers:
173
271
  - regex: '(Navigator)/(\d+)\.(\d+)([ab]\d+)'
174
272
  family_replacement: 'Netscape'
175
273
 
176
- - regex: '(Netscape6)/(\d+)\.(\d+)\.?([ab]?\d+)?'
274
+ - regex: '(Netscape6)/(\d+)\.(\d+)\.?([ab]?\d+|)'
177
275
  family_replacement: 'Netscape'
178
276
 
179
277
  - regex: '(MyIBrow)/(\d+)\.(\d+)'
@@ -186,8 +284,8 @@ user_agent_parsers:
186
284
 
187
285
  # Opera will stop at 9.80 and hide the real version in the Version string.
188
286
  # see: http://dev.opera.com/articles/view/opera-ua-string-changes/
189
- - regex: '(Opera Tablet).*Version/(\d+)\.(\d+)(?:\.(\d+))?'
190
- - regex: '(Opera Mini)(?:/att)?/?(\d+)?(?:\.(\d+))?(?:\.(\d+))?'
287
+ - regex: '(Opera Tablet).*Version/(\d+)\.(\d+)(?:\.(\d+)|)'
288
+ - regex: '(Opera Mini)(?:/att|)/?(\d+|)(?:\.(\d+)|)(?:\.(\d+)|)'
191
289
  - regex: '(Opera)/.+Opera Mobi.+Version/(\d+)\.(\d+)'
192
290
  family_replacement: 'Opera Mobile'
193
291
  - regex: '(Opera)/(\d+)\.(\d+).+Opera Mobi'
@@ -196,7 +294,7 @@ user_agent_parsers:
196
294
  family_replacement: 'Opera Mobile'
197
295
  - regex: 'Opera Mobi'
198
296
  family_replacement: 'Opera Mobile'
199
- - regex: '(Opera)/9.80.*Version/(\d+)\.(\d+)(?:\.(\d+))?'
297
+ - regex: '(Opera)/9.80.*Version/(\d+)\.(\d+)(?:\.(\d+)|)'
200
298
 
201
299
  # Opera 14 for Android uses a WebKit render engine.
202
300
  - regex: '(?:Mobile Safari).*(OPR)/(\d+)\.(\d+)\.(\d+)'
@@ -219,7 +317,7 @@ user_agent_parsers:
219
317
  family_replacement: 'Opera Neon'
220
318
 
221
319
  # Palm WebOS looks a lot like Safari.
222
- - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
320
+ - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+)|)'
223
321
  family_replacement: 'webOS Browser'
224
322
 
225
323
  # LuaKit has no version info.
@@ -235,20 +333,20 @@ user_agent_parsers:
235
333
  - regex: 'Gecko/\d+ (Lightning)/(\d+)\.(\d+)\.?((?:[ab]?\d+[a-z]*)|(?:\d*))'
236
334
 
237
335
  # Swiftfox
238
- - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre)?) \(Swiftfox\)'
336
+ - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre|)) \(Swiftfox\)'
239
337
  family_replacement: 'Swiftfox'
240
- - regex: '(Firefox)/(\d+)\.(\d+)([ab]\d+[a-z]*)? \(Swiftfox\)'
338
+ - regex: '(Firefox)/(\d+)\.(\d+)([ab]\d+[a-z]*|) \(Swiftfox\)'
241
339
  family_replacement: 'Swiftfox'
242
340
 
243
341
  # Rekonq
244
- - regex: '(rekonq)/(\d+)\.(\d+)\.?(\d+)? Safari'
342
+ - regex: '(rekonq)/(\d+)\.(\d+)(?:\.(\d+)|) Safari'
245
343
  family_replacement: 'Rekonq'
246
344
  - regex: 'rekonq'
247
345
  family_replacement: 'Rekonq'
248
346
 
249
347
  # Conkeror lowercase/uppercase
250
348
  # http://conkeror.org/
251
- - regex: '(conkeror|Conkeror)/(\d+)\.(\d+)\.?(\d+)?'
349
+ - regex: '(conkeror|Conkeror)/(\d+)\.(\d+)(?:\.(\d+)|)'
252
350
  family_replacement: 'Conkeror'
253
351
 
254
352
  # catches lower case konqueror
@@ -277,41 +375,72 @@ user_agent_parsers:
277
375
  family_replacement: 'NetFront NX'
278
376
 
279
377
  # Amazon Silk, should go before Safari and Chrome Mobile
280
- - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
378
+ - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+)|)'
281
379
  family_replacement: 'Amazon Silk'
282
380
 
283
381
  # @ref: http://www.puffinbrowser.com
284
- - regex: '(Puffin)/(\d+)\.(\d+)(?:\.(\d+))?'
382
+ - regex: '(Puffin)/(\d+)\.(\d+)(?:\.(\d+)|)'
285
383
 
286
384
  # Edge Mobile
287
385
  - regex: 'Windows Phone .*(Edge)/(\d+)\.(\d+)'
288
386
  family_replacement: 'Edge Mobile'
387
+ - regex: '(EdgiOS|EdgA)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
388
+ family_replacement: 'Edge Mobile'
289
389
 
290
390
  # Samsung Internet (based on Chrome, but lacking some features)
291
391
  - regex: '(SamsungBrowser)/(\d+)\.(\d+)'
292
392
  family_replacement: 'Samsung Internet'
293
393
 
294
394
  # Seznam.cz browser (based on WebKit)
295
- - regex: '(SznProhlizec)/(\d+)\.(\d+)(?:\.(\d+))?'
395
+ - regex: '(SznProhlizec)/(\d+)\.(\d+)(?:\.(\d+)|)'
296
396
  family_replacement: 'Seznam prohlížeč'
297
397
 
298
398
  # Coc Coc browser, based on Chrome (used in Vietnam)
299
- - regex: '(coc_coc_browser)/(\d+)\.(\d+)(?:\.(\d+))?'
399
+ - regex: '(coc_coc_browser)/(\d+)\.(\d+)(?:\.(\d+)|)'
300
400
  family_replacement: 'Coc Coc'
301
401
 
302
402
  # Baidu Browsers (desktop spoofs chrome & IE, explorer is mobile)
303
- - regex: '(baidubrowser)[/\s](\d+)(?:\.(\d+)(?:\.(\d+))?)?'
403
+ - regex: '(baidubrowser)[/\s](\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
304
404
  family_replacement: 'Baidu Browser'
305
405
  - regex: '(FlyFlow)/(\d+)\.(\d+)'
306
406
  family_replacement: 'Baidu Explorer'
307
407
 
308
408
  # MxBrowser is Maxthon. Must go before Mobile Chrome for Android
309
- - regex: '(MxBrowser)/(\d+)\.(\d+)(?:\.(\d+))?'
409
+ - regex: '(MxBrowser)/(\d+)\.(\d+)(?:\.(\d+)|)'
310
410
  family_replacement: 'Maxthon'
311
411
 
312
412
  # Crosswalk must go before Mobile Chrome for Android
313
413
  - regex: '(Crosswalk)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
314
414
 
415
+ # LINE https://line.me/en/
416
+ # Must go before Mobile Chrome for Android
417
+ - regex: '(Line)/(\d+)\.(\d+)\.(\d+)'
418
+ family_replacement: 'LINE'
419
+
420
+ # MiuiBrowser should got before Mobile Chrome for Android
421
+ - regex: '(MiuiBrowser)/(\d+)\.(\d+)\.(\d+)'
422
+ family_replacement: 'MiuiBrowser'
423
+
424
+ # Mint Browser should got before Mobile Chrome for Android
425
+ - regex: '(Mint Browser)/(\d+)\.(\d+)\.(\d+)'
426
+ family_replacement: 'Mint Browser'
427
+
428
+ # TopBuzz Android must go before Chrome Mobile WebView
429
+ - regex: '(TopBuzz)/(\d+).(\d+).(\d+)'
430
+ family_replacement: 'TopBuzz'
431
+
432
+ # Google Search App on Android, eg:
433
+ - regex: 'Mozilla.+Android.+(GSA)/(\d+)\.(\d+)\.(\d+)'
434
+ family_replacement: 'Google'
435
+
436
+ # QQ Browsers
437
+ - regex: '(MQQBrowser/Mini)(?:(\d+)(?:\.(\d+)|)(?:\.(\d+)|)|)'
438
+ family_replacement: 'QQ Browser Mini'
439
+ - regex: '(MQQBrowser)(?:/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)|)'
440
+ family_replacement: 'QQ Browser Mobile'
441
+ - regex: '(QQBrowser)(?:/(\d+)(?:\.(\d+)\.(\d+)(?:\.(\d+)|)|)|)'
442
+ family_replacement: 'QQ Browser'
443
+
315
444
  # Chrome Mobile
316
445
  - regex: 'Version/.+(Chrome)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
317
446
  family_replacement: 'Chrome Mobile WebView'
@@ -338,18 +467,13 @@ user_agent_parsers:
338
467
  - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)'
339
468
  family_replacement: 'Sogou Explorer'
340
469
 
341
- # QQ Browsers
342
- - regex: '(MQQBrowser/Mini)(?:(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
343
- family_replacement: 'QQ Browser Mini'
344
- - regex: '(MQQBrowser)(?:/(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
345
- family_replacement: 'QQ Browser Mobile'
346
- - regex: '(QQBrowser)(?:/(\d+)(?:\.(\d+)\.(\d+)(?:\.(\d+))?)?)?'
347
- family_replacement: 'QQ Browser'
348
-
349
470
  # Rackspace Monitoring
350
471
  - regex: '(Rackspace Monitoring)/(\d+)\.(\d+)'
351
472
  family_replacement: 'RackspaceBot'
352
473
 
474
+ # PRTG Network Monitoring
475
+ - regex: '(PRTG Network Monitor)'
476
+
353
477
  # PyAMF
354
478
  - regex: '(PyAMF)/(\d+)\.(\d+)\.(\d+)'
355
479
 
@@ -365,7 +489,7 @@ user_agent_parsers:
365
489
  - regex: '(AOL) (\d+)\.(\d+); AOLBuild (\d+)'
366
490
 
367
491
  # Podcast catcher Applications using iTunes
368
- - regex: '(PodCruncher|Downcast)[ /]?(\d+)\.?(\d+)?\.?(\d+)?\.?(\d+)?'
492
+ - regex: '(PodCruncher|Downcast)[ /]?(\d+)(?:\.(\d+)|)(?:\.(\d+)|)(?:\.(\d+)|)'
369
493
 
370
494
  # Box Notes https://www.box.com/resources/downloads
371
495
  # Must be before Electron
@@ -378,6 +502,13 @@ user_agent_parsers:
378
502
  - regex: '(Whale)/(\d+)\.(\d+)\.(\d+)'
379
503
  family_replacement: 'Whale'
380
504
 
505
+ # 1Password
506
+ - regex: '(1Password)/(\d+)\.(\d+)\.(\d+)'
507
+
508
+ # Ghost
509
+ # @ref: http://www.ghost.org
510
+ - regex: '(Ghost)/(\d+)\.(\d+)\.(\d+)'
511
+
381
512
  #### END SPECIAL CASES TOP ####
382
513
 
383
514
  #### MAIN CASES - this catches > 50% of all browsers ####
@@ -389,7 +520,7 @@ user_agent_parsers:
389
520
 
390
521
  # HipChat provides a version on Mac, but not on Windows.
391
522
  # Needs to be before Chrome on Windows, and AppleMail on Mac.
392
- - regex: '(HipChat)/?(\d+)?'
523
+ - regex: '(HipChat)/?(\d+|)'
393
524
  family_replacement: 'HipChat Desktop Client'
394
525
 
395
526
  # Browser/major_version.minor_version.beta_version
@@ -411,19 +542,22 @@ user_agent_parsers:
411
542
  v1_replacement: '2013'
412
543
 
413
544
  # Outlook 2016
414
- - regex: 'Microsoft Outlook (?:Mail )?16\.\d+\.\d+'
545
+ - regex: 'Microsoft Outlook (?:Mail )?16\.\d+\.\d+|MSOffice 16'
415
546
  family_replacement: 'Outlook'
416
547
  v1_replacement: '2016'
417
548
 
549
+ # Word 2014
550
+ - regex: 'Microsoft Office (Word) 2014'
551
+
418
552
  # Windows Live Mail
419
553
  - regex: 'Outlook-Express\/7\.0.*'
420
554
  family_replacement: 'Windows Live Mail'
421
555
 
422
556
  # Apple Air Mail
423
- - regex: '(Airmail) (\d+)\.(\d+)(?:\.(\d+))?'
557
+ - regex: '(Airmail) (\d+)\.(\d+)(?:\.(\d+)|)'
424
558
 
425
559
  # Thunderbird
426
- - regex: '(Thunderbird)/(\d+)\.(\d+)(?:\.(\d+(?:pre)?))?'
560
+ - regex: '(Thunderbird)/(\d+)\.(\d+)(?:\.(\d+(?:pre|))|)'
427
561
  family_replacement: 'Thunderbird'
428
562
 
429
563
  # Postbox
@@ -431,18 +565,25 @@ user_agent_parsers:
431
565
  family_replacement: 'Postbox'
432
566
 
433
567
  # Barca
434
- - regex: '(Barca(?:Pro)?)/(\d+)\.(\d+)(?:\.(\d+))?'
568
+ - regex: '(Barca(?:Pro)?)/(\d+)\.(\d+)(?:\.(\d+)|)'
435
569
  family_replacement: 'Barca'
436
570
 
437
571
  # Lotus Notes
438
- - regex: '(Lotus-Notes)/(\d+)\.(\d+)(?:\.(\d+))?'
572
+ - regex: '(Lotus-Notes)/(\d+)\.(\d+)(?:\.(\d+)|)'
439
573
  family_replacement: 'Lotus Notes'
440
574
 
575
+ # Superhuman Mail Client
576
+ # @ref: https://www.superhuman.com
577
+ - regex: 'Superhuman'
578
+ family_replacement: 'Superhuman'
579
+
441
580
  # Vivaldi uses "Vivaldi"
442
581
  - regex: '(Vivaldi)/(\d+)\.(\d+)\.(\d+)'
443
582
 
444
583
  # Edge/major_version.minor_version
445
- - regex: '(Edge)/(\d+)(?:\.(\d+))?'
584
+ # Edge with chromium Edg/major_version.minor_version.patch.minor_patch
585
+ - regex: '(Edge?)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)(?:\.(\d+)|)'
586
+ family_replacement: 'Edge'
446
587
 
447
588
  # Brave Browser https://brave.com/
448
589
  - regex: '(brave)/(\d+)\.(\d+)\.(\d+) Chrome'
@@ -454,23 +595,23 @@ user_agent_parsers:
454
595
 
455
596
  # Dolphin Browser
456
597
  # @ref: http://www.dolphin.com
457
- - regex: '\b(Dolphin)(?: |HDCN/|/INT\-)(\d+)\.(\d+)\.?(\d+)?'
598
+ - regex: '\b(Dolphin)(?: |HDCN/|/INT\-)(\d+)\.(\d+)(?:\.(\d+)|)'
458
599
 
459
600
  # Headless Chrome
460
601
  # https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
461
- - regex: '(HeadlessChrome)(?:/(\d+)\.(\d+)\.(\d+))?'
602
+ - regex: '(HeadlessChrome)(?:/(\d+)\.(\d+)\.(\d+)|)'
462
603
 
463
604
  # Evolution Mail CardDav/CalDav integration
464
605
  - regex: '(Evolution)/(\d+)\.(\d+)\.(\d+\.\d+)'
465
606
 
466
607
  # Roundcube Mail CardDav plugin
467
- - regex: '(RCM CardDAV plugin)/(\d+)\.(\d+)\.(\d+(?:-dev)?)'
608
+ - regex: '(RCM CardDAV plugin)/(\d+)\.(\d+)\.(\d+(?:-dev|))'
468
609
 
469
610
  # Browser/major_version.minor_version
470
- - regex: '(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient|Dragon|Outlook-iOS-Android)/(\d+)\.(\d+)(?:\.(\d+))?'
611
+ - regex: '(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient|Dragon|Outlook-iOS-Android)/(\d+)\.(\d+)(?:\.(\d+)|)'
471
612
 
472
613
  # Chrome/Chromium/major_version.minor_version
473
- - regex: '(Chromium|Chrome)/(\d+)\.(\d+)(?:\.(\d+))?(?:\.(\d+))?'
614
+ - regex: '(Chromium|Chrome)/(\d+)\.(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
474
615
 
475
616
  ##########
476
617
  # IE Mobile needs to happen before Android to catch cases such as:
@@ -490,8 +631,8 @@ user_agent_parsers:
490
631
  # Podcast catchers
491
632
  - regex: '^(bPod|Pocket Casts|Player FM)$'
492
633
  - regex: '^(AlexaMediaPlayer|VLC)/(\d+)\.(\d+)\.([^.\s]+)'
493
- - regex: '^(AntennaPod|WMPlayer|Zune|Podkicker|Radio|ExoPlayerDemo|Overcast|PocketTunes|NSPlayer|okhttp|DoggCatcher|QuickNews|QuickTime|Peapod|Podcasts|GoldenPod|VLC|Spotify|Miro|MediaGo|Juice|iPodder|gPodder|Banshee)/(\d+)\.(\d+)\.?(\d+)?\.?(\d+)?'
494
- - regex: '^(Peapod|Liferea)/([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?'
634
+ - regex: '^(AntennaPod|WMPlayer|Zune|Podkicker|Radio|ExoPlayerDemo|Overcast|PocketTunes|NSPlayer|okhttp|DoggCatcher|QuickNews|QuickTime|Peapod|Podcasts|GoldenPod|VLC|Spotify|Miro|MediaGo|Juice|iPodder|gPodder|Banshee)/(\d+)\.(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
635
+ - regex: '^(Peapod|Liferea)/([^.\s]+)\.([^.\s]+|)\.?([^.\s]+|)'
495
636
  - regex: '^(bPod|Player FM) BMID/(\S+)'
496
637
  - regex: '^(Podcast ?Addict)/v(\d+) '
497
638
  - regex: '^(Podcast ?Addict) '
@@ -501,8 +642,8 @@ user_agent_parsers:
501
642
  - regex: '(CITA) RSS Aggregator/(\d+)\.(\d+)'
502
643
  - regex: '(Pocket Casts)$'
503
644
  - regex: '(Player FM)$'
504
- - regex: '(LG Player|Doppler|FancyMusic|MediaMonkey|Clementine) (\d+)\.(\d+)\.?([^.\s]+)?\.?([^.\s]+)?'
505
- - regex: '(philpodder)/(\d+)\.(\d+)\.?([^.\s]+)?\.?([^.\s]+)?'
645
+ - regex: '(LG Player|Doppler|FancyMusic|MediaMonkey|Clementine) (\d+)\.(\d+)\.?([^.\s]+|)\.?([^.\s]+|)'
646
+ - regex: '(philpodder)/(\d+)\.(\d+)\.?([^.\s]+|)\.?([^.\s]+|)'
506
647
  - regex: '(Player FM|Pocket Casts|DoggCatcher|Spotify|MediaMonkey|MediaGo|BashPodder)'
507
648
  - regex: '(QuickTime)\.(\d+)\.(\d+)\.(\d+)'
508
649
  - regex: '(Kinoma)(\d+)'
@@ -510,35 +651,35 @@ user_agent_parsers:
510
651
  family_replacement: 'FancyMusic'
511
652
  - regex: 'EspnDownloadManager'
512
653
  family_replacement: 'ESPN'
513
- - regex: '(ESPN) Radio (\d+)\.(\d+)\.?(\d+)? ?(?:rv:(\d+))? '
514
- - regex: '(podracer|jPodder) v ?(\d+)\.(\d+)\.?(\d+)?'
654
+ - regex: '(ESPN) Radio (\d+)\.(\d+)(?:\.(\d+)|) ?(?:rv:(\d+)|) '
655
+ - regex: '(podracer|jPodder) v ?(\d+)\.(\d+)(?:\.(\d+)|)'
515
656
  - regex: '(ZDM)/(\d+)\.(\d+)[; ]?'
516
- - regex: '(Zune|BeyondPod) (\d+)\.?(\d+)?[\);]'
657
+ - regex: '(Zune|BeyondPod) (\d+)(?:\.(\d+)|)[\);]'
517
658
  - regex: '(WMPlayer)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
518
659
  - regex: '^(Lavf)'
519
660
  family_replacement: 'WMPlayer'
520
- - regex: '^(RSSRadio)[ /]?(\d+)?'
661
+ - regex: '^(RSSRadio)[ /]?(\d+|)'
521
662
  - regex: '(RSS_Radio) (\d+)\.(\d+)'
522
663
  family_replacement: 'RSSRadio'
523
664
  - regex: '(Podkicker) \S+/(\d+)\.(\d+)\.(\d+)'
524
665
  family_replacement: 'Podkicker'
525
- - regex: '^(HTC) Streaming Player \S+ / \S+ / \S+ / (\d+)\.(\d+)\.?(\d+)?'
666
+ - regex: '^(HTC) Streaming Player \S+ / \S+ / \S+ / (\d+)\.(\d+)(?:\.(\d+)|)'
526
667
  - regex: '^(Stitcher)/iOS'
527
668
  - regex: '^(Stitcher)/Android'
528
669
  - regex: '^(VLC) .*version (\d+)\.(\d+)\.(\d+)'
529
670
  - regex: ' (VLC) for'
530
671
  - regex: '(vlc)/(\d+)\.(\d+)\.(\d+)'
531
672
  family_replacement: 'VLC'
532
- - regex: '^(foobar)\S+/([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?'
533
- - regex: '^(Clementine)\S+ ([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?'
534
- - regex: '(amarok)/([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?'
673
+ - regex: '^(foobar)\S+/([^.\s]+)\.([^.\s]+|)\.?([^.\s]+|)'
674
+ - regex: '^(Clementine)\S+ ([^.\s]+)\.([^.\s]+|)\.?([^.\s]+|)'
675
+ - regex: '(amarok)/([^.\s]+)\.([^.\s]+|)\.?([^.\s]+|)'
535
676
  family_replacement: 'Amarok'
536
677
  - regex: '(Custom)-Feed Reader'
537
678
 
538
679
  # Browser major_version.minor_version.beta_version (space instead of slash)
539
680
  - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
540
681
  # Browser major_version.minor_version (space instead of slash)
541
- - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris|Microsoft SkyDriveSync|The Bat!) (\d+)\.(\d+)\.?(\d+)?'
682
+ - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris|Microsoft SkyDriveSync|The Bat!) (\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
542
683
 
543
684
  # Kindle WebKit
544
685
  - regex: '(Kindle)/(\d+)\.(\d+)'
@@ -578,12 +719,16 @@ user_agent_parsers:
578
719
  - regex: '(ownCloud-android)/(\d+)\.(\d+)\.(\d+)'
579
720
  family_replacement: 'Owncloud'
580
721
 
722
+ # Skype for Business
723
+ - regex: '(OC)/(\d+)\.(\d+)\.(\d+)\.(\d+) \(Skype for Business\)'
724
+ family_replacement: 'Skype'
725
+
581
726
  #### END MAIN CASES ####
582
727
 
583
728
  #### SPECIAL CASES ####
584
729
  - regex: '(Obigo)InternetBrowser'
585
730
  - regex: '(Obigo)\-Browser'
586
- - regex: '(Obigo|OBIGO)[^\d]*(\d+)(?:.(\d+))?'
731
+ - regex: '(Obigo|OBIGO)[^\d]*(\d+)(?:.(\d+)|)'
587
732
  family_replacement: 'Obigo'
588
733
 
589
734
  - regex: '(MAXTHON|Maxthon) (\d+)\.(\d+)'
@@ -602,24 +747,32 @@ user_agent_parsers:
602
747
  - regex: '(Embider)/(\d+)\.(\d+)'
603
748
  family_replacement: 'Polaris'
604
749
 
605
- - regex: '(BonEcho)/(\d+)\.(\d+)\.?([ab]?\d+)?'
750
+ - regex: '(BonEcho)/(\d+)\.(\d+)\.?([ab]?\d+|)'
606
751
  family_replacement: 'Bon Echo'
607
752
 
753
+ # topbuzz on IOS
754
+ - regex: '(TopBuzz) com.alex.NewsMaster/(\d+).(\d+).(\d+)'
755
+ family_replacement: 'TopBuzz'
756
+ - regex: '(TopBuzz) com.mobilesrepublic.newsrepublic/(\d+).(\d+).(\d+)'
757
+ family_replacement: 'TopBuzz'
758
+ - regex: '(TopBuzz) com.topbuzz.videoen/(\d+).(\d+).(\d+)'
759
+ family_replacement: 'TopBuzz'
760
+
608
761
  # @note: iOS / OSX Applications
609
- - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+))?.*[ +]Safari'
762
+ - regex: '(iPod|iPhone|iPad).+GSA/(\d+)\.(\d+)\.(\d+)(?:\.(\d+)|) Mobile'
763
+ family_replacement: 'Google'
764
+ - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+)|).*[ +]Safari'
610
765
  family_replacement: 'Mobile Safari'
611
- - regex: '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\d+)_(\d+)(?:_(\d+))?.* AppleNews\/\d+\.\d+\.\d+?'
766
+ - regex: '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\d+)_(\d+)(?:_(\d+)|).* AppleNews\/\d+\.\d+\.\d+?'
612
767
  family_replacement: 'Mobile Safari UI/WKWebView'
613
- - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+))?'
614
- family_replacement: 'Mobile Safari UI/WKWebView'
615
- - regex: '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\d+)_(\d+)(?:_(\d+))?.*Mobile.*[ +]Safari'
616
- family_replacement: 'Mobile Safari'
617
- - regex: '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\d+)_(\d+)(?:_(\d+))?.*Mobile'
768
+ - regex: '(iPod|iPhone|iPad).+Version/(\d+)\.(\d+)(?:\.(\d+)|)'
618
769
  family_replacement: 'Mobile Safari UI/WKWebView'
619
- - regex: '(iPod|iPhone|iPad).* Safari'
770
+ - regex: '(iPod|iPod touch|iPhone|iPad).* Safari'
620
771
  family_replacement: 'Mobile Safari'
621
- - regex: '(iPod|iPhone|iPad)'
772
+ - regex: '(iPod|iPod touch|iPhone|iPad)'
622
773
  family_replacement: 'Mobile Safari UI/WKWebView'
774
+ - regex: '(Watch)(\d+),(\d+)'
775
+ family_replacement: 'Apple $1 App'
623
776
 
624
777
  ##########################
625
778
  # Outlook on iOS >= 2.62.0
@@ -687,18 +840,18 @@ user_agent_parsers:
687
840
 
688
841
  - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)'
689
842
 
690
- #- regex: '\(iPad;.+(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/'
843
+ #- regex: '\(iPad;.+(Version)/(\d+)\.(\d+)(?:\.(\d+)|).*Safari/'
691
844
  # family_replacement: 'iPad'
692
845
 
693
846
  # Phantomjs, should go before Safari
694
847
  - regex: '(PhantomJS)/(\d+)\.(\d+)\.(\d+)'
695
848
 
696
849
  # WebKit Nightly
697
- - regex: '(AppleWebKit)/(\d+)\.?(\d+)?\+ .* Safari'
850
+ - regex: '(AppleWebKit)/(\d+)(?:\.(\d+)|)\+ .* Safari'
698
851
  family_replacement: 'WebKit Nightly'
699
852
 
700
853
  # Safari
701
- - regex: '(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/'
854
+ - regex: '(Version)/(\d+)\.(\d+)(?:\.(\d+)|).*Safari/'
702
855
  family_replacement: 'Safari'
703
856
  # Safari didn't provide "Version/d.d.d" prior to 3.0
704
857
  - regex: '(Safari)/\d+'
@@ -733,9 +886,9 @@ user_agent_parsers:
733
886
  v1_replacement: '8'
734
887
 
735
888
  # Espial
736
- - regex: '(Espial)/(\d+)(?:\.(\d+))?(?:\.(\d+))?'
889
+ - regex: '(Espial)/(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
737
890
 
738
- # Apple Mail
891
+ # Apple Mail
739
892
 
740
893
  # apple mail - not directly detectable, have it after Safari stuff
741
894
  - regex: '(AppleWebKit)/(\d+)\.(\d+)\.(\d+)'
@@ -745,7 +898,7 @@ user_agent_parsers:
745
898
  # AFTER IE11
746
899
  # BEFORE all other IE
747
900
  - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
748
- - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
901
+ - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*|)'
749
902
 
750
903
  - regex: '([MS]?IE) (\d+)\.(\d+)'
751
904
  family_replacement: 'IE'
@@ -754,13 +907,22 @@ user_agent_parsers:
754
907
  family_replacement: 'Python Requests'
755
908
 
756
909
  # headless user-agents
757
- - regex: '\b(Windows-Update-Agent|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia)(?:[ /](\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
910
+ - regex: '\b(Windows-Update-Agent|WindowsPowerShell|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|wget2|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia|fetch libfetch|akka-http|got)(?:[ /](\d+)(?:\.(\d+)|)(?:\.(\d+)|)|)'
911
+
912
+ # Asynchronous HTTP Client/Server for asyncio and Python (https://aiohttp.readthedocs.io/)
913
+ - regex: '(Python/3\.\d{1,3} aiohttp)/(\d+)\.(\d+)\.(\d+)'
914
+ family_replacement: 'Python aiohttp'
758
915
 
759
- - regex: '(Java)[/ ]{0,1}\d+\.(\d+)\.(\d+)[_-]*([a-zA-Z0-9]+)*'
916
+ - regex: '(Java)[/ ]?\d+\.(\d+)\.(\d+)[_-]*([a-zA-Z0-9]+|)'
760
917
 
761
918
  # Cloud Storage Clients
762
- - regex: '^(Cyberduck)/(\d+)\.(\d+)\.(\d+)(?:\.\d+)?'
763
- - regex: '^(S3 Browser) (\d+)-(\d+)-(\d+)(?:\s*http://s3browser\.com)?'
919
+ - regex: '^(Cyberduck)/(\d+)\.(\d+)\.(\d+)(?:\.\d+|)'
920
+ - regex: '^(S3 Browser) (\d+)-(\d+)-(\d+)(?:\s*http://s3browser\.com|)'
921
+ - regex: '(S3Gof3r)'
922
+ # IBM COS (Cloud Object Storage) API
923
+ - regex: '\b(ibm-cos-sdk-(?:core|java|js|python))/(\d+)\.(\d+)(?:\.(\d+)|)'
924
+ # rusoto - Rusoto - AWS SDK for Rust - https://github.com/rusoto/rusoto
925
+ - regex: '^(rusoto)/(\d+)\.(\d+)\.(\d+)'
764
926
  # rclone - rsync for cloud storage - https://rclone.org/
765
927
  - regex: '^(rclone)/v(\d+)\.(\d+)'
766
928
 
@@ -774,6 +936,10 @@ user_agent_parsers:
774
936
  # Box Drive and Box Sync https://www.box.com/resources/downloads
775
937
  - regex: '^(Box(?: Sync)?)/(\d+)\.(\d+)\.(\d+)'
776
938
 
939
+ # ViaFree streaming app https://www.viafree.{dk|se|no}
940
+ - regex: '^(ViaFree|Viafree)-(?:tvOS-)?[A-Z]{2}/(\d+)\.(\d+)\.(\d+)'
941
+ family_replacement: 'ViaFree'
942
+
777
943
  os_parsers:
778
944
  ##########
779
945
  # HbbTV vendors
@@ -819,11 +985,11 @@ os_parsers:
819
985
  # Philips : not found any other way than a manual mapping
820
986
  # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/4.1.3 PHILIPSTV/1.1.1; en) Presto/2.10.250 Version/11.60
821
987
  # Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70
822
- - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/4'
988
+ - regex: 'HbbTV/1\.1\.1 \(; (Philips);.*NETTV/4'
823
989
  os_v1_replacement: '2013'
824
- - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/3'
990
+ - regex: 'HbbTV/1\.1\.1 \(; (Philips);.*NETTV/3'
825
991
  os_v1_replacement: '2012'
826
- - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/2'
992
+ - regex: 'HbbTV/1\.1\.1 \(; (Philips);.*NETTV/2'
827
993
  os_v1_replacement: '2011'
828
994
 
829
995
  # the HbbTV emulator developers use HbbTV/1.1.1 (;;;;;) firetv-firefox-plugin 1.1.20
@@ -833,6 +999,10 @@ os_parsers:
833
999
  # generic HbbTV, hoping to catch manufacturer name (always after 2nd comma) and the first string that looks like a 2011-2019 year
834
1000
  - regex: 'HbbTV/\d+\.\d+\.\d+ \(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\)'
835
1001
 
1002
+ # aspiegel.com spider (owned by Huawei)
1003
+ - regex: 'AspiegelBot'
1004
+ os_replacement: 'Other'
1005
+
836
1006
  ##########
837
1007
  # @note: Windows Phone needs to come before Windows NT 6.1 *and* before Android to catch cases such as:
838
1008
  # Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920)...
@@ -844,14 +1014,20 @@ os_parsers:
844
1014
  - regex: '(Windows Phone) (?:OS[ /])?(\d+)\.(\d+)'
845
1015
 
846
1016
  # Again a MS-special one: iPhone.*Outlook-iOS-Android/x.x is erroneously detected as Android
847
- - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+))?.*Outlook-iOS-Android'
1017
+ - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+)|).*Outlook-iOS-Android'
848
1018
  os_replacement: 'iOS'
849
1019
 
1020
+ # Special case for old ArcGIS Mobile products
1021
+ - regex: 'ArcGIS\.?(iOS|Android)-\d+\.\d+(?:\.\d+|)(?:[^\/]+|)\/(\d+)(?:\.(\d+)(?:\.(\d+)|)|)'
1022
+
1023
+ # Special case for new ArcGIS Mobile products
1024
+ - regex: 'ArcGISRuntime-(?:Android|iOS)\/\d+\.\d+(?:\.\d+|) \((Android|iOS) (\d+)(?:\.(\d+)(?:\.(\d+)|)|);'
1025
+
850
1026
  ##########
851
1027
  # Android
852
1028
  # can actually detect rooted android os. do we care?
853
1029
  ##########
854
- - regex: '(Android)[ \-/](\d+)\.?(\d+)?(?:[.\-]([a-z0-9]+))?'
1030
+ - regex: '(Android)[ \-/](\d+)(?:\.(\d+)|)(?:[.\-]([a-z0-9]+)|)'
855
1031
 
856
1032
  - regex: '(Android) Donut'
857
1033
  os_v1_replacement: '1'
@@ -872,19 +1048,22 @@ os_parsers:
872
1048
  - regex: '(Android) Honeycomb'
873
1049
  os_v1_replacement: '3'
874
1050
 
1051
+ # Android 9; Android 10;
1052
+ - regex: '(Android) (\d+);'
1053
+
875
1054
  # UCWEB
876
- - regex: '^UCWEB.*; (Adr) (\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?;'
1055
+ - regex: '^UCWEB.*; (Adr) (\d+)\.(\d+)(?:[.\-]([a-z0-9]+)|);'
877
1056
  os_replacement: 'Android'
878
- - regex: '^UCWEB.*; (iPad|iPh|iPd) OS (\d+)_(\d+)(?:_(\d+))?;'
1057
+ - regex: '^UCWEB.*; (iPad|iPh|iPd) OS (\d+)_(\d+)(?:_(\d+)|);'
879
1058
  os_replacement: 'iOS'
880
- - regex: '^UCWEB.*; (wds) (\d+)\.(\d+)(?:\.(\d+))?;'
1059
+ - regex: '^UCWEB.*; (wds) (\d+)\.(\d+)(?:\.(\d+)|);'
881
1060
  os_replacement: 'Windows Phone'
882
1061
  # JUC
883
- - regex: '^(JUC).*; ?U; ?(?:Android)?(\d+)\.(\d+)(?:[\.\-]([a-z0-9]+))?'
1062
+ - regex: '^(JUC).*; ?U; ?(?:Android|)(\d+)\.(\d+)(?:[\.\-]([a-z0-9]+)|)'
884
1063
  os_replacement: 'Android'
885
1064
 
886
1065
  # Salesforce
887
- - regex: '(android)\s(?:mobile\/)(\d+)\.(\d+)\.?(\d+)?'
1066
+ - regex: '(android)\s(?:mobile\/)(\d+)(?:\.(\d+)(?:\.(\d+)|)|)'
888
1067
  os_replacement: 'Android'
889
1068
 
890
1069
  ##########
@@ -893,6 +1072,14 @@ os_parsers:
893
1072
  - regex: '(Silk-Accelerated=[a-z]{4,5})'
894
1073
  os_replacement: 'Android'
895
1074
 
1075
+ # Citrix Chrome App on Chrome OS
1076
+ # Note, this needs to come before the windows parsers as the app doesn't
1077
+ # properly identify as Chrome OS
1078
+ #
1079
+ # ex: Mozilla/5.0 (X11; Windows aarch64 10718.88.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.118 Safari/537.36 CitrixChromeApp
1080
+ - regex: '(x86_64|aarch64)\ (\d+)\.(\d+)\.(\d+).*Chrome.*(?:CitrixChromeApp)$'
1081
+ os_replacement: 'Chrome OS'
1082
+
896
1083
  ##########
897
1084
  # Windows
898
1085
  # http://en.wikipedia.org/wiki/Windows_NT#Releases
@@ -911,15 +1098,19 @@ os_parsers:
911
1098
  - regex: '(Windows ?Mobile)'
912
1099
  os_replacement: 'Windows Mobile'
913
1100
 
1101
+ - regex: '(Windows 10)'
1102
+ os_replacement: 'Windows'
1103
+ os_v1_replacement: '10'
1104
+
914
1105
  - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
915
1106
  os_replacement: 'Windows'
916
1107
  os_v1_replacement: 'XP'
917
1108
 
918
- - regex: '(Windows NT 6\.1)'
1109
+ - regex: '(Win(?:dows NT |32NT\/)6\.1)'
919
1110
  os_replacement: 'Windows'
920
1111
  os_v1_replacement: '7'
921
1112
 
922
- - regex: '(Windows NT 6\.0)'
1113
+ - regex: '(Win(?:dows NT |32NT\/)6\.0)'
923
1114
  os_replacement: 'Windows'
924
1115
  os_v1_replacement: 'Vista'
925
1116
 
@@ -927,25 +1118,25 @@ os_parsers:
927
1118
  os_replacement: 'Windows'
928
1119
  os_v1_replacement: 'ME'
929
1120
 
930
- - regex: '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\.0|Windows Vista|Windows 2000|Windows 3.1)'
931
-
932
1121
  - regex: '(Windows NT 6\.2; ARM;)'
933
1122
  os_replacement: 'Windows'
934
1123
  os_v1_replacement: 'RT'
935
1124
 
936
- - regex: '(Windows NT 6\.2)'
1125
+ - regex: '(Win(?:dows NT |32NT\/)6\.2)'
937
1126
  os_replacement: 'Windows'
938
1127
  os_v1_replacement: '8'
939
1128
 
940
1129
  - regex: '(Windows NT 6\.3; ARM;)'
941
1130
  os_replacement: 'Windows'
942
- os_v1_replacement: 'RT 8.1'
1131
+ os_v1_replacement: 'RT 8'
1132
+ os_v2_replacement: '1'
943
1133
 
944
- - regex: '(Windows NT 6\.3)'
1134
+ - regex: '(Win(?:dows NT |32NT\/)6\.3)'
945
1135
  os_replacement: 'Windows'
946
- os_v1_replacement: '8.1'
1136
+ os_v1_replacement: '8'
1137
+ os_v2_replacement: '1'
947
1138
 
948
- - regex: '(Windows NT 6\.4)'
1139
+ - regex: '(Win(?:dows NT |32NT\/)6\.4)'
949
1140
  os_replacement: 'Windows'
950
1141
  os_v1_replacement: '10'
951
1142
 
@@ -965,7 +1156,7 @@ os_parsers:
965
1156
  os_replacement: 'Windows'
966
1157
  os_v1_replacement: 'CE'
967
1158
 
968
- - regex: 'Win ?(95|98|3.1|NT|ME|2000)'
1159
+ - regex: 'Win(?:dows)? ?(95|98|3.1|NT|ME|2000|XP|Vista|7|CE)'
969
1160
  os_replacement: 'Windows'
970
1161
  os_v1_replacement: '$1'
971
1162
 
@@ -993,13 +1184,13 @@ os_parsers:
993
1184
  # @ref: http://en.wikipedia.org/wiki/Mac_OS_X#Versions
994
1185
  # @ref: http://www.puredarwin.org/curious/versions
995
1186
  ##########
996
- - regex: '((?:Mac[ +]?|; )OS[ +]X)[\s+/](?:(\d+)[_.](\d+)(?:[_.](\d+))?|Mach-O)'
1187
+ - regex: '((?:Mac[ +]?|; )OS[ +]X)[\s+/](?:(\d+)[_.](\d+)(?:[_.](\d+)|)|Mach-O)'
997
1188
  os_replacement: 'Mac OS X'
998
- - regex: '(\w+\s+Mac OS X\s+\w+\s+(\d+).(\d+).(\d+).*)'
1189
+ - regex: '\w+\s+Mac OS X\s+\w+\s+(\d+).(\d+).(\d+).*'
999
1190
  os_replacement: 'Mac OS X'
1000
- os_v1_replacement: '$2'
1001
- os_v2_replacement: '$3'
1002
- os_v3_replacement: '$4'
1191
+ os_v1_replacement: '$1'
1192
+ os_v2_replacement: '$2'
1193
+ os_v3_replacement: '$3'
1003
1194
  # Leopard
1004
1195
  - regex: ' (Dar)(win)/(9).(\d+).*\((?:i386|x86_64|Power Macintosh)\)'
1005
1196
  os_replacement: 'Mac OS X'
@@ -1038,7 +1229,7 @@ os_parsers:
1038
1229
  - regex: '(?:PPC|Intel) (Mac OS X)'
1039
1230
 
1040
1231
  # Box Drive and Box Sync on Mac OS X use OSX version numbers, not Darwin
1041
- - regex: '^Box.*;(Darwin)/(10)\.(1\d)(?:\.(\d+))?'
1232
+ - regex: '^Box.*;(Darwin)/(10)\.(1\d)(?:\.(\d+)|)'
1042
1233
  os_replacement: 'Mac OS X'
1043
1234
 
1044
1235
  ##########
@@ -1046,10 +1237,10 @@ os_parsers:
1046
1237
  # http://en.wikipedia.org/wiki/IOS_version_history
1047
1238
  ##########
1048
1239
  # keep this above generic iOS, since AppleTV UAs contain 'CPU OS'
1049
- - regex: '(Apple\s?TV)(?:/(\d+)\.(\d+))?'
1240
+ - regex: '(Apple\s?TV)(?:/(\d+)\.(\d+)|)'
1050
1241
  os_replacement: 'ATV OS X'
1051
1242
 
1052
- - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+))?'
1243
+ - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+)|)'
1053
1244
  os_replacement: 'iOS'
1054
1245
 
1055
1246
  # remaining cases are mostly only opera uas, so catch opera as to not catch iphone spoofs
@@ -1231,19 +1422,31 @@ os_parsers:
1231
1422
  os_replacement: 'iOS'
1232
1423
 
1233
1424
  # iOS Apps
1234
- - regex: '\b(iOS[ /]|iOS; |iPhone(?:/| v|[ _]OS[/,]|; | OS : |\d,\d/|\d,\d; )|iPad/)(\d{1,2})[_\.](\d{1,2})(?:[_\.](\d+))?'
1425
+ - regex: '\b(iOS[ /]|iOS; |iPhone(?:/| v|[ _]OS[/,]|; | OS : |\d,\d/|\d,\d; )|iPad/)(\d{1,2})[_\.](\d{1,2})(?:[_\.](\d+)|)'
1235
1426
  os_replacement: 'iOS'
1236
1427
  - regex: '\((iOS);'
1237
1428
 
1429
+ ##########
1430
+ # Apple Watch
1431
+ ##########
1432
+ - regex: '(watchOS)/(\d+)\.(\d+)(?:\.(\d+)|)'
1433
+ os_replacement: 'WatchOS'
1434
+
1238
1435
  ##########################
1239
1436
  # Outlook on iOS >= 2.62.0
1240
1437
  ##########################
1241
1438
  - regex: 'Outlook-(iOS)/\d+\.\d+\.prod\.iphone'
1242
1439
 
1440
+ ##########################
1441
+ # iOS devices, the same regex matches mobile safari webviews
1442
+ ##########################
1443
+ - regex: '(iPod|iPhone|iPad)'
1444
+ os_replacement: 'iOS'
1445
+
1243
1446
  ##########
1244
1447
  # Apple TV
1245
1448
  ##########
1246
- - regex: '(tvOS)/(\d+).(\d+)'
1449
+ - regex: '(tvOS)[/ ](\d+)\.(\d+)(?:\.(\d+)|)'
1247
1450
  os_replacement: 'tvOS'
1248
1451
 
1249
1452
  ##########
@@ -1252,7 +1455,7 @@ os_parsers:
1252
1455
  # http://code.google.com/p/chromium-os/issues/detail?id=11573
1253
1456
  # http://code.google.com/p/chromium-os/issues/detail?id=13790
1254
1457
  ##########
1255
- - regex: '(CrOS) [a-z0-9_]+ (\d+)\.(\d+)(?:\.(\d+))?'
1458
+ - regex: '(CrOS) [a-z0-9_]+ (\d+)\.(\d+)(?:\.(\d+)|)'
1256
1459
  os_replacement: 'Chrome OS'
1257
1460
 
1258
1461
  ##########
@@ -1260,8 +1463,8 @@ os_parsers:
1260
1463
  ##########
1261
1464
  - regex: '([Dd]ebian)'
1262
1465
  os_replacement: 'Debian'
1263
- - regex: '(Linux Mint)(?:/(\d+))?'
1264
- - regex: '(Mandriva)(?: Linux)?/(?:[\d.-]+m[a-z]{2}(\d+).(\d))?'
1466
+ - regex: '(Linux Mint)(?:/(\d+)|)'
1467
+ - regex: '(Mandriva)(?: Linux|)/(?:[\d.-]+m[a-z]{2}(\d+).(\d)|)'
1265
1468
 
1266
1469
  ##########
1267
1470
  # Symbian + Symbian OS
@@ -1290,9 +1493,9 @@ os_parsers:
1290
1493
  ##########
1291
1494
  - regex: '(BB10);.+Version/(\d+)\.(\d+)\.(\d+)'
1292
1495
  os_replacement: 'BlackBerry OS'
1293
- - regex: '(Black[Bb]erry)[0-9a-z]+/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
1496
+ - regex: '(Black[Bb]erry)[0-9a-z]+/(\d+)\.(\d+)\.(\d+)(?:\.(\d+)|)'
1294
1497
  os_replacement: 'BlackBerry OS'
1295
- - regex: '(Black[Bb]erry).+Version/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
1498
+ - regex: '(Black[Bb]erry).+Version/(\d+)\.(\d+)\.(\d+)(?:\.(\d+)|)'
1296
1499
  os_replacement: 'BlackBerry OS'
1297
1500
  - regex: '(RIM Tablet OS) (\d+)\.(\d+)\.(\d+)'
1298
1501
  os_replacement: 'BlackBerry Tablet OS'
@@ -1301,6 +1504,12 @@ os_parsers:
1301
1504
  - regex: '(Black[Bb]erry)'
1302
1505
  os_replacement: 'BlackBerry OS'
1303
1506
 
1507
+ ##########
1508
+ # KaiOS
1509
+ ##########
1510
+ - regex: '(K[Aa][Ii]OS)\/(\d+)\.(\d+)(?:\.(\d+)|)'
1511
+ os_replacement: 'KaiOS'
1512
+
1304
1513
  ##########
1305
1514
  # Firefox OS
1306
1515
  ##########
@@ -1359,20 +1568,20 @@ os_parsers:
1359
1568
  ##########
1360
1569
  # Google TV
1361
1570
  ##########
1362
- - regex: '(GoogleTV)(?: (\d+)\.(\d+)(?:\.(\d+))?|/[\da-z]+)'
1571
+ - regex: '(GoogleTV)(?: (\d+)\.(\d+)(?:\.(\d+)|)|/[\da-z]+)'
1363
1572
 
1364
1573
  - regex: '(WebTV)/(\d+).(\d+)'
1365
1574
 
1366
1575
  ##########
1367
1576
  # Chromecast
1368
1577
  ##########
1369
- - regex: '(CrKey)(?:[/](\d+)\.(\d+)(?:\.(\d+))?)?'
1578
+ - regex: '(CrKey)(?:[/](\d+)\.(\d+)(?:\.(\d+)|)|)'
1370
1579
  os_replacement: 'Chromecast'
1371
1580
 
1372
1581
  ##########
1373
1582
  # Misc mobile
1374
1583
  ##########
1375
- - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
1584
+ - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+)|)'
1376
1585
  os_replacement: 'webOS'
1377
1586
  - regex: '(VRE);'
1378
1587
 
@@ -1380,10 +1589,10 @@ os_parsers:
1380
1589
  # Generic patterns
1381
1590
  # since the majority of os cases are very specific, these go last
1382
1591
  ##########
1383
- - regex: '(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\b)BSD)[/ ](\d+)\.(\d+)(?:\.(\d+)(?:\.(\d+))?)?'
1592
+ - regex: '(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Sailfish|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\b)BSD)[/ ](\d+)\.(\d+)(?:\.(\d+)|)(?:\.(\d+)|)'
1384
1593
 
1385
1594
  # Gentoo Linux + Kernel Version
1386
- - regex: '(Linux)[ /](\d+)\.(\d+)(?:\.(\d+))?.*gentoo'
1595
+ - regex: '(Linux)[ /](\d+)\.(\d+)(?:\.(\d+)|).*gentoo'
1387
1596
  os_replacement: 'Gentoo'
1388
1597
 
1389
1598
  # Opera Mini Bada
@@ -1393,7 +1602,7 @@ os_parsers:
1393
1602
  - regex: '(Windows|Android|WeTab|Maemo|Web0S)'
1394
1603
  - regex: '(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Mageia|(?:Free|Open|Net|\b)BSD)'
1395
1604
  # Linux + Kernel Version
1396
- - regex: '(Linux)(?:[ /](\d+)\.(\d+)(?:\.(\d+))?)?'
1605
+ - regex: '(Linux)(?:[ /](\d+)\.(\d+)(?:\.(\d+)|)|)'
1397
1606
  - regex: 'SunOS'
1398
1607
  os_replacement: 'Solaris'
1399
1608
  # Wget/x.x.x (linux-gnu)
@@ -1403,6 +1612,8 @@ os_parsers:
1403
1612
  os_replacement: 'Red Hat'
1404
1613
  - regex: '\((freebsd)(\d+)\.(\d+)\)'
1405
1614
  os_replacement: 'FreeBSD'
1615
+ - regex: 'linux'
1616
+ os_replacement: 'Linux'
1406
1617
 
1407
1618
  # Roku Digital-Video-Players https://www.roku.com/
1408
1619
  - regex: '^(Roku)/DVP-(\d+)\.(\d+)'
@@ -1424,11 +1635,31 @@ device_parsers:
1424
1635
  brand_replacement: 'Spider'
1425
1636
  model_replacement: 'Feature Phone'
1426
1637
 
1638
+ # PTST / WebPageTest.org crawlers
1639
+ - regex: ' PTST/\d+(?:\.)?\d+$'
1640
+ device_replacement: 'Spider'
1641
+ brand_replacement: 'Spider'
1642
+
1643
+ # Datanyze.com spider
1644
+ - regex: 'X11; Datanyze; Linux'
1645
+ device_replacement: 'Spider'
1646
+ brand_replacement: 'Spider'
1647
+
1648
+ # aspiegel.com spider (owned by Huawei)
1649
+ - regex: 'Mozilla.*Mobile.*AspiegelBot'
1650
+ device_replacement: 'Spider'
1651
+ brand_replacement: 'Spider'
1652
+ model_replacement: 'Smartphone'
1653
+ - regex: 'Mozilla.*AspiegelBot'
1654
+ device_replacement: 'Spider'
1655
+ brand_replacement: 'Spider'
1656
+ model_replacement: 'Desktop'
1657
+
1427
1658
  #########
1428
1659
  # WebBrowser for SmartWatch
1429
1660
  # @ref: https://play.google.com/store/apps/details?id=se.vaggan.webbrowser&hl=en
1430
1661
  #########
1431
- - regex: '\bSmartWatch *\( *([^;]+) *; *([^;]+) *;'
1662
+ - regex: '\bSmartWatch {0,2}\( {0,2}([^;]+) {0,2}; {0,2}([^;]+) {0,2};'
1432
1663
  device_replacement: '$1 $2'
1433
1664
  brand_replacement: '$1'
1434
1665
  model_replacement: '$2'
@@ -1440,7 +1671,7 @@ device_parsers:
1440
1671
  ######################################################################
1441
1672
 
1442
1673
  # Android Application
1443
- - regex: 'Android Application[^\-]+ - (Sony) ?(Ericsson)? (.+) \w+ - '
1674
+ - regex: 'Android Application[^\-]+ - (Sony) ?(Ericsson|) (.+) \w+ - '
1444
1675
  device_replacement: '$1 $2'
1445
1676
  brand_replacement: '$1$2'
1446
1677
  model_replacement: '$3'
@@ -1458,11 +1689,11 @@ device_parsers:
1458
1689
  # 3Q
1459
1690
  # @ref: http://www.3q-int.com/
1460
1691
  #########
1461
- - regex: '; *([BLRQ]C\d{4}[A-Z]+) +Build/'
1692
+ - regex: '; *([BLRQ]C\d{4}[A-Z]+?)(?: Build|\) AppleWebKit)'
1462
1693
  device_replacement: '3Q $1'
1463
1694
  brand_replacement: '3Q'
1464
1695
  model_replacement: '$1'
1465
- - regex: '; *(?:3Q_)([^;/]+) +Build'
1696
+ - regex: '; *(?:3Q_)([^;/]+?)(?: Build|\) AppleWebKit)'
1466
1697
  device_replacement: '3Q $1'
1467
1698
  brand_replacement: '3Q'
1468
1699
  model_replacement: '$1'
@@ -1471,19 +1702,19 @@ device_parsers:
1471
1702
  # Acer
1472
1703
  # @ref: http://us.acer.com/ac/en/US/content/group/tablets
1473
1704
  #########
1474
- - regex: 'Android [34].*; *(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700(?: Lite| 3G)?|A701|B1-A71|A1-\d{3}|B1-\d{3}|V360|V370|W500|W500P|W501|W501P|W510|W511|W700|Slider SL101|DA22[^;/]+) Build'
1705
+ - regex: 'Android [34].*; *(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700(?: Lite| 3G|)|A701|B1-A71|A1-\d{3}|B1-\d{3}|V360|V370|W500|W500P|W501|W501P|W510|W511|W700|Slider SL101|DA22[^;/]+?)(?: Build|\) AppleWebKit)'
1475
1706
  device_replacement: '$1'
1476
1707
  brand_replacement: 'Acer'
1477
1708
  model_replacement: '$1'
1478
- - regex: '; *Acer Iconia Tab ([^;/]+) Build'
1709
+ - regex: '; *Acer Iconia Tab ([^;/]+?)(?: Build|\) AppleWebKit)'
1479
1710
  device_replacement: '$1'
1480
1711
  brand_replacement: 'Acer'
1481
1712
  model_replacement: '$1'
1482
- - regex: '; *(Z1[1235]0|E320[^/]*|S500|S510|Liquid[^;/]*|Iconia A\d+) Build'
1713
+ - regex: '; *(Z1[1235]0|E320[^/]*|S500|S510|Liquid[^;/]*|Iconia A\d+)(?: Build|\) AppleWebKit)'
1483
1714
  device_replacement: '$1'
1484
1715
  brand_replacement: 'Acer'
1485
1716
  model_replacement: '$1'
1486
- - regex: '; *(Acer |ACER )([^;/]+) Build'
1717
+ - regex: '; *(Acer |ACER )([^;/]+?)(?: Build|\) AppleWebKit)'
1487
1718
  device_replacement: '$1$2'
1488
1719
  brand_replacement: 'Acer'
1489
1720
  model_replacement: '$2'
@@ -1494,7 +1725,7 @@ device_parsers:
1494
1725
  # @note: VegaBean and VegaComb (names derived from jellybean, honeycomb) are
1495
1726
  # custom ROM builds for Vega
1496
1727
  #########
1497
- - regex: '; *(Advent )?(Vega(?:Bean|Comb)?).* Build'
1728
+ - regex: '; *(Advent |)(Vega(?:Bean|Comb|)).*?(?: Build|\) AppleWebKit)'
1498
1729
  device_replacement: '$1$2'
1499
1730
  brand_replacement: 'Advent'
1500
1731
  model_replacement: '$2'
@@ -1503,7 +1734,7 @@ device_parsers:
1503
1734
  # Ainol
1504
1735
  # @ref: http://www.ainol.com/plugin.php?identifier=ainol&module=product
1505
1736
  #########
1506
- - regex: '; *(Ainol )?((?:NOVO|[Nn]ovo)[^;/]+) Build'
1737
+ - regex: '; *(Ainol |)((?:NOVO|[Nn]ovo)[^;/]+?)(?: Build|\) AppleWebKit)'
1507
1738
  device_replacement: '$1$2'
1508
1739
  brand_replacement: 'Ainol'
1509
1740
  model_replacement: '$2'
@@ -1517,7 +1748,7 @@ device_parsers:
1517
1748
  device_replacement: '$1'
1518
1749
  brand_replacement: 'Airis'
1519
1750
  model_replacement: '$1'
1520
- - regex: '; *(OnePAD[^;/]+) Build'
1751
+ - regex: '; *(OnePAD[^;/]+?)(?: Build|\) AppleWebKit)'
1521
1752
  regex_flag: 'i'
1522
1753
  device_replacement: '$1'
1523
1754
  brand_replacement: 'Airis'
@@ -1527,7 +1758,7 @@ device_parsers:
1527
1758
  # Airpad
1528
1759
  # @ref: ??
1529
1760
  #########
1530
- - regex: '; *Airpad[ \-]([^;/]+) Build'
1761
+ - regex: '; *Airpad[ \-]([^;/]+?)(?: Build|\) AppleWebKit)'
1531
1762
  device_replacement: 'Airpad $1'
1532
1763
  brand_replacement: 'Airpad'
1533
1764
  model_replacement: '$1'
@@ -1536,29 +1767,29 @@ device_parsers:
1536
1767
  # Alcatel - TCT
1537
1768
  # @ref: http://www.alcatelonetouch.com/global-en/products/smartphones.html
1538
1769
  #########
1539
- - regex: '; *(one ?touch) (EVO7|T10|T20) Build'
1770
+ - regex: '; *(one ?touch) (EVO7|T10|T20)(?: Build|\) AppleWebKit)'
1540
1771
  device_replacement: 'Alcatel One Touch $2'
1541
1772
  brand_replacement: 'Alcatel'
1542
1773
  model_replacement: 'One Touch $2'
1543
- - regex: '; *(?:alcatel[ _])?(?:(?:one[ _]?touch[ _])|ot[ \-])([^;/]+);? Build'
1774
+ - regex: '; *(?:alcatel[ _]|)(?:(?:one[ _]?touch[ _])|ot[ \-])([^;/]+?)(?: Build|\) AppleWebKit)'
1544
1775
  regex_flag: 'i'
1545
1776
  device_replacement: 'Alcatel One Touch $1'
1546
1777
  brand_replacement: 'Alcatel'
1547
1778
  model_replacement: 'One Touch $1'
1548
- - regex: '; *(TCL)[ _]([^;/]+) Build'
1779
+ - regex: '; *(TCL)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
1549
1780
  device_replacement: '$1 $2'
1550
1781
  brand_replacement: '$1'
1551
1782
  model_replacement: '$2'
1552
1783
  # operator specific models
1553
- - regex: '; *(Vodafone Smart II|Optimus_Madrid) Build'
1784
+ - regex: '; *(Vodafone Smart II|Optimus_Madrid)(?: Build|\) AppleWebKit)'
1554
1785
  device_replacement: 'Alcatel $1'
1555
1786
  brand_replacement: 'Alcatel'
1556
1787
  model_replacement: '$1'
1557
- - regex: '; *BASE_Lutea_3 Build'
1788
+ - regex: '; *BASE_Lutea_3(?: Build|\) AppleWebKit)'
1558
1789
  device_replacement: 'Alcatel One Touch 998'
1559
1790
  brand_replacement: 'Alcatel'
1560
1791
  model_replacement: 'One Touch 998'
1561
- - regex: '; *BASE_Varia Build'
1792
+ - regex: '; *BASE_Varia(?: Build|\) AppleWebKit)'
1562
1793
  device_replacement: 'Alcatel One Touch 918D'
1563
1794
  brand_replacement: 'Alcatel'
1564
1795
  model_replacement: 'One Touch 918D'
@@ -1567,7 +1798,7 @@ device_parsers:
1567
1798
  # Allfine
1568
1799
  # @ref: http://www.myallfine.com/Products.asp
1569
1800
  #########
1570
- - regex: '; *((?:FINE|Fine)\d[^;/]+) Build'
1801
+ - regex: '; *((?:FINE|Fine)\d[^;/]+?)(?: Build|\) AppleWebKit)'
1571
1802
  device_replacement: '$1'
1572
1803
  brand_replacement: 'Allfine'
1573
1804
  model_replacement: '$1'
@@ -1576,15 +1807,15 @@ device_parsers:
1576
1807
  # Allview
1577
1808
  # @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/
1578
1809
  #########
1579
- - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).*) Build/'
1810
+ - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).*?)(?: Build|\) AppleWebKit)'
1580
1811
  device_replacement: '$1$2'
1581
1812
  brand_replacement: 'Allview'
1582
1813
  model_replacement: '$2'
1583
- - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)?(AX1_Shine|AX2_Frenzy) Build'
1814
+ - regex: '; *(ALLVIEW[ _]?|Allview[ _]?|)(AX1_Shine|AX2_Frenzy)(?: Build|\) AppleWebKit)'
1584
1815
  device_replacement: '$1$2'
1585
1816
  brand_replacement: 'Allview'
1586
1817
  model_replacement: '$2'
1587
- - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)([^;/]*) Build'
1818
+ - regex: '; *(ALLVIEW[ _]?|Allview[ _]?)([^;/]*?)(?: Build|\) AppleWebKit)'
1588
1819
  device_replacement: '$1$2'
1589
1820
  brand_replacement: 'Allview'
1590
1821
  model_replacement: '$2'
@@ -1594,11 +1825,11 @@ device_parsers:
1594
1825
  # @ref: http://www.allwinner.com/
1595
1826
  # @models: A31 (13.3"),A20,A10,
1596
1827
  #########
1597
- - regex: '; *(A13-MID) Build'
1828
+ - regex: '; *(A13-MID)(?: Build|\) AppleWebKit)'
1598
1829
  device_replacement: '$1'
1599
1830
  brand_replacement: 'Allwinner'
1600
1831
  model_replacement: '$1'
1601
- - regex: '; *(Allwinner)[ _\-]?([^;/]+) Build'
1832
+ - regex: '; *(Allwinner)[ _\-]?([^;/]+?)(?: Build|\) AppleWebKit)'
1602
1833
  device_replacement: '$1 $2'
1603
1834
  brand_replacement: 'Allwinner'
1604
1835
  model_replacement: '$1'
@@ -1607,7 +1838,7 @@ device_parsers:
1607
1838
  # Amaway
1608
1839
  # @ref: http://www.amaway.cn/
1609
1840
  #########
1610
- - regex: '; *(A651|A701B?|A702|A703|A705|A706|A707|A711|A712|A713|A717|A722|A785|A801|A802|A803|A901|A902|A1002|A1003|A1006|A1007|A9701|A9703|Q710|Q80) Build'
1841
+ - regex: '; *(A651|A701B?|A702|A703|A705|A706|A707|A711|A712|A713|A717|A722|A785|A801|A802|A803|A901|A902|A1002|A1003|A1006|A1007|A9701|A9703|Q710|Q80)(?: Build|\) AppleWebKit)'
1611
1842
  device_replacement: '$1'
1612
1843
  brand_replacement: 'Amaway'
1613
1844
  model_replacement: '$1'
@@ -1616,11 +1847,11 @@ device_parsers:
1616
1847
  # Amoi
1617
1848
  # @ref: http://www.amoi.com/en/prd/prd_index.jspx
1618
1849
  #########
1619
- - regex: '; *(?:AMOI|Amoi)[ _]([^;/]+) Build'
1850
+ - regex: '; *(?:AMOI|Amoi)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
1620
1851
  device_replacement: 'Amoi $1'
1621
1852
  brand_replacement: 'Amoi'
1622
1853
  model_replacement: '$1'
1623
- - regex: '^(?:AMOI|Amoi)[ _]([^;/]+) Linux'
1854
+ - regex: '^(?:AMOI|Amoi)[ _]([^;/]+?) Linux'
1624
1855
  device_replacement: 'Amoi $1'
1625
1856
  brand_replacement: 'Amoi'
1626
1857
  model_replacement: '$1'
@@ -1629,7 +1860,7 @@ device_parsers:
1629
1860
  # Aoc
1630
1861
  # @ref: http://latin.aoc.com/media_tablet
1631
1862
  #########
1632
- - regex: '; *(MW(?:0[789]|10)[^;/]+) Build'
1863
+ - regex: '; *(MW(?:0[789]|10)[^;/]+?)(?: Build|\) AppleWebKit)'
1633
1864
  device_replacement: '$1'
1634
1865
  brand_replacement: 'Aoc'
1635
1866
  model_replacement: '$1'
@@ -1640,11 +1871,11 @@ device_parsers:
1640
1871
  # @ref: http://www.luckystar.com.cn/en/mobiletel.aspx?page=1
1641
1872
  # @note: brand owned by luckystar
1642
1873
  #########
1643
- - regex: '; *(G7|M1013|M1015G|M11[CG]?|M-?12[B]?|M15|M19[G]?|M30[ACQ]?|M31[GQ]|M32|M33[GQ]|M36|M37|M38|M701T|M710|M712B|M713|M715G|M716G|M71(?:G|GS|T)?|M72[T]?|M73[T]?|M75[GT]?|M77G|M79T|M7L|M7LN|M81|M810|M81T|M82|M92|M92KS|M92S|M717G|M721|M722G|M723|M725G|M739|M785|M791|M92SK|M93D) Build'
1874
+ - regex: '; *(G7|M1013|M1015G|M11[CG]?|M-?12[B]?|M15|M19[G]?|M30[ACQ]?|M31[GQ]|M32|M33[GQ]|M36|M37|M38|M701T|M710|M712B|M713|M715G|M716G|M71(?:G|GS|T|)|M72[T]?|M73[T]?|M75[GT]?|M77G|M79T|M7L|M7LN|M81|M810|M81T|M82|M92|M92KS|M92S|M717G|M721|M722G|M723|M725G|M739|M785|M791|M92SK|M93D)(?: Build|\) AppleWebKit)'
1644
1875
  device_replacement: 'Aoson $1'
1645
1876
  brand_replacement: 'Aoson'
1646
1877
  model_replacement: '$1'
1647
- - regex: '; *Aoson ([^;/]+) Build'
1878
+ - regex: '; *Aoson ([^;/]+?)(?: Build|\) AppleWebKit)'
1648
1879
  regex_flag: 'i'
1649
1880
  device_replacement: 'Aoson $1'
1650
1881
  brand_replacement: 'Aoson'
@@ -1654,7 +1885,7 @@ device_parsers:
1654
1885
  # Apanda
1655
1886
  # @ref: http://www.apanda.com.cn/
1656
1887
  #########
1657
- - regex: '; *[Aa]panda[ _\-]([^;/]+) Build'
1888
+ - regex: '; *[Aa]panda[ _\-]([^;/]+?)(?: Build|\) AppleWebKit)'
1658
1889
  device_replacement: 'Apanda $1'
1659
1890
  brand_replacement: 'Apanda'
1660
1891
  model_replacement: '$1'
@@ -1664,7 +1895,7 @@ device_parsers:
1664
1895
  # @ref: http://www.archos.com/de/products/tablets.html
1665
1896
  # @ref: http://www.archos.com/de/products/smartphones/index.html
1666
1897
  #########
1667
- - regex: '; *(?:ARCHOS|Archos) ?(GAMEPAD.*?)(?: Build|[;/\(\)\-])'
1898
+ - regex: '; *(?:ARCHOS|Archos) ?(GAMEPAD.*?)(?: Build|\) AppleWebKit)'
1668
1899
  device_replacement: 'Archos $1'
1669
1900
  brand_replacement: 'Archos'
1670
1901
  model_replacement: '$1'
@@ -1676,11 +1907,11 @@ device_parsers:
1676
1907
  device_replacement: 'Archos $1'
1677
1908
  brand_replacement: 'Archos'
1678
1909
  model_replacement: '$1'
1679
- - regex: '; *(AN(?:7|8|9|10|13)[A-Z0-9]{1,4}) Build'
1910
+ - regex: '; *(AN(?:7|8|9|10|13)[A-Z0-9]{1,4})(?: Build|\) AppleWebKit)'
1680
1911
  device_replacement: 'Archos $1'
1681
1912
  brand_replacement: 'Archos'
1682
1913
  model_replacement: '$1'
1683
- - regex: '; *(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9) Build'
1914
+ - regex: '; *(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9)(?: Build|\) AppleWebKit)'
1684
1915
  device_replacement: 'Archos $1'
1685
1916
  brand_replacement: 'Archos'
1686
1917
  model_replacement: '$1'
@@ -1689,11 +1920,11 @@ device_parsers:
1689
1920
  # A-rival
1690
1921
  # @ref: http://www.a-rival.de/de/
1691
1922
  #########
1692
- - regex: '; *(PAD-FMD[^;/]+) Build'
1923
+ - regex: '; *(PAD-FMD[^;/]+?)(?: Build|\) AppleWebKit)'
1693
1924
  device_replacement: '$1'
1694
1925
  brand_replacement: 'Arival'
1695
1926
  model_replacement: '$1'
1696
- - regex: '; *(BioniQ) ?([^;/]+) Build'
1927
+ - regex: '; *(BioniQ) ?([^;/]+?)(?: Build|\) AppleWebKit)'
1697
1928
  device_replacement: '$1 $2'
1698
1929
  brand_replacement: 'Arival'
1699
1930
  model_replacement: '$1 $2'
@@ -1702,11 +1933,11 @@ device_parsers:
1702
1933
  # Arnova
1703
1934
  # @ref: http://arnovatech.com/
1704
1935
  #########
1705
- - regex: '; *(AN\d[^;/]+|ARCHM\d+) Build'
1936
+ - regex: '; *(AN\d[^;/]+|ARCHM\d+)(?: Build|\) AppleWebKit)'
1706
1937
  device_replacement: 'Arnova $1'
1707
1938
  brand_replacement: 'Arnova'
1708
1939
  model_replacement: '$1'
1709
- - regex: '; *(?:ARNOVA|Arnova) ?([^;/]+) Build'
1940
+ - regex: '; *(?:ARNOVA|Arnova) ?([^;/]+?)(?: Build|\) AppleWebKit)'
1710
1941
  device_replacement: 'Arnova $1'
1711
1942
  brand_replacement: 'Arnova'
1712
1943
  model_replacement: '$1'
@@ -1715,7 +1946,7 @@ device_parsers:
1715
1946
  # Assistant
1716
1947
  # @ref: http://www.assistant.ua
1717
1948
  #########
1718
- - regex: '; *(?:ASSISTANT )?(AP)-?([1789]\d{2}[A-Z]{0,2}|80104) Build'
1949
+ - regex: '; *(?:ASSISTANT |)(AP)-?([1789]\d{2}[A-Z]{0,2}|80104)(?: Build|\) AppleWebKit)'
1719
1950
  device_replacement: 'Assistant $1-$2'
1720
1951
  brand_replacement: 'Assistant'
1721
1952
  model_replacement: '$1-$2'
@@ -1724,11 +1955,11 @@ device_parsers:
1724
1955
  # Asus
1725
1956
  # @ref: http://www.asus.com/uk/Tablets_Mobile/
1726
1957
  #########
1727
- - regex: '; *(ME17\d[^;/]*|ME3\d{2}[^;/]+|K00[A-Z]|Nexus 10|Nexus 7(?: 2013)?|PadFone[^;/]*|Transformer[^;/]*|TF\d{3}[^;/]*|eeepc) Build'
1958
+ - regex: '; *(ME17\d[^;/]*|ME3\d{2}[^;/]+|K00[A-Z]|Nexus 10|Nexus 7(?: 2013|)|PadFone[^;/]*|Transformer[^;/]*|TF\d{3}[^;/]*|eeepc)(?: Build|\) AppleWebKit)'
1728
1959
  device_replacement: 'Asus $1'
1729
1960
  brand_replacement: 'Asus'
1730
1961
  model_replacement: '$1'
1731
- - regex: '; *ASUS[ _]*([^;/]+) Build'
1962
+ - regex: '; *ASUS[ _]*([^;/]+?)(?: Build|\) AppleWebKit)'
1732
1963
  device_replacement: 'Asus $1'
1733
1964
  brand_replacement: 'Asus'
1734
1965
  model_replacement: '$1'
@@ -1736,11 +1967,11 @@ device_parsers:
1736
1967
  #########
1737
1968
  # Garmin-Asus
1738
1969
  #########
1739
- - regex: '; *Garmin-Asus ([^;/]+) Build'
1970
+ - regex: '; *Garmin-Asus ([^;/]+?)(?: Build|\) AppleWebKit)'
1740
1971
  device_replacement: 'Garmin-Asus $1'
1741
1972
  brand_replacement: 'Garmin-Asus'
1742
1973
  model_replacement: '$1'
1743
- - regex: '; *(Garminfone) Build'
1974
+ - regex: '; *(Garminfone)(?: Build|\) AppleWebKit)'
1744
1975
  device_replacement: 'Garmin $1'
1745
1976
  brand_replacement: 'Garmin-Asus'
1746
1977
  model_replacement: '$1'
@@ -1749,7 +1980,7 @@ device_parsers:
1749
1980
  # Attab
1750
1981
  # @ref: http://www.theattab.com/
1751
1982
  #########
1752
- - regex: '; (@TAB-[^;/]+) Build'
1983
+ - regex: '; (@TAB-[^;/]+?)(?: Build|\) AppleWebKit)'
1753
1984
  device_replacement: '$1'
1754
1985
  brand_replacement: 'Attab'
1755
1986
  model_replacement: '$1'
@@ -1759,7 +1990,7 @@ device_parsers:
1759
1990
  # @ref: ??
1760
1991
  # @note: Take care with Docomo T-01 Toshiba
1761
1992
  #########
1762
- - regex: '; *(T-(?:07|[^0]\d)[^;/]+) Build'
1993
+ - regex: '; *(T-(?:07|[^0]\d)[^;/]+?)(?: Build|\) AppleWebKit)'
1763
1994
  device_replacement: '$1'
1764
1995
  brand_replacement: 'Audiosonic'
1765
1996
  model_replacement: '$1'
@@ -1768,7 +1999,7 @@ device_parsers:
1768
1999
  # Axioo
1769
2000
  # @ref: http://www.axiooworld.com/ww/index.php
1770
2001
  #########
1771
- - regex: '; *(?:Axioo[ _\-]([^;/]+)|(picopad)[ _\-]([^;/]+)) Build'
2002
+ - regex: '; *(?:Axioo[ _\-]([^;/]+?)|(picopad)[ _\-]([^;/]+?))(?: Build|\) AppleWebKit)'
1772
2003
  regex_flag: 'i'
1773
2004
  device_replacement: 'Axioo $1$2 $3'
1774
2005
  brand_replacement: 'Axioo'
@@ -1778,7 +2009,7 @@ device_parsers:
1778
2009
  # Azend
1779
2010
  # @ref: http://azendcorp.com/index.php/products/portable-electronics
1780
2011
  #########
1781
- - regex: '; *(V(?:100|700|800)[^;/]*) Build'
2012
+ - regex: '; *(V(?:100|700|800)[^;/]*)(?: Build|\) AppleWebKit)'
1782
2013
  device_replacement: '$1'
1783
2014
  brand_replacement: 'Azend'
1784
2015
  model_replacement: '$1'
@@ -1787,7 +2018,7 @@ device_parsers:
1787
2018
  # Bak
1788
2019
  # @ref: http://www.bakinternational.com/produtos.php?cat=80
1789
2020
  #########
1790
- - regex: '; *(IBAK\-[^;/]*) Build'
2021
+ - regex: '; *(IBAK\-[^;/]*)(?: Build|\) AppleWebKit)'
1791
2022
  regex_flag: 'i'
1792
2023
  device_replacement: '$1'
1793
2024
  brand_replacement: 'Bak'
@@ -1798,7 +2029,7 @@ device_parsers:
1798
2029
  # @ref: http://www.bedove.com/product.html
1799
2030
  # @models: HY6501|HY5001|X12|X21|I5
1800
2031
  #########
1801
- - regex: '; *(HY5001|HY6501|X12|X21|I5) Build'
2032
+ - regex: '; *(HY5001|HY6501|X12|X21|I5)(?: Build|\) AppleWebKit)'
1802
2033
  device_replacement: 'Bedove $1'
1803
2034
  brand_replacement: 'Bedove'
1804
2035
  model_replacement: '$1'
@@ -1807,7 +2038,7 @@ device_parsers:
1807
2038
  # Benss
1808
2039
  # @ref: http://www.benss.net/
1809
2040
  #########
1810
- - regex: '; *(JC-[^;/]*) Build'
2041
+ - regex: '; *(JC-[^;/]*)(?: Build|\) AppleWebKit)'
1811
2042
  device_replacement: 'Benss $1'
1812
2043
  brand_replacement: 'Benss'
1813
2044
  model_replacement: '$1'
@@ -1817,7 +2048,7 @@ device_parsers:
1817
2048
  # @ref: http://uk.blackberry.com/
1818
2049
  # @note: Android Apps seams to be used here
1819
2050
  #########
1820
- - regex: '; *(BB) ([^;/]+) Build'
2051
+ - regex: '; *(BB) ([^;/]+?)(?: Build|\) AppleWebKit)'
1821
2052
  device_replacement: '$1 $2'
1822
2053
  brand_replacement: 'Blackberry'
1823
2054
  model_replacement: '$2'
@@ -1826,11 +2057,11 @@ device_parsers:
1826
2057
  # Blackbird
1827
2058
  # @ref: http://iblackbird.co.kr
1828
2059
  #########
1829
- - regex: '; *(BlackBird)[ _](I8.*) Build'
2060
+ - regex: '; *(BlackBird)[ _](I8.*?)(?: Build|\) AppleWebKit)'
1830
2061
  device_replacement: '$1 $2'
1831
2062
  brand_replacement: '$1'
1832
2063
  model_replacement: '$2'
1833
- - regex: '; *(BlackBird)[ _](.*) Build'
2064
+ - regex: '; *(BlackBird)[ _](.*?)(?: Build|\) AppleWebKit)'
1834
2065
  device_replacement: '$1 $2'
1835
2066
  brand_replacement: '$1'
1836
2067
  model_replacement: '$2'
@@ -1840,7 +2071,7 @@ device_parsers:
1840
2071
  # @ref: http://www.blaupunkt.com
1841
2072
  #########
1842
2073
  # Endeavour
1843
- - regex: '; *([0-9]+BP[EM][^;/]*|Endeavour[^;/]+) Build'
2074
+ - regex: '; *([0-9]+BP[EM][^;/]*|Endeavour[^;/]+?)(?: Build|\) AppleWebKit)'
1844
2075
  device_replacement: 'Blaupunkt $1'
1845
2076
  brand_replacement: 'Blaupunkt'
1846
2077
  model_replacement: '$1'
@@ -1849,12 +2080,12 @@ device_parsers:
1849
2080
  # Blu
1850
2081
  # @ref: http://bluproducts.com
1851
2082
  #########
1852
- - regex: '; *((?:BLU|Blu)[ _\-])([^;/]+) Build'
2083
+ - regex: '; *((?:BLU|Blu)[ _\-])([^;/]+?)(?: Build|\) AppleWebKit)'
1853
2084
  device_replacement: '$1$2'
1854
2085
  brand_replacement: 'Blu'
1855
2086
  model_replacement: '$2'
1856
2087
  # BMOBILE = operator branded device
1857
- - regex: '; *(?:BMOBILE )?(Blu|BLU|DASH [^;/]+|VIVO 4\.3|TANK 4\.5) Build'
2088
+ - regex: '; *(?:BMOBILE )?(Blu|BLU|DASH [^;/]+|VIVO 4\.3|TANK 4\.5)(?: Build|\) AppleWebKit)'
1858
2089
  device_replacement: '$1'
1859
2090
  brand_replacement: 'Blu'
1860
2091
  model_replacement: '$1'
@@ -1864,7 +2095,7 @@ device_parsers:
1864
2095
  # @ref: http://www.blusens.com/es/?sg=1&sv=al&roc=1
1865
2096
  #########
1866
2097
  # tablet
1867
- - regex: '; *(TOUCH\d[^;/]+) Build'
2098
+ - regex: '; *(TOUCH\d[^;/]+?)(?: Build|\) AppleWebKit)'
1868
2099
  device_replacement: '$1'
1869
2100
  brand_replacement: 'Blusens'
1870
2101
  model_replacement: '$1'
@@ -1875,7 +2106,7 @@ device_parsers:
1875
2106
  # @note: Might collide with Maxx as AX is used also there.
1876
2107
  #########
1877
2108
  # smartphone
1878
- - regex: '; *(AX5\d+) Build'
2109
+ - regex: '; *(AX5\d+)(?: Build|\) AppleWebKit)'
1879
2110
  device_replacement: '$1'
1880
2111
  brand_replacement: 'Bmobile'
1881
2112
  model_replacement: '$1'
@@ -1884,11 +2115,11 @@ device_parsers:
1884
2115
  # bq
1885
2116
  # @ref: http://bqreaders.com
1886
2117
  #########
1887
- - regex: '; *([Bb]q) ([^;/]+);? Build'
2118
+ - regex: '; *([Bb]q) ([^;/]+?);?(?: Build|\) AppleWebKit)'
1888
2119
  device_replacement: '$1 $2'
1889
2120
  brand_replacement: 'bq'
1890
2121
  model_replacement: '$2'
1891
- - regex: '; *(Maxwell [^;/]+) Build'
2122
+ - regex: '; *(Maxwell [^;/]+?)(?: Build|\) AppleWebKit)'
1892
2123
  device_replacement: '$1'
1893
2124
  brand_replacement: 'bq'
1894
2125
  model_replacement: '$1'
@@ -1897,7 +2128,7 @@ device_parsers:
1897
2128
  # Braun Phototechnik
1898
2129
  # @ref: http://www.braun-phototechnik.de/en/products/list/~pcat.250/Tablet-PC.html
1899
2130
  #########
1900
- - regex: '; *((?:B-Tab|B-TAB) ?\d[^;/]+) Build'
2131
+ - regex: '; *((?:B-Tab|B-TAB) ?\d[^;/]+?)(?: Build|\) AppleWebKit)'
1901
2132
  device_replacement: '$1'
1902
2133
  brand_replacement: 'Braun'
1903
2134
  model_replacement: '$1'
@@ -1906,7 +2137,7 @@ device_parsers:
1906
2137
  # Broncho
1907
2138
  # @ref: http://www.broncho.cn/
1908
2139
  #########
1909
- - regex: '; *(Broncho) ([^;/]+) Build'
2140
+ - regex: '; *(Broncho) ([^;/]+?)(?: Build|\) AppleWebKit)'
1910
2141
  device_replacement: '$1 $2'
1911
2142
  brand_replacement: '$1'
1912
2143
  model_replacement: '$2'
@@ -1915,7 +2146,7 @@ device_parsers:
1915
2146
  # Captiva
1916
2147
  # @ref: http://www.captiva-power.de
1917
2148
  #########
1918
- - regex: '; *CAPTIVA ([^;/]+) Build'
2149
+ - regex: '; *CAPTIVA ([^;/]+?)(?: Build|\) AppleWebKit)'
1919
2150
  device_replacement: 'Captiva $1'
1920
2151
  brand_replacement: 'Captiva'
1921
2152
  model_replacement: '$1'
@@ -1924,7 +2155,7 @@ device_parsers:
1924
2155
  # Casio
1925
2156
  # @ref: http://www.casiogzone.com/
1926
2157
  #########
1927
- - regex: '; *(C771|CAL21|IS11CA) Build'
2158
+ - regex: '; *(C771|CAL21|IS11CA)(?: Build|\) AppleWebKit)'
1928
2159
  device_replacement: '$1'
1929
2160
  brand_replacement: 'Casio'
1930
2161
  model_replacement: '$1'
@@ -1933,15 +2164,15 @@ device_parsers:
1933
2164
  # Cat
1934
2165
  # @ref: http://www.cat-sound.com
1935
2166
  #########
1936
- - regex: '; *(?:Cat|CAT) ([^;/]+) Build'
2167
+ - regex: '; *(?:Cat|CAT) ([^;/]+?)(?: Build|\) AppleWebKit)'
1937
2168
  device_replacement: 'Cat $1'
1938
2169
  brand_replacement: 'Cat'
1939
2170
  model_replacement: '$1'
1940
- - regex: '; *(?:Cat)(Nova.*) Build'
2171
+ - regex: '; *(?:Cat)(Nova.*?)(?: Build|\) AppleWebKit)'
1941
2172
  device_replacement: 'Cat $1'
1942
2173
  brand_replacement: 'Cat'
1943
2174
  model_replacement: '$1'
1944
- - regex: '; *(INM8002KP|ADM8000KP_[AB]) Build'
2175
+ - regex: '; *(INM8002KP|ADM8000KP_[AB])(?: Build|\) AppleWebKit)'
1945
2176
  device_replacement: '$1'
1946
2177
  brand_replacement: 'Cat'
1947
2178
  model_replacement: 'Tablet PHOENIX 8.1J0'
@@ -1959,7 +2190,7 @@ device_parsers:
1959
2190
  device_replacement: '$1'
1960
2191
  brand_replacement: 'Celkon'
1961
2192
  model_replacement: '$1'
1962
- - regex: '; *(CT)-?(\d+) Build'
2193
+ - regex: '; *(CT)-?(\d+)(?: Build|\) AppleWebKit)'
1963
2194
  device_replacement: '$1$2'
1964
2195
  brand_replacement: 'Celkon'
1965
2196
  model_replacement: '$1$2'
@@ -1975,7 +2206,7 @@ device_parsers:
1975
2206
  # @brief: China manufacturer makes tablets for different small brands
1976
2207
  # (eg. http://www.zeepad.net/index.html)
1977
2208
  #########
1978
- - regex: '; *(TPC[0-9]{4,5}) Build'
2209
+ - regex: '; *(TPC[0-9]{4,5})(?: Build|\) AppleWebKit)'
1979
2210
  device_replacement: '$1'
1980
2211
  brand_replacement: 'ChangJia'
1981
2212
  model_replacement: '$1'
@@ -1984,15 +2215,15 @@ device_parsers:
1984
2215
  # Cloudfone
1985
2216
  # @ref: http://www.cloudfonemobile.com/
1986
2217
  #########
1987
- - regex: '; *(Cloudfone)[ _](Excite)([^ ][^;/]+) Build'
2218
+ - regex: '; *(Cloudfone)[ _](Excite)([^ ][^;/]+?)(?: Build|\) AppleWebKit)'
1988
2219
  device_replacement: '$1 $2 $3'
1989
2220
  brand_replacement: 'Cloudfone'
1990
2221
  model_replacement: '$1 $2 $3'
1991
- - regex: '; *(Excite|ICE)[ _](\d+[^;/]+) Build'
2222
+ - regex: '; *(Excite|ICE)[ _](\d+[^;/]+?)(?: Build|\) AppleWebKit)'
1992
2223
  device_replacement: 'Cloudfone $1 $2'
1993
2224
  brand_replacement: 'Cloudfone'
1994
2225
  model_replacement: 'Cloudfone $1 $2'
1995
- - regex: '; *(Cloudfone|CloudPad)[ _]([^;/]+) Build'
2226
+ - regex: '; *(Cloudfone|CloudPad)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
1996
2227
  device_replacement: '$1 $2'
1997
2228
  brand_replacement: 'Cloudfone'
1998
2229
  model_replacement: '$1 $2'
@@ -2001,7 +2232,7 @@ device_parsers:
2001
2232
  # Cmx
2002
2233
  # @ref: http://cmx.at/de/
2003
2234
  #########
2004
- - regex: '; *((?:Aquila|Clanga|Rapax)[^;/]+) Build'
2235
+ - regex: '; *((?:Aquila|Clanga|Rapax)[^;/]+?)(?: Build|\) AppleWebKit)'
2005
2236
  regex_flag: 'i'
2006
2237
  device_replacement: '$1'
2007
2238
  brand_replacement: 'Cmx'
@@ -2021,7 +2252,7 @@ device_parsers:
2021
2252
  # Coolpad
2022
2253
  # @ref: ??
2023
2254
  #########
2024
- - regex: '; *([^;/]*)Coolpad[ _]([^;/]+) Build'
2255
+ - regex: '; *([^;/]*)Coolpad[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2025
2256
  device_replacement: '$1$2'
2026
2257
  brand_replacement: 'Coolpad'
2027
2258
  model_replacement: '$1$2'
@@ -2030,7 +2261,7 @@ device_parsers:
2030
2261
  # Cube
2031
2262
  # @ref: http://www.cube-tablet.com/buy-products.html
2032
2263
  #########
2033
- - regex: '; *(CUBE[ _])?([KU][0-9]+ ?GT.*|A5300) Build'
2264
+ - regex: '; *(CUBE[ _])?([KU][0-9]+ ?GT.*?|A5300)(?: Build|\) AppleWebKit)'
2034
2265
  regex_flag: 'i'
2035
2266
  device_replacement: '$1$2'
2036
2267
  brand_replacement: 'Cube'
@@ -2040,12 +2271,12 @@ device_parsers:
2040
2271
  # Cubot
2041
2272
  # @ref: http://www.cubotmall.com/
2042
2273
  #########
2043
- - regex: '; *CUBOT ([^;/]+) Build'
2274
+ - regex: '; *CUBOT ([^;/]+?)(?: Build|\) AppleWebKit)'
2044
2275
  regex_flag: 'i'
2045
2276
  device_replacement: '$1'
2046
2277
  brand_replacement: 'Cubot'
2047
2278
  model_replacement: '$1'
2048
- - regex: '; *(BOBBY) Build'
2279
+ - regex: '; *(BOBBY)(?: Build|\) AppleWebKit)'
2049
2280
  regex_flag: 'i'
2050
2281
  device_replacement: '$1'
2051
2282
  brand_replacement: 'Cubot'
@@ -2055,7 +2286,7 @@ device_parsers:
2055
2286
  # Danew
2056
2287
  # @ref: http://www.danew.com/produits-tablette.php
2057
2288
  #########
2058
- - regex: '; *(Dslide [^;/]+) Build'
2289
+ - regex: '; *(Dslide [^;/]+?)(?: Build|\) AppleWebKit)'
2059
2290
  device_replacement: '$1'
2060
2291
  brand_replacement: 'Danew'
2061
2292
  model_replacement: '$1'
@@ -2069,39 +2300,39 @@ device_parsers:
2069
2300
  # @ref: http://www.dell.com/in/p/mobile-xcd28/pd
2070
2301
  # @ref: http://www.dell.com/in/p/mobile-xcd35/pd
2071
2302
  #########
2072
- - regex: '; *(XCD)[ _]?(28|35) Build'
2303
+ - regex: '; *(XCD)[ _]?(28|35)(?: Build|\) AppleWebKit)'
2073
2304
  device_replacement: 'Dell $1$2'
2074
2305
  brand_replacement: 'Dell'
2075
2306
  model_replacement: '$1$2'
2076
- - regex: '; *(001DL) Build'
2307
+ - regex: '; *(001DL)(?: Build|\) AppleWebKit)'
2077
2308
  device_replacement: 'Dell $1'
2078
2309
  brand_replacement: 'Dell'
2079
2310
  model_replacement: 'Streak'
2080
- - regex: '; *(?:Dell|DELL) (Streak) Build'
2311
+ - regex: '; *(?:Dell|DELL) (Streak)(?: Build|\) AppleWebKit)'
2081
2312
  device_replacement: 'Dell $1'
2082
2313
  brand_replacement: 'Dell'
2083
2314
  model_replacement: 'Streak'
2084
- - regex: '; *(101DL|GS01|Streak Pro[^;/]*) Build'
2315
+ - regex: '; *(101DL|GS01|Streak Pro[^;/]*)(?: Build|\) AppleWebKit)'
2085
2316
  device_replacement: 'Dell $1'
2086
2317
  brand_replacement: 'Dell'
2087
2318
  model_replacement: 'Streak Pro'
2088
- - regex: '; *([Ss]treak ?7) Build'
2319
+ - regex: '; *([Ss]treak ?7)(?: Build|\) AppleWebKit)'
2089
2320
  device_replacement: 'Dell $1'
2090
2321
  brand_replacement: 'Dell'
2091
2322
  model_replacement: 'Streak 7'
2092
- - regex: '; *(Mini-3iX) Build'
2323
+ - regex: '; *(Mini-3iX)(?: Build|\) AppleWebKit)'
2093
2324
  device_replacement: 'Dell $1'
2094
2325
  brand_replacement: 'Dell'
2095
2326
  model_replacement: '$1'
2096
- - regex: '; *(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.*|Streak[ _]Pro) Build'
2327
+ - regex: '; *(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.*?|Streak[ _]Pro)(?: Build|\) AppleWebKit)'
2097
2328
  device_replacement: 'Dell $1'
2098
2329
  brand_replacement: 'Dell'
2099
2330
  model_replacement: '$1'
2100
- - regex: '; *Dell[ _]([^;/]+) Build'
2331
+ - regex: '; *Dell[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2101
2332
  device_replacement: 'Dell $1'
2102
2333
  brand_replacement: 'Dell'
2103
2334
  model_replacement: '$1'
2104
- - regex: '; *Dell ([^;/]+) Build'
2335
+ - regex: '; *Dell ([^;/]+?)(?: Build|\) AppleWebKit)'
2105
2336
  device_replacement: 'Dell $1'
2106
2337
  brand_replacement: 'Dell'
2107
2338
  model_replacement: '$1'
@@ -2110,7 +2341,7 @@ device_parsers:
2110
2341
  # Denver
2111
2342
  # @ref: http://www.denver-electronics.com/tablets1/
2112
2343
  #########
2113
- - regex: '; *(TA[CD]-\d+[^;/]*) Build'
2344
+ - regex: '; *(TA[CD]-\d+[^;/]*)(?: Build|\) AppleWebKit)'
2114
2345
  device_replacement: '$1'
2115
2346
  brand_replacement: 'Denver'
2116
2347
  model_replacement: '$1'
@@ -2119,7 +2350,7 @@ device_parsers:
2119
2350
  # Dex
2120
2351
  # @ref: http://dex.ua/
2121
2352
  #########
2122
- - regex: '; *(iP[789]\d{2}(?:-3G)?|IP10\d{2}(?:-8GB)?) Build'
2353
+ - regex: '; *(iP[789]\d{2}(?:-3G)?|IP10\d{2}(?:-8GB)?)(?: Build|\) AppleWebKit)'
2123
2354
  device_replacement: '$1'
2124
2355
  brand_replacement: 'Dex'
2125
2356
  model_replacement: '$1'
@@ -2128,7 +2359,7 @@ device_parsers:
2128
2359
  # DNS AirTab
2129
2360
  # @ref: http://www.dns-shop.ru/
2130
2361
  #########
2131
- - regex: '; *(AirTab)[ _\-]([^;/]+) Build'
2362
+ - regex: '; *(AirTab)[ _\-]([^;/]+?)(?: Build|\) AppleWebKit)'
2132
2363
  device_replacement: '$1 $2'
2133
2364
  brand_replacement: 'DNS'
2134
2365
  model_replacement: '$1 $2'
@@ -2137,43 +2368,43 @@ device_parsers:
2137
2368
  # Docomo (Operator Branded Device)
2138
2369
  # @ref: http://www.ipentec.com/document/document.aspx?page=android-useragent
2139
2370
  #########
2140
- - regex: '; *(F\-\d[^;/]+) Build'
2371
+ - regex: '; *(F\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2141
2372
  device_replacement: '$1'
2142
2373
  brand_replacement: 'Fujitsu'
2143
2374
  model_replacement: '$1'
2144
- - regex: '; *(HT-03A) Build'
2375
+ - regex: '; *(HT-03A)(?: Build|\) AppleWebKit)'
2145
2376
  device_replacement: '$1'
2146
2377
  brand_replacement: 'HTC'
2147
2378
  model_replacement: 'Magic'
2148
- - regex: '; *(HT\-\d[^;/]+) Build'
2379
+ - regex: '; *(HT\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2149
2380
  device_replacement: '$1'
2150
2381
  brand_replacement: 'HTC'
2151
2382
  model_replacement: '$1'
2152
- - regex: '; *(L\-\d[^;/]+) Build'
2383
+ - regex: '; *(L\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2153
2384
  device_replacement: '$1'
2154
2385
  brand_replacement: 'LG'
2155
2386
  model_replacement: '$1'
2156
- - regex: '; *(N\-\d[^;/]+) Build'
2387
+ - regex: '; *(N\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2157
2388
  device_replacement: '$1'
2158
2389
  brand_replacement: 'Nec'
2159
2390
  model_replacement: '$1'
2160
- - regex: '; *(P\-\d[^;/]+) Build'
2391
+ - regex: '; *(P\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2161
2392
  device_replacement: '$1'
2162
2393
  brand_replacement: 'Panasonic'
2163
2394
  model_replacement: '$1'
2164
- - regex: '; *(SC\-\d[^;/]+) Build'
2395
+ - regex: '; *(SC\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2165
2396
  device_replacement: '$1'
2166
2397
  brand_replacement: 'Samsung'
2167
2398
  model_replacement: '$1'
2168
- - regex: '; *(SH\-\d[^;/]+) Build'
2399
+ - regex: '; *(SH\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2169
2400
  device_replacement: '$1'
2170
2401
  brand_replacement: 'Sharp'
2171
2402
  model_replacement: '$1'
2172
- - regex: '; *(SO\-\d[^;/]+) Build'
2403
+ - regex: '; *(SO\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2173
2404
  device_replacement: '$1'
2174
2405
  brand_replacement: 'SonyEricsson'
2175
2406
  model_replacement: '$1'
2176
- - regex: '; *(T\-0[12][^;/]+) Build'
2407
+ - regex: '; *(T\-0[12][^;/]+?)(?: Build|\) AppleWebKit)'
2177
2408
  device_replacement: '$1'
2178
2409
  brand_replacement: 'Toshiba'
2179
2410
  model_replacement: '$1'
@@ -2182,7 +2413,7 @@ device_parsers:
2182
2413
  # DOOV
2183
2414
  # @ref: http://www.doov.com.cn/
2184
2415
  #########
2185
- - regex: '; *(DOOV)[ _]([^;/]+) Build'
2416
+ - regex: '; *(DOOV)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2186
2417
  device_replacement: '$1 $2'
2187
2418
  brand_replacement: 'DOOV'
2188
2419
  model_replacement: '$2'
@@ -2191,7 +2422,7 @@ device_parsers:
2191
2422
  # Enot
2192
2423
  # @ref: http://www.enot.ua/
2193
2424
  #########
2194
- - regex: '; *(Enot|ENOT)[ -]?([^;/]+) Build'
2425
+ - regex: '; *(Enot|ENOT)[ -]?([^;/]+?)(?: Build|\) AppleWebKit)'
2195
2426
  device_replacement: '$1 $2'
2196
2427
  brand_replacement: 'Enot'
2197
2428
  model_replacement: '$2'
@@ -2204,7 +2435,7 @@ device_parsers:
2204
2435
  device_replacement: 'CROSS $1'
2205
2436
  brand_replacement: 'Evercoss'
2206
2437
  model_replacement: 'Cross $1'
2207
- - regex: '; *(CROSS|Cross)[ _\-]([^;/]+) Build'
2438
+ - regex: '; *(CROSS|Cross)[ _\-]([^;/]+?)(?: Build|\) AppleWebKit)'
2208
2439
  device_replacement: '$1 $2'
2209
2440
  brand_replacement: 'Evercoss'
2210
2441
  model_replacement: 'Cross $2'
@@ -2222,11 +2453,11 @@ device_parsers:
2222
2453
  # Fly
2223
2454
  # @ref: http://www.fly-phone.com/
2224
2455
  #########
2225
- - regex: '; *(IQ.*) Build'
2456
+ - regex: '; *(IQ.*?)(?: Build|\) AppleWebKit)'
2226
2457
  device_replacement: '$1'
2227
2458
  brand_replacement: 'Fly'
2228
2459
  model_replacement: '$1'
2229
- - regex: '; *(Fly|FLY)[ _](IQ[^;]+|F[34]\d+[^;]*);? Build'
2460
+ - regex: '; *(Fly|FLY)[ _](IQ[^;]+?|F[34]\d+[^;]*?);?(?: Build|\) AppleWebKit)'
2230
2461
  device_replacement: '$1 $2'
2231
2462
  brand_replacement: 'Fly'
2232
2463
  model_replacement: '$2'
@@ -2235,7 +2466,7 @@ device_parsers:
2235
2466
  # Fujitsu
2236
2467
  # @ref: http://www.fujitsu.com/global/
2237
2468
  #########
2238
- - regex: '; *(M532|Q572|FJL21) Build/'
2469
+ - regex: '; *(M532|Q572|FJL21)(?: Build|\) AppleWebKit)'
2239
2470
  device_replacement: '$1'
2240
2471
  brand_replacement: 'Fujitsu'
2241
2472
  model_replacement: '$1'
@@ -2244,7 +2475,7 @@ device_parsers:
2244
2475
  # Galapad
2245
2476
  # @ref: http://www.galapad.net/product.html
2246
2477
  #########
2247
- - regex: '; *(G1) Build'
2478
+ - regex: '; *(G1)(?: Build|\) AppleWebKit)'
2248
2479
  device_replacement: '$1'
2249
2480
  brand_replacement: 'Galapad'
2250
2481
  model_replacement: '$1'
@@ -2253,7 +2484,7 @@ device_parsers:
2253
2484
  # Geeksphone
2254
2485
  # @ref: http://www.geeksphone.com/
2255
2486
  #########
2256
- - regex: '; *(Geeksphone) ([^;/]+) Build'
2487
+ - regex: '; *(Geeksphone) ([^;/]+?)(?: Build|\) AppleWebKit)'
2257
2488
  device_replacement: '$1 $2'
2258
2489
  brand_replacement: '$1'
2259
2490
  model_replacement: '$2'
@@ -2263,7 +2494,7 @@ device_parsers:
2263
2494
  # @ref: http://www.gfivemobile.com/en
2264
2495
  #########
2265
2496
  #- regex: '; *(G\'?FIVE) ([^;/]+) Build' # there is a problem with python yaml parser here
2266
- - regex: '; *(G[^F]?FIVE) ([^;/]+) Build'
2497
+ - regex: '; *(G[^F]?FIVE) ([^;/]+?)(?: Build|\) AppleWebKit)'
2267
2498
  device_replacement: '$1 $2'
2268
2499
  brand_replacement: 'Gfive'
2269
2500
  model_replacement: '$2'
@@ -2272,12 +2503,12 @@ device_parsers:
2272
2503
  # Gionee
2273
2504
  # @ref: http://www.gionee.com/
2274
2505
  #########
2275
- - regex: '; *(Gionee)[ _\-]([^;/]+)(?:/[^;/]+)? Build'
2506
+ - regex: '; *(Gionee)[ _\-]([^;/]+?)(?:/[^;/]+|)(?: Build|\) AppleWebKit)'
2276
2507
  regex_flag: 'i'
2277
2508
  device_replacement: '$1 $2'
2278
2509
  brand_replacement: 'Gionee'
2279
2510
  model_replacement: '$2'
2280
- - regex: '; *(GN\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1) Build'
2511
+ - regex: '; *(GN\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1)(?: Build|\) AppleWebKit)'
2281
2512
  device_replacement: 'Gionee $1'
2282
2513
  brand_replacement: 'Gionee'
2283
2514
  model_replacement: '$1'
@@ -2295,11 +2526,11 @@ device_parsers:
2295
2526
  # GoClever
2296
2527
  # @ref: http://www.goclever.com
2297
2528
  #########
2298
- - regex: '; *((?:FONE|QUANTUM|INSIGNIA) \d+[^;/]*|PLAYTAB) Build'
2529
+ - regex: '; *((?:FONE|QUANTUM|INSIGNIA) \d+[^;/]*|PLAYTAB)(?: Build|\) AppleWebKit)'
2299
2530
  device_replacement: 'GoClever $1'
2300
2531
  brand_replacement: 'GoClever'
2301
2532
  model_replacement: '$1'
2302
- - regex: '; *GOCLEVER ([^;/]+) Build'
2533
+ - regex: '; *GOCLEVER ([^;/]+?)(?: Build|\) AppleWebKit)'
2303
2534
  device_replacement: 'GoClever $1'
2304
2535
  brand_replacement: 'GoClever'
2305
2536
  model_replacement: '$1'
@@ -2308,11 +2539,11 @@ device_parsers:
2308
2539
  # Google
2309
2540
  # @ref: http://www.google.de/glass/start/
2310
2541
  #########
2311
- - regex: '; *(Glass \d+) Build'
2542
+ - regex: '; *(Glass \d+)(?: Build|\) AppleWebKit)'
2312
2543
  device_replacement: '$1'
2313
2544
  brand_replacement: 'Google'
2314
2545
  model_replacement: '$1'
2315
- - regex: '; *(Pixel.*) Build'
2546
+ - regex: '; *(Pixel.*?)(?: Build|\) AppleWebKit)'
2316
2547
  device_replacement: '$1'
2317
2548
  brand_replacement: 'Google'
2318
2549
  model_replacement: '$1'
@@ -2321,7 +2552,7 @@ device_parsers:
2321
2552
  # Gigabyte
2322
2553
  # @ref: http://gsmart.gigabytecm.com/en/
2323
2554
  #########
2324
- - regex: '; *(GSmart)[ -]([^/]+) Build'
2555
+ - regex: '; *(GSmart)[ -]([^/]+)(?: Build|\) AppleWebKit)'
2325
2556
  device_replacement: '$1 $2'
2326
2557
  brand_replacement: 'Gigabyte'
2327
2558
  model_replacement: '$1 $2'
@@ -2330,7 +2561,7 @@ device_parsers:
2330
2561
  # Freescale development boards
2331
2562
  # @ref: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX53QSB
2332
2563
  #########
2333
- - regex: '; *(imx5[13]_[^/]+) Build'
2564
+ - regex: '; *(imx5[13]_[^/]+)(?: Build|\) AppleWebKit)'
2334
2565
  device_replacement: 'Freescale $1'
2335
2566
  brand_replacement: 'Freescale'
2336
2567
  model_replacement: '$1'
@@ -2340,11 +2571,11 @@ device_parsers:
2340
2571
  # @ref: http://www.haier.com/
2341
2572
  # @ref: http://www.haier.com/de/produkte/tablet/
2342
2573
  #########
2343
- - regex: '; *Haier[ _\-]([^/]+) Build'
2574
+ - regex: '; *Haier[ _\-]([^/]+)(?: Build|\) AppleWebKit)'
2344
2575
  device_replacement: 'Haier $1'
2345
2576
  brand_replacement: 'Haier'
2346
2577
  model_replacement: '$1'
2347
- - regex: '; *(PAD1016) Build'
2578
+ - regex: '; *(PAD1016)(?: Build|\) AppleWebKit)'
2348
2579
  device_replacement: 'Haipad $1'
2349
2580
  brand_replacement: 'Haipad'
2350
2581
  model_replacement: '$1'
@@ -2354,7 +2585,7 @@ device_parsers:
2354
2585
  # @ref: http://www.haipad.net/
2355
2586
  # @models: V7P|M7SM7S|M9XM9X|M7XM7X|M9|M8|M7-M|M1002|M7|M701
2356
2587
  #########
2357
- - regex: '; *(M701|M7|M8|M9) Build'
2588
+ - regex: '; *(M701|M7|M8|M9)(?: Build|\) AppleWebKit)'
2358
2589
  device_replacement: 'Haipad $1'
2359
2590
  brand_replacement: 'Haipad'
2360
2591
  model_replacement: '$1'
@@ -2386,7 +2617,7 @@ device_parsers:
2386
2617
  # Hena
2387
2618
  # @ref: http://www.henadigital.com/en/product/index.asp?id=6
2388
2619
  #########
2389
- - regex: '; *(MID-?\d{4}C[EM]) Build'
2620
+ - regex: '; *(MID-?\d{4}C[EM])(?: Build|\) AppleWebKit)'
2390
2621
  device_replacement: 'Hena $1'
2391
2622
  brand_replacement: 'Hena'
2392
2623
  model_replacement: '$1'
@@ -2395,11 +2626,11 @@ device_parsers:
2395
2626
  # Hisense
2396
2627
  # @ref: http://www.hisense.com/
2397
2628
  #########
2398
- - regex: '; *(EG\d{2,}|HS-[^;/]+|MIRA[^;/]+) Build'
2629
+ - regex: '; *(EG\d{2,}|HS-[^;/]+|MIRA[^;/]+?)(?: Build|\) AppleWebKit)'
2399
2630
  device_replacement: 'Hisense $1'
2400
2631
  brand_replacement: 'Hisense'
2401
2632
  model_replacement: '$1'
2402
- - regex: '; *(andromax[^;/]+) Build'
2633
+ - regex: '; *(andromax[^;/]+?)(?: Build|\) AppleWebKit)'
2403
2634
  regex_flag: 'i'
2404
2635
  device_replacement: 'Hisense $1'
2405
2636
  brand_replacement: 'Hisense'
@@ -2409,7 +2640,7 @@ device_parsers:
2409
2640
  # hitech
2410
2641
  # @ref: http://www.hitech-mobiles.com/
2411
2642
  #########
2412
- - regex: '; *(?:AMAZE[ _](S\d+)|(S\d+)[ _]AMAZE) Build'
2643
+ - regex: '; *(?:AMAZE[ _](S\d+)|(S\d+)[ _]AMAZE)(?: Build|\) AppleWebKit)'
2413
2644
  device_replacement: 'AMAZE $1$2'
2414
2645
  brand_replacement: 'hitech'
2415
2646
  model_replacement: 'AMAZE $1$2'
@@ -2418,15 +2649,15 @@ device_parsers:
2418
2649
  # HP
2419
2650
  # @ref: http://www.hp.com/
2420
2651
  #########
2421
- - regex: '; *(PlayBook) Build'
2652
+ - regex: '; *(PlayBook)(?: Build|\) AppleWebKit)'
2422
2653
  device_replacement: 'HP $1'
2423
2654
  brand_replacement: 'HP'
2424
2655
  model_replacement: '$1'
2425
- - regex: '; *HP ([^/]+) Build'
2656
+ - regex: '; *HP ([^/]+)(?: Build|\) AppleWebKit)'
2426
2657
  device_replacement: 'HP $1'
2427
2658
  brand_replacement: 'HP'
2428
2659
  model_replacement: '$1'
2429
- - regex: '; *([^/]+_tenderloin) Build'
2660
+ - regex: '; *([^/]+_tenderloin)(?: Build|\) AppleWebKit)'
2430
2661
  device_replacement: 'HP TouchPad'
2431
2662
  brand_replacement: 'HP'
2432
2663
  model_replacement: 'TouchPad'
@@ -2436,11 +2667,11 @@ device_parsers:
2436
2667
  # @ref: http://www.huaweidevice.com
2437
2668
  # @note: Needs to be before HTC due to Desire HD Build on U8815
2438
2669
  #########
2439
- - regex: '; *(HUAWEI |Huawei-)?([UY][^;/]+) Build/(?:Huawei|HUAWEI)([UY][^\);]+)\)'
2670
+ - regex: '; *(HUAWEI |Huawei-|)([UY][^;/]+) Build/(?:Huawei|HUAWEI)([UY][^\);]+)\)'
2440
2671
  device_replacement: '$1$2'
2441
2672
  brand_replacement: 'Huawei'
2442
2673
  model_replacement: '$2'
2443
- - regex: '; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)[^\);]*\)'
2674
+ - regex: '; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)\)'
2444
2675
  device_replacement: '$1'
2445
2676
  brand_replacement: 'Huawei'
2446
2677
  model_replacement: '$2'
@@ -2452,7 +2683,7 @@ device_parsers:
2452
2683
  device_replacement: '$1$2'
2453
2684
  brand_replacement: 'Huawei'
2454
2685
  model_replacement: '$2'
2455
- - regex: '; *((?:HUAWEI[ _]?|Huawei[ _])?Ascend[ _])([^;/]+) Build'
2686
+ - regex: '; *((?:HUAWEI[ _]?|Huawei[ _]|)Ascend[ _])([^;/]+) Build'
2456
2687
  device_replacement: '$1$2'
2457
2688
  brand_replacement: 'Huawei'
2458
2689
  model_replacement: '$2'
@@ -2488,6 +2719,10 @@ device_parsers:
2488
2719
  device_replacement: 'Huawei $1'
2489
2720
  brand_replacement: 'Huawei'
2490
2721
  model_replacement: '$1'
2722
+ - regex: '; *((?:[A-Z]{3})\-L[A-Za0-9]{2})[\)]'
2723
+ device_replacement: 'Huawei $1'
2724
+ brand_replacement: 'Huawei'
2725
+ model_replacement: '$1'
2491
2726
 
2492
2727
  #########
2493
2728
  # HTC
@@ -2507,33 +2742,33 @@ device_parsers:
2507
2742
  device_replacement: 'HTC $1'
2508
2743
  brand_replacement: 'HTC'
2509
2744
  model_replacement: '$1'
2510
- - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+))?(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))'
2745
+ - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)|)(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))'
2511
2746
  device_replacement: 'HTC $1 $2'
2512
2747
  brand_replacement: 'HTC'
2513
2748
  model_replacement: '$1 $2'
2514
- - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+))?)?(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))'
2749
+ - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))'
2515
2750
  device_replacement: 'HTC $1 $2 $3'
2516
2751
  brand_replacement: 'HTC'
2517
2752
  model_replacement: '$1 $2 $3'
2518
- - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+))?)?)?(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))'
2753
+ - regex: '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)|)(?:[/\\]1\.0 | V|/| +)\d+\.\d[\d\.]*(?: *Build|\))'
2519
2754
  device_replacement: 'HTC $1 $2 $3 $4'
2520
2755
  brand_replacement: 'HTC'
2521
2756
  model_replacement: '$1 $2 $3 $4'
2522
2757
 
2523
2758
  # Android HTC without Version Number matcher
2524
- - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/;]+)(?: *Build|[;\)]| - )'
2759
+ - regex: '; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/;]+)(?: *Build|[;\)]| - )'
2525
2760
  device_replacement: 'HTC $1'
2526
2761
  brand_replacement: 'HTC'
2527
2762
  model_replacement: '$1'
2528
- - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/;\)]+))?(?: *Build|[;\)]| - )'
2763
+ - regex: '; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/;\)]+)|)(?: *Build|[;\)]| - )'
2529
2764
  device_replacement: 'HTC $1 $2'
2530
2765
  brand_replacement: 'HTC'
2531
2766
  model_replacement: '$1 $2'
2532
- - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\)]+))?)?(?: *Build|[;\)]| - )'
2767
+ - regex: '; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\)]+)|)|)(?: *Build|[;\)]| - )'
2533
2768
  device_replacement: 'HTC $1 $2 $3'
2534
2769
  brand_replacement: 'HTC'
2535
2770
  model_replacement: '$1 $2 $3'
2536
- - regex: '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+))?)?)?(?: *Build|[;\)]| - )'
2771
+ - regex: '; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+)|)|)|)(?: *Build|[;\)]| - )'
2537
2772
  device_replacement: 'HTC $1 $2 $3 $4'
2538
2773
  brand_replacement: 'HTC'
2539
2774
  model_replacement: '$1 $2 $3 $4'
@@ -2544,7 +2779,7 @@ device_parsers:
2544
2779
  brand_replacement: 'HTC'
2545
2780
  model_replacement: '$1'
2546
2781
  # general matcher for anything else
2547
- - regex: '(?:[;,] *|^)(?:htccn_chs-)?HTC[ _-]?([^;]+?)(?: *Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\(\)]|$)'
2782
+ - regex: '(?:[;,] *|^)(?:htccn_chs-|)HTC[ _-]?([^;]+?)(?: *Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\(\)]|$)'
2548
2783
  regex_flag: 'i'
2549
2784
  device_replacement: 'HTC $1'
2550
2785
  brand_replacement: 'HTC'
@@ -2565,16 +2800,16 @@ device_parsers:
2565
2800
  # Hyundai
2566
2801
  # @ref: http://www.hyundaitechnologies.com
2567
2802
  #########
2568
- - regex: '; *HYUNDAI (T\d[^/]*) Build'
2803
+ - regex: '; *HYUNDAI (T\d[^/]*)(?: Build|\) AppleWebKit)'
2569
2804
  device_replacement: 'Hyundai $1'
2570
2805
  brand_replacement: 'Hyundai'
2571
2806
  model_replacement: '$1'
2572
- - regex: '; *HYUNDAI ([^;/]+) Build'
2807
+ - regex: '; *HYUNDAI ([^;/]+?)(?: Build|\) AppleWebKit)'
2573
2808
  device_replacement: 'Hyundai $1'
2574
2809
  brand_replacement: 'Hyundai'
2575
2810
  model_replacement: '$1'
2576
2811
  # X900? http://www.amazon.com/Hyundai-X900-Retina-Android-Bluetooth/dp/B00AO07H3O
2577
- - regex: '; *(X700|Hold X|MB-6900) Build'
2812
+ - regex: '; *(X700|Hold X|MB-6900)(?: Build|\) AppleWebKit)'
2578
2813
  device_replacement: 'Hyundai $1'
2579
2814
  brand_replacement: 'Hyundai'
2580
2815
  model_replacement: '$1'
@@ -2583,12 +2818,12 @@ device_parsers:
2583
2818
  # iBall
2584
2819
  # @ref: http://www.iball.co.in/Category/Mobiles/22
2585
2820
  #########
2586
- - regex: '; *(?:iBall[ _\-])?(Andi)[ _]?(\d[^;/]*) Build'
2821
+ - regex: '; *(?:iBall[ _\-]|)(Andi)[ _]?(\d[^;/]*)(?: Build|\) AppleWebKit)'
2587
2822
  regex_flag: 'i'
2588
2823
  device_replacement: '$1 $2'
2589
2824
  brand_replacement: 'iBall'
2590
2825
  model_replacement: '$1 $2'
2591
- - regex: '; *(IBall)(?:[ _]([^;/]+))? Build'
2826
+ - regex: '; *(IBall)(?:[ _]([^;/]+?)|)(?: Build|\) AppleWebKit)'
2592
2827
  regex_flag: 'i'
2593
2828
  device_replacement: '$1 $2'
2594
2829
  brand_replacement: 'iBall'
@@ -2598,7 +2833,7 @@ device_parsers:
2598
2833
  # IconBIT
2599
2834
  # @ref: http://www.iconbit.com/catalog/tablets/
2600
2835
  #########
2601
- - regex: '; *(NT-\d+[^ ;/]*|Net[Tt]AB [^;/]+|Mercury [A-Z]+|iconBIT)(?: S/N:[^;/]+)? Build'
2836
+ - regex: '; *(NT-\d+[^ ;/]*|Net[Tt]AB [^;/]+|Mercury [A-Z]+|iconBIT)(?: S/N:[^;/]+|)(?: Build|\) AppleWebKit)'
2602
2837
  device_replacement: '$1'
2603
2838
  brand_replacement: 'IconBIT'
2604
2839
  model_replacement: '$1'
@@ -2607,7 +2842,7 @@ device_parsers:
2607
2842
  # IMO
2608
2843
  # @ref: http://www.ponselimo.com/
2609
2844
  #########
2610
- - regex: '; *(IMO)[ _]([^;/]+) Build'
2845
+ - regex: '; *(IMO)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2611
2846
  regex_flag: 'i'
2612
2847
  device_replacement: '$1 $2'
2613
2848
  brand_replacement: 'IMO'
@@ -2617,12 +2852,12 @@ device_parsers:
2617
2852
  # i-mobile
2618
2853
  # @ref: http://www.i-mobilephone.com/
2619
2854
  #########
2620
- - regex: '; *i-?mobile[ _]([^/]+) Build/'
2855
+ - regex: '; *i-?mobile[ _]([^/]+)(?: Build|\) AppleWebKit)'
2621
2856
  regex_flag: 'i'
2622
2857
  device_replacement: 'i-mobile $1'
2623
2858
  brand_replacement: 'imobile'
2624
2859
  model_replacement: '$1'
2625
- - regex: '; *(i-(?:style|note)[^/]*) Build/'
2860
+ - regex: '; *(i-(?:style|note)[^/]*)(?: Build|\) AppleWebKit)'
2626
2861
  regex_flag: 'i'
2627
2862
  device_replacement: 'i-mobile $1'
2628
2863
  brand_replacement: 'imobile'
@@ -2632,7 +2867,7 @@ device_parsers:
2632
2867
  # Impression
2633
2868
  # @ref: http://impression.ua/planshetnye-kompyutery
2634
2869
  #########
2635
- - regex: '; *(ImPAD) ?(\d+(?:.)*) Build'
2870
+ - regex: '; *(ImPAD) ?(\d+(?:.)*?)(?: Build|\) AppleWebKit)'
2636
2871
  device_replacement: '$1 $2'
2637
2872
  brand_replacement: 'Impression'
2638
2873
  model_replacement: '$1 $2'
@@ -2641,7 +2876,7 @@ device_parsers:
2641
2876
  # Infinix
2642
2877
  # @ref: http://www.infinixmobility.com/index.html
2643
2878
  #########
2644
- - regex: '; *(Infinix)[ _]([^;/]+) Build'
2879
+ - regex: '; *(Infinix)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2645
2880
  device_replacement: '$1 $2'
2646
2881
  brand_replacement: 'Infinix'
2647
2882
  model_replacement: '$2'
@@ -2650,7 +2885,7 @@ device_parsers:
2650
2885
  # Informer
2651
2886
  # @ref: ??
2652
2887
  #########
2653
- - regex: '; *(Informer)[ \-]([^;/]+) Build'
2888
+ - regex: '; *(Informer)[ \-]([^;/]+?)(?: Build|\) AppleWebKit)'
2654
2889
  device_replacement: '$1 $2'
2655
2890
  brand_replacement: 'Informer'
2656
2891
  model_replacement: '$2'
@@ -2660,7 +2895,7 @@ device_parsers:
2660
2895
  # @ref: http://www.intenso.de
2661
2896
  # @models: 7":TAB 714,TAB 724;8":TAB 814,TAB 824;10":TAB 1004
2662
2897
  #########
2663
- - regex: '; *(TAB) ?([78][12]4) Build'
2898
+ - regex: '; *(TAB) ?([78][12]4)(?: Build|\) AppleWebKit)'
2664
2899
  device_replacement: 'Intenso $1'
2665
2900
  brand_replacement: 'Intenso'
2666
2901
  model_replacement: '$1 $2'
@@ -2671,21 +2906,21 @@ device_parsers:
2671
2906
  # @note: Zync also offers a "Cloud Z5" device
2672
2907
  #########
2673
2908
  # smartphones
2674
- - regex: '; *(?:Intex[ _])?(AQUA|Aqua)([ _\.\-])([^;/]+) *(?:Build|;)'
2909
+ - regex: '; *(?:Intex[ _]|)(AQUA|Aqua)([ _\.\-])([^;/]+?) *(?:Build|;)'
2675
2910
  device_replacement: '$1$2$3'
2676
2911
  brand_replacement: 'Intex'
2677
2912
  model_replacement: '$1 $3'
2678
2913
  # matches "INTEX CLOUD X1"
2679
- - regex: '; *(?:INTEX|Intex)(?:[_ ]([^\ _;/]+))(?:[_ ]([^\ _;/]+))? *(?:Build|;)'
2914
+ - regex: '; *(?:INTEX|Intex)(?:[_ ]([^\ _;/]+))(?:[_ ]([^\ _;/]+)|) *(?:Build|;)'
2680
2915
  device_replacement: '$1 $2'
2681
2916
  brand_replacement: 'Intex'
2682
2917
  model_replacement: '$1 $2'
2683
2918
  # tablets
2684
- - regex: '; *([iI]Buddy)[ _]?(Connect)(?:_|\?_| )?([^;/]*) *(?:Build|;)'
2919
+ - regex: '; *([iI]Buddy)[ _]?(Connect)(?:_|\?_| |)([^;/]*) *(?:Build|;)'
2685
2920
  device_replacement: '$1 $2 $3'
2686
2921
  brand_replacement: 'Intex'
2687
2922
  model_replacement: 'iBuddy $2 $3'
2688
- - regex: '; *(I-Buddy)[ _]([^;/]+) *(?:Build|;)'
2923
+ - regex: '; *(I-Buddy)[ _]([^;/]+?) *(?:Build|;)'
2689
2924
  device_replacement: '$1 $2'
2690
2925
  brand_replacement: 'Intex'
2691
2926
  model_replacement: 'iBuddy $2'
@@ -2694,7 +2929,7 @@ device_parsers:
2694
2929
  # iOCEAN
2695
2930
  # @ref: http://www.iocean.cc/
2696
2931
  #########
2697
- - regex: '; *(iOCEAN) ([^/]+) Build'
2932
+ - regex: '; *(iOCEAN) ([^/]+)(?: Build|\) AppleWebKit)'
2698
2933
  regex_flag: 'i'
2699
2934
  device_replacement: '$1 $2'
2700
2935
  brand_replacement: 'iOCEAN'
@@ -2704,7 +2939,7 @@ device_parsers:
2704
2939
  # i.onik
2705
2940
  # @ref: http://www.i-onik.de/
2706
2941
  #########
2707
- - regex: '; *(TP\d+(?:\.\d+)?\-\d[^;/]+) Build'
2942
+ - regex: '; *(TP\d+(?:\.\d+|)\-\d[^;/]+?)(?: Build|\) AppleWebKit)'
2708
2943
  device_replacement: 'ionik $1'
2709
2944
  brand_replacement: 'ionik'
2710
2945
  model_replacement: '$1'
@@ -2713,21 +2948,30 @@ device_parsers:
2713
2948
  # IRU.ru
2714
2949
  # @ref: http://www.iru.ru/catalog/soho/planetable/
2715
2950
  #########
2716
- - regex: '; *(M702pro) Build'
2951
+ - regex: '; *(M702pro)(?: Build|\) AppleWebKit)'
2717
2952
  device_replacement: '$1'
2718
2953
  brand_replacement: 'Iru'
2719
2954
  model_replacement: '$1'
2720
2955
 
2956
+ #########
2957
+ # Itel Mobile
2958
+ # @ref: https://www.itel-mobile.com/global/products/
2959
+ #########
2960
+ - regex: '; *itel ([^;/]*)(?: Build|\) AppleWebKit)'
2961
+ device_replacement: 'Itel $1'
2962
+ brand_replacement: 'Itel'
2963
+ model_replacement: '$1'
2964
+
2721
2965
  #########
2722
2966
  # Ivio
2723
2967
  # @ref: http://www.ivio.com/mobile.php
2724
2968
  # @models: DG80,DG20,DE38,DE88,MD70
2725
2969
  #########
2726
- - regex: '; *(DE88Plus|MD70) Build'
2970
+ - regex: '; *(DE88Plus|MD70)(?: Build|\) AppleWebKit)'
2727
2971
  device_replacement: '$1'
2728
2972
  brand_replacement: 'Ivio'
2729
2973
  model_replacement: '$1'
2730
- - regex: '; *IVIO[_\-]([^;/]+) Build'
2974
+ - regex: '; *IVIO[_\-]([^;/]+?)(?: Build|\) AppleWebKit)'
2731
2975
  device_replacement: '$1'
2732
2976
  brand_replacement: 'Ivio'
2733
2977
  model_replacement: '$1'
@@ -2736,7 +2980,7 @@ device_parsers:
2736
2980
  # Jaytech
2737
2981
  # @ref: http://www.jay-tech.de/jaytech/servlet/frontend/
2738
2982
  #########
2739
- - regex: '; *(TPC-\d+|JAY-TECH) Build'
2983
+ - regex: '; *(TPC-\d+|JAY-TECH)(?: Build|\) AppleWebKit)'
2740
2984
  device_replacement: '$1'
2741
2985
  brand_replacement: 'Jaytech'
2742
2986
  model_replacement: '$1'
@@ -2745,7 +2989,7 @@ device_parsers:
2745
2989
  # Jiayu
2746
2990
  # @ref: http://www.ejiayu.com/en/Product.html
2747
2991
  #########
2748
- - regex: '; *(JY-[^;/]+|G[234]S?) Build'
2992
+ - regex: '; *(JY-[^;/]+|G[234]S?)(?: Build|\) AppleWebKit)'
2749
2993
  device_replacement: '$1'
2750
2994
  brand_replacement: 'Jiayu'
2751
2995
  model_replacement: '$1'
@@ -2754,7 +2998,7 @@ device_parsers:
2754
2998
  # JXD
2755
2999
  # @ref: http://www.jxd.hk/
2756
3000
  #########
2757
- - regex: '; *(JXD)[ _\-]([^;/]+) Build'
3001
+ - regex: '; *(JXD)[ _\-]([^;/]+?)(?: Build|\) AppleWebKit)'
2758
3002
  device_replacement: '$1 $2'
2759
3003
  brand_replacement: 'JXD'
2760
3004
  model_replacement: '$2'
@@ -2781,84 +3025,84 @@ device_parsers:
2781
3025
  # KDDI (Operator Branded Device)
2782
3026
  # @ref: http://www.ipentec.com/document/document.aspx?page=android-useragent
2783
3027
  #########
2784
- - regex: '; *(IS01|IS03|IS05|IS\d{2}SH) Build'
3028
+ - regex: '; *(IS01|IS03|IS05|IS\d{2}SH)(?: Build|\) AppleWebKit)'
2785
3029
  device_replacement: '$1'
2786
3030
  brand_replacement: 'Sharp'
2787
3031
  model_replacement: '$1'
2788
- - regex: '; *(IS04) Build'
3032
+ - regex: '; *(IS04)(?: Build|\) AppleWebKit)'
2789
3033
  device_replacement: '$1'
2790
3034
  brand_replacement: 'Regza'
2791
3035
  model_replacement: '$1'
2792
- - regex: '; *(IS06|IS\d{2}PT) Build'
3036
+ - regex: '; *(IS06|IS\d{2}PT)(?: Build|\) AppleWebKit)'
2793
3037
  device_replacement: '$1'
2794
3038
  brand_replacement: 'Pantech'
2795
3039
  model_replacement: '$1'
2796
- - regex: '; *(IS11S) Build'
3040
+ - regex: '; *(IS11S)(?: Build|\) AppleWebKit)'
2797
3041
  device_replacement: '$1'
2798
3042
  brand_replacement: 'SonyEricsson'
2799
3043
  model_replacement: 'Xperia Acro'
2800
- - regex: '; *(IS11CA) Build'
3044
+ - regex: '; *(IS11CA)(?: Build|\) AppleWebKit)'
2801
3045
  device_replacement: '$1'
2802
3046
  brand_replacement: 'Casio'
2803
3047
  model_replacement: 'GzOne $1'
2804
- - regex: '; *(IS11LG) Build'
3048
+ - regex: '; *(IS11LG)(?: Build|\) AppleWebKit)'
2805
3049
  device_replacement: '$1'
2806
3050
  brand_replacement: 'LG'
2807
3051
  model_replacement: 'Optimus X'
2808
- - regex: '; *(IS11N) Build'
3052
+ - regex: '; *(IS11N)(?: Build|\) AppleWebKit)'
2809
3053
  device_replacement: '$1'
2810
3054
  brand_replacement: 'Medias'
2811
3055
  model_replacement: '$1'
2812
- - regex: '; *(IS11PT) Build'
3056
+ - regex: '; *(IS11PT)(?: Build|\) AppleWebKit)'
2813
3057
  device_replacement: '$1'
2814
3058
  brand_replacement: 'Pantech'
2815
3059
  model_replacement: 'MIRACH'
2816
- - regex: '; *(IS12F) Build'
3060
+ - regex: '; *(IS12F)(?: Build|\) AppleWebKit)'
2817
3061
  device_replacement: '$1'
2818
3062
  brand_replacement: 'Fujitsu'
2819
3063
  model_replacement: 'Arrows ES'
2820
3064
  # @ref: https://ja.wikipedia.org/wiki/IS12M
2821
- - regex: '; *(IS12M) Build'
3065
+ - regex: '; *(IS12M)(?: Build|\) AppleWebKit)'
2822
3066
  device_replacement: '$1'
2823
3067
  brand_replacement: 'Motorola'
2824
3068
  model_replacement: 'XT909'
2825
- - regex: '; *(IS12S) Build'
3069
+ - regex: '; *(IS12S)(?: Build|\) AppleWebKit)'
2826
3070
  device_replacement: '$1'
2827
3071
  brand_replacement: 'SonyEricsson'
2828
3072
  model_replacement: 'Xperia Acro HD'
2829
- - regex: '; *(ISW11F) Build'
3073
+ - regex: '; *(ISW11F)(?: Build|\) AppleWebKit)'
2830
3074
  device_replacement: '$1'
2831
3075
  brand_replacement: 'Fujitsu'
2832
3076
  model_replacement: 'Arrowz Z'
2833
- - regex: '; *(ISW11HT) Build'
3077
+ - regex: '; *(ISW11HT)(?: Build|\) AppleWebKit)'
2834
3078
  device_replacement: '$1'
2835
3079
  brand_replacement: 'HTC'
2836
3080
  model_replacement: 'EVO'
2837
- - regex: '; *(ISW11K) Build'
3081
+ - regex: '; *(ISW11K)(?: Build|\) AppleWebKit)'
2838
3082
  device_replacement: '$1'
2839
3083
  brand_replacement: 'Kyocera'
2840
3084
  model_replacement: 'DIGNO'
2841
- - regex: '; *(ISW11M) Build'
3085
+ - regex: '; *(ISW11M)(?: Build|\) AppleWebKit)'
2842
3086
  device_replacement: '$1'
2843
3087
  brand_replacement: 'Motorola'
2844
3088
  model_replacement: 'Photon'
2845
- - regex: '; *(ISW11SC) Build'
3089
+ - regex: '; *(ISW11SC)(?: Build|\) AppleWebKit)'
2846
3090
  device_replacement: '$1'
2847
3091
  brand_replacement: 'Samsung'
2848
3092
  model_replacement: 'GALAXY S II WiMAX'
2849
- - regex: '; *(ISW12HT) Build'
3093
+ - regex: '; *(ISW12HT)(?: Build|\) AppleWebKit)'
2850
3094
  device_replacement: '$1'
2851
3095
  brand_replacement: 'HTC'
2852
3096
  model_replacement: 'EVO 3D'
2853
- - regex: '; *(ISW13HT) Build'
3097
+ - regex: '; *(ISW13HT)(?: Build|\) AppleWebKit)'
2854
3098
  device_replacement: '$1'
2855
3099
  brand_replacement: 'HTC'
2856
3100
  model_replacement: 'J'
2857
- - regex: '; *(ISW?[0-9]{2}[A-Z]{0,2}) Build'
3101
+ - regex: '; *(ISW?[0-9]{2}[A-Z]{0,2})(?: Build|\) AppleWebKit)'
2858
3102
  device_replacement: '$1'
2859
3103
  brand_replacement: 'KDDI'
2860
3104
  model_replacement: '$1'
2861
- - regex: '; *(INFOBAR [^;/]+) Build'
3105
+ - regex: '; *(INFOBAR [^;/]+?)(?: Build|\) AppleWebKit)'
2862
3106
  device_replacement: '$1'
2863
3107
  brand_replacement: 'KDDI'
2864
3108
  model_replacement: '$1'
@@ -2867,7 +3111,7 @@ device_parsers:
2867
3111
  # Kingcom
2868
3112
  # @ref: http://www.e-kingcom.com
2869
3113
  #########
2870
- - regex: '; *(JOYPAD|Joypad)[ _]([^;/]+) Build/'
3114
+ - regex: '; *(JOYPAD|Joypad)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2871
3115
  device_replacement: '$1 $2'
2872
3116
  brand_replacement: 'Kingcom'
2873
3117
  model_replacement: '$1 $2'
@@ -2877,7 +3121,7 @@ device_parsers:
2877
3121
  # @ref: https://en.wikipedia.org/wiki/Kobo_Inc.
2878
3122
  # @ref: http://www.kobo.com/devices#tablets
2879
3123
  #########
2880
- - regex: '; *(Vox|VOX|Arc|K080) Build/'
3124
+ - regex: '; *(Vox|VOX|Arc|K080)(?: Build|\) AppleWebKit)'
2881
3125
  regex_flag: 'i'
2882
3126
  device_replacement: '$1'
2883
3127
  brand_replacement: 'Kobo'
@@ -2891,7 +3135,7 @@ device_parsers:
2891
3135
  # K-Touch
2892
3136
  # @ref: ??
2893
3137
  #########
2894
- - regex: '; *(K-Touch)[ _]([^;/]+) Build'
3138
+ - regex: '; *(K-Touch)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
2895
3139
  regex_flag: 'i'
2896
3140
  device_replacement: '$1 $2'
2897
3141
  brand_replacement: 'Ktouch'
@@ -2901,7 +3145,7 @@ device_parsers:
2901
3145
  # KT Tech
2902
3146
  # @ref: http://www.kttech.co.kr
2903
3147
  #########
2904
- - regex: '; *((?:EV|KM)-S\d+[A-Z]?) Build'
3148
+ - regex: '; *((?:EV|KM)-S\d+[A-Z]?)(?: Build|\) AppleWebKit)'
2905
3149
  regex_flag: 'i'
2906
3150
  device_replacement: '$1'
2907
3151
  brand_replacement: 'KTtech'
@@ -2911,7 +3155,7 @@ device_parsers:
2911
3155
  # Kyocera
2912
3156
  # @ref: http://www.android.com/devices/?country=all&m=kyocera
2913
3157
  #########
2914
- - regex: '; *(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\d{2}) Build/'
3158
+ - regex: '; *(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\d{2})(?: Build|\) AppleWebKit)'
2915
3159
  device_replacement: '$1'
2916
3160
  brand_replacement: 'Kyocera'
2917
3161
  model_replacement: '$1'
@@ -2920,7 +3164,7 @@ device_parsers:
2920
3164
  # Lava
2921
3165
  # @ref: http://www.lavamobiles.com/
2922
3166
  #########
2923
- - regex: '; *(?:LAVA[ _])?IRIS[ _\-]?([^/;\)]+) *(?:;|\)|Build)'
3167
+ - regex: '; *(?:LAVA[ _]|)IRIS[ _\-]?([^/;\)]+) *(?:;|\)|Build)'
2924
3168
  regex_flag: 'i'
2925
3169
  device_replacement: 'Iris $1'
2926
3170
  brand_replacement: 'Lava'
@@ -2934,7 +3178,7 @@ device_parsers:
2934
3178
  # Lemon
2935
3179
  # @ref: http://www.lemonmobiles.com/products.php?type=1
2936
3180
  #########
2937
- - regex: '; *(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]+))_? Build'
3181
+ - regex: '; *(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]+))_?(?: Build|\) AppleWebKit)'
2938
3182
  device_replacement: 'Lemon $1$2'
2939
3183
  brand_replacement: 'Lemon'
2940
3184
  model_replacement: '$1$2'
@@ -2943,11 +3187,11 @@ device_parsers:
2943
3187
  # Lenco
2944
3188
  # @ref: http://www.lenco.com/c/tablets/
2945
3189
  #########
2946
- - regex: '; *(TAB-1012) Build/'
3190
+ - regex: '; *(TAB-1012)(?: Build|\) AppleWebKit)'
2947
3191
  device_replacement: 'Lenco $1'
2948
3192
  brand_replacement: 'Lenco'
2949
3193
  model_replacement: '$1'
2950
- - regex: '; Lenco ([^;/]+) Build/'
3194
+ - regex: '; Lenco ([^;/]+?)(?: Build|\) AppleWebKit)'
2951
3195
  device_replacement: 'Lenco $1'
2952
3196
  brand_replacement: 'Lenco'
2953
3197
  model_replacement: '$1'
@@ -2972,15 +3216,15 @@ device_parsers:
2972
3216
  device_replacement: 'Lenovo $1 $2'
2973
3217
  brand_replacement: 'Lenovo'
2974
3218
  model_replacement: '$1 $2'
2975
- - regex: '; *(?:LNV-)?(?:=?[Ll]enovo[ _\-]?|LENOVO[ _])+(.+?)(?:Build|[;/\)])'
3219
+ - regex: '; *(?:LNV-|)(?:=?[Ll]enovo[ _\-]?|LENOVO[ _])(.+?)(?:Build|[;/\)])'
2976
3220
  device_replacement: 'Lenovo $1'
2977
3221
  brand_replacement: 'Lenovo'
2978
3222
  model_replacement: '$1'
2979
- - regex: '[;,] (?:Vodafone )?(SmartTab) ?(II) ?(\d+) Build/'
3223
+ - regex: '[;,] (?:Vodafone |)(SmartTab) ?(II) ?(\d+) Build/'
2980
3224
  device_replacement: 'Lenovo $1 $2 $3'
2981
3225
  brand_replacement: 'Lenovo'
2982
3226
  model_replacement: '$1 $2 $3'
2983
- - regex: '; *(?:Ideapad )?K1 Build/'
3227
+ - regex: '; *(?:Ideapad |)K1 Build/'
2984
3228
  device_replacement: 'Lenovo Ideapad K1'
2985
3229
  brand_replacement: 'Lenovo'
2986
3230
  model_replacement: 'Ideapad K1'
@@ -2997,7 +3241,7 @@ device_parsers:
2997
3241
  # Lexibook
2998
3242
  # @ref: http://www.lexibook.com/fr
2999
3243
  #########
3000
- - regex: '; *(MFC\d+)[A-Z]{2}([^;,/]*),? Build'
3244
+ - regex: '; *(MFC\d+)[A-Z]{2}([^;,/]*),?(?: Build|\) AppleWebKit)'
3001
3245
  device_replacement: '$1$2'
3002
3246
  brand_replacement: 'Lexibook'
3003
3247
  model_replacement: '$1$2'
@@ -3010,7 +3254,7 @@ device_parsers:
3010
3254
  device_replacement: '$1'
3011
3255
  brand_replacement: 'LG'
3012
3256
  model_replacement: '$1'
3013
- - regex: '[;:] *(L-\d+[A-Z]|LGL\d+[A-Z]?)(?:/V\d+)? *(?:Build|[;\)])'
3257
+ - regex: '[;:] *(L-\d+[A-Z]|LGL\d+[A-Z]?)(?:/V\d+|) *(?:Build|[;\)])'
3014
3258
  device_replacement: '$1'
3015
3259
  brand_replacement: 'LG'
3016
3260
  model_replacement: '$1'
@@ -3035,11 +3279,11 @@ device_parsers:
3035
3279
  # Malata
3036
3280
  # @ref: http://www.malata.com/en/products.aspx?classid=680
3037
3281
  #########
3038
- - regex: '; *((?:SMB|smb)[^;/]+) Build/'
3282
+ - regex: '; *((?:SMB|smb)[^;/]+?)(?: Build|\) AppleWebKit)'
3039
3283
  device_replacement: '$1'
3040
3284
  brand_replacement: 'Malata'
3041
3285
  model_replacement: '$1'
3042
- - regex: '; *(?:Malata|MALATA) ([^;/]+) Build/'
3286
+ - regex: '; *(?:Malata|MALATA) ([^;/]+?)(?: Build|\) AppleWebKit)'
3043
3287
  device_replacement: '$1'
3044
3288
  brand_replacement: 'Malata'
3045
3289
  model_replacement: '$1'
@@ -3048,7 +3292,7 @@ device_parsers:
3048
3292
  # Manta
3049
3293
  # @ref: http://www.manta.com.pl/en
3050
3294
  #########
3051
- - regex: '; *(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9]) Build/'
3295
+ - regex: '; *(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9])(?: Build|\) AppleWebKit)'
3052
3296
  device_replacement: '$1'
3053
3297
  brand_replacement: 'Manta'
3054
3298
  model_replacement: '$1'
@@ -3057,7 +3301,7 @@ device_parsers:
3057
3301
  # Match
3058
3302
  # @ref: http://www.match.net.cn/products.asp
3059
3303
  #########
3060
- - regex: '; *(M1052|M806|M9000|M9100|M9701|MID100|MID120|MID125|MID130|MID135|MID140|MID701|MID710|MID713|MID727|MID728|MID731|MID732|MID733|MID735|MID736|MID737|MID760|MID800|MID810|MID820|MID830|MID833|MID835|MID860|MID900|MID930|MID933|MID960|MID980) Build/'
3304
+ - regex: '; *(M1052|M806|M9000|M9100|M9701|MID100|MID120|MID125|MID130|MID135|MID140|MID701|MID710|MID713|MID727|MID728|MID731|MID732|MID733|MID735|MID736|MID737|MID760|MID800|MID810|MID820|MID830|MID833|MID835|MID860|MID900|MID930|MID933|MID960|MID980)(?: Build|\) AppleWebKit)'
3061
3305
  device_replacement: '$1'
3062
3306
  brand_replacement: 'Match'
3063
3307
  model_replacement: '$1'
@@ -3071,7 +3315,7 @@ device_parsers:
3071
3315
  # Maxx MT150, Maxx MQ601, Maxx M2020, Maxx Sleek MX463neo, Maxx MX525, Maxx MX192-Tune, Maxx Genx Droid 7 AX353,
3072
3316
  # @note: Need more User-Agents!!!
3073
3317
  #########
3074
- - regex: '; *(GenxDroid7|MSD7.*|AX\d.*|Tab 701|Tab 722) Build/'
3318
+ - regex: '; *(GenxDroid7|MSD7.*?|AX\d.*?|Tab 701|Tab 722)(?: Build|\) AppleWebKit)'
3075
3319
  device_replacement: 'Maxx $1'
3076
3320
  brand_replacement: 'Maxx'
3077
3321
  model_replacement: '$1'
@@ -3080,11 +3324,11 @@ device_parsers:
3080
3324
  # Mediacom
3081
3325
  # @ref: http://www.mediacomeurope.it/
3082
3326
  #########
3083
- - regex: '; *(M-PP[^;/]+|PhonePad ?\d{2,}[^;/]+) Build'
3327
+ - regex: '; *(M-PP[^;/]+|PhonePad ?\d{2,}[^;/]+?)(?: Build|\) AppleWebKit)'
3084
3328
  device_replacement: 'Mediacom $1'
3085
3329
  brand_replacement: 'Mediacom'
3086
3330
  model_replacement: '$1'
3087
- - regex: '; *(M-MP[^;/]+|SmartPad ?\d{2,}[^;/]+) Build'
3331
+ - regex: '; *(M-MP[^;/]+|SmartPad ?\d{2,}[^;/]+?)(?: Build|\) AppleWebKit)'
3088
3332
  device_replacement: 'Mediacom $1'
3089
3333
  brand_replacement: 'Mediacom'
3090
3334
  model_replacement: '$1'
@@ -3093,12 +3337,12 @@ device_parsers:
3093
3337
  # Medion
3094
3338
  # @ref: http://www.medion.com/en/
3095
3339
  #########
3096
- - regex: '; *(?:MD_)?LIFETAB[ _]([^;/]+) Build'
3340
+ - regex: '; *(?:MD_|)LIFETAB[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
3097
3341
  regex_flag: 'i'
3098
3342
  device_replacement: 'Medion Lifetab $1'
3099
3343
  brand_replacement: 'Medion'
3100
3344
  model_replacement: 'Lifetab $1'
3101
- - regex: '; *MEDION ([^;/]+) Build'
3345
+ - regex: '; *MEDION ([^;/]+?)(?: Build|\) AppleWebKit)'
3102
3346
  device_replacement: 'Medion $1'
3103
3347
  brand_replacement: 'Medion'
3104
3348
  model_replacement: '$1'
@@ -3107,7 +3351,7 @@ device_parsers:
3107
3351
  # Meizu
3108
3352
  # @ref: http://www.meizu.com
3109
3353
  #########
3110
- - regex: '; *(M030|M031|M035|M040|M065|m9) Build'
3354
+ - regex: '; *(M030|M031|M035|M040|M065|m9)(?: Build|\) AppleWebKit)'
3111
3355
  device_replacement: 'Meizu $1'
3112
3356
  brand_replacement: 'Meizu'
3113
3357
  model_replacement: '$1'
@@ -3151,7 +3395,7 @@ device_parsers:
3151
3395
  # Mito
3152
3396
  # @ref: http://new.mitomobile.com/
3153
3397
  #########
3154
- - regex: '; *(MITO)[ _\-]?([^;/]+) Build'
3398
+ - regex: '; *(MITO)[ _\-]?([^;/]+?)(?: Build|\) AppleWebKit)'
3155
3399
  regex_flag: 'i'
3156
3400
  device_replacement: '$1 $2'
3157
3401
  brand_replacement: 'Mito'
@@ -3171,12 +3415,12 @@ device_parsers:
3171
3415
  # Modecom
3172
3416
  # @ref: http://www.modecom.eu/tablets/portal/
3173
3417
  #########
3174
- - regex: '; *(MODECOM )?(FreeTab) ?([^;/]+) Build'
3418
+ - regex: '; *(MODECOM |)(FreeTab) ?([^;/]+?)(?: Build|\) AppleWebKit)'
3175
3419
  regex_flag: 'i'
3176
3420
  device_replacement: '$1$2 $3'
3177
3421
  brand_replacement: 'Modecom'
3178
3422
  model_replacement: '$2 $3'
3179
- - regex: '; *(MODECOM )([^;/]+) Build'
3423
+ - regex: '; *(MODECOM )([^;/]+?)(?: Build|\) AppleWebKit)'
3180
3424
  regex_flag: 'i'
3181
3425
  device_replacement: '$1 $2'
3182
3426
  brand_replacement: 'Modecom'
@@ -3220,7 +3464,7 @@ device_parsers:
3220
3464
  # MpMan
3221
3465
  # @ref: http://www.mpmaneurope.com
3222
3466
  #########
3223
- - regex: '; *((?:MP[DQ]C|MPG\d{1,4}|MP\d{3,4}|MID(?:(?:10[234]|114|43|7[247]|8[24]|7)C|8[01]1))[^;/]*) Build'
3467
+ - regex: '; *((?:MP[DQ]C|MPG\d{1,4}|MP\d{3,4}|MID(?:(?:10[234]|114|43|7[247]|8[24]|7)C|8[01]1))[^;/]*)(?: Build|\) AppleWebKit)'
3224
3468
  device_replacement: '$1'
3225
3469
  brand_replacement: 'Mpman'
3226
3470
  model_replacement: '$1'
@@ -3229,7 +3473,7 @@ device_parsers:
3229
3473
  # MSI
3230
3474
  # @ref: http://www.msi.com/product/windpad/
3231
3475
  #########
3232
- - regex: '; *(?:MSI[ _])?(Primo\d+|Enjoy[ _\-][^;/]+) Build'
3476
+ - regex: '; *(?:MSI[ _]|)(Primo\d+|Enjoy[ _\-][^;/]+?)(?: Build|\) AppleWebKit)'
3233
3477
  regex_flag: 'i'
3234
3478
  device_replacement: '$1'
3235
3479
  brand_replacement: 'Msi'
@@ -3239,7 +3483,7 @@ device_parsers:
3239
3483
  # Multilaser
3240
3484
  # http://www.multilaser.com.br/listagem_produtos.php?cat=5
3241
3485
  #########
3242
- - regex: '; *Multilaser[ _]([^;/]+) Build'
3486
+ - regex: '; *Multilaser[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
3243
3487
  device_replacement: '$1'
3244
3488
  brand_replacement: 'Multilaser'
3245
3489
  model_replacement: '$1'
@@ -3248,15 +3492,15 @@ device_parsers:
3248
3492
  # MyPhone
3249
3493
  # @ref: http://myphone.com.ph/
3250
3494
  #########
3251
- - regex: '; *(My)[_]?(Pad)[ _]([^;/]+) Build'
3495
+ - regex: '; *(My)[_]?(Pad)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
3252
3496
  device_replacement: '$1$2 $3'
3253
3497
  brand_replacement: 'MyPhone'
3254
3498
  model_replacement: '$1$2 $3'
3255
- - regex: '; *(My)\|?(Phone)[ _]([^;/]+) Build'
3499
+ - regex: '; *(My)\|?(Phone)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
3256
3500
  device_replacement: '$1$2 $3'
3257
3501
  brand_replacement: 'MyPhone'
3258
3502
  model_replacement: '$3'
3259
- - regex: '; *(A\d+)[ _](Duo)? Build'
3503
+ - regex: '; *(A\d+)[ _](Duo|)(?: Build|\) AppleWebKit)'
3260
3504
  regex_flag: 'i'
3261
3505
  device_replacement: '$1 $2'
3262
3506
  brand_replacement: 'MyPhone'
@@ -3266,7 +3510,7 @@ device_parsers:
3266
3510
  # Mytab
3267
3511
  # @ref: http://www.mytab.eu/en/category/mytab-products/
3268
3512
  #########
3269
- - regex: '; *(myTab[^;/]*) Build'
3513
+ - regex: '; *(myTab[^;/]*)(?: Build|\) AppleWebKit)'
3270
3514
  device_replacement: '$1'
3271
3515
  brand_replacement: 'Mytab'
3272
3516
  model_replacement: '$1'
@@ -3275,7 +3519,7 @@ device_parsers:
3275
3519
  # Nabi
3276
3520
  # @ref: https://www.nabitablet.com
3277
3521
  #########
3278
- - regex: '; *(NABI2?-)([^;/]+) Build/'
3522
+ - regex: '; *(NABI2?-)([^;/]+?)(?: Build|\) AppleWebKit)'
3279
3523
  device_replacement: '$1$2'
3280
3524
  brand_replacement: 'Nabi'
3281
3525
  model_replacement: '$2'
@@ -3284,15 +3528,15 @@ device_parsers:
3284
3528
  # Nec Medias
3285
3529
  # @ref: http://www.n-keitai.com/
3286
3530
  #########
3287
- - regex: '; *(N-\d+[CDE]) Build/'
3531
+ - regex: '; *(N-\d+[CDE])(?: Build|\) AppleWebKit)'
3288
3532
  device_replacement: '$1'
3289
3533
  brand_replacement: 'Nec'
3290
3534
  model_replacement: '$1'
3291
- - regex: '; ?(NEC-)(.*) Build/'
3535
+ - regex: '; ?(NEC-)(.*?)(?: Build|\) AppleWebKit)'
3292
3536
  device_replacement: '$1$2'
3293
3537
  brand_replacement: 'Nec'
3294
3538
  model_replacement: '$2'
3295
- - regex: '; *(LT-NA7) Build/'
3539
+ - regex: '; *(LT-NA7)(?: Build|\) AppleWebKit)'
3296
3540
  device_replacement: '$1'
3297
3541
  brand_replacement: 'Nec'
3298
3542
  model_replacement: 'Lifetouch Note'
@@ -3301,7 +3545,7 @@ device_parsers:
3301
3545
  # Nextbook
3302
3546
  # @ref: http://nextbookusa.com
3303
3547
  #########
3304
- - regex: '; *(NXM\d+[A-z0-9_]*|Next\d[A-z0-9_ \-]*|NEXT\d[A-z0-9_ \-]*|Nextbook [A-z0-9_ ]*|DATAM803HC|M805)(?: Build|[\);])'
3548
+ - regex: '; *(NXM\d+[A-Za-z0-9_]*|Next\d[A-Za-z0-9_ \-]*|NEXT\d[A-Za-z0-9_ \-]*|Nextbook [A-Za-z0-9_ ]*|DATAM803HC|M805)(?: Build|[\);])'
3305
3549
  device_replacement: '$1'
3306
3550
  brand_replacement: 'Nextbook'
3307
3551
  model_replacement: '$1'
@@ -3315,17 +3559,21 @@ device_parsers:
3315
3559
  device_replacement: '$1$2$3'
3316
3560
  brand_replacement: 'Nokia'
3317
3561
  model_replacement: '$3'
3562
+ - regex: '; *(TA\-\d{4})(?: Build|\) AppleWebKit)'
3563
+ device_replacement: 'Nokia $1'
3564
+ brand_replacement: 'Nokia'
3565
+ model_replacement: '$1'
3318
3566
 
3319
3567
  #########
3320
3568
  # Nook
3321
3569
  # @ref:
3322
3570
  # TODO nook browser/1.0
3323
3571
  #########
3324
- - regex: '; *(Nook ?|Barnes & Noble Nook |BN )([^;/]+) Build'
3572
+ - regex: '; *(Nook ?|Barnes & Noble Nook |BN )([^;/]+?)(?: Build|\) AppleWebKit)'
3325
3573
  device_replacement: '$1$2'
3326
3574
  brand_replacement: 'Nook'
3327
3575
  model_replacement: '$2'
3328
- - regex: '; *(NOOK )?(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2) Build'
3576
+ - regex: '; *(NOOK |)(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2)(?: Build|\) AppleWebKit)'
3329
3577
  device_replacement: '$1$2'
3330
3578
  brand_replacement: 'Nook'
3331
3579
  model_replacement: '$2'
@@ -3338,7 +3586,7 @@ device_parsers:
3338
3586
  # Olivetti
3339
3587
  # @ref: http://www.olivetti.de/EN/Page/t02/view_html?idp=348
3340
3588
  #########
3341
- - regex: '; *(OP110|OliPad[^;/]+) Build'
3589
+ - regex: '; *(OP110|OliPad[^;/]+?)(?: Build|\) AppleWebKit)'
3342
3590
  device_replacement: 'Olivetti $1'
3343
3591
  brand_replacement: 'Olivetti'
3344
3592
  model_replacement: '$1'
@@ -3349,7 +3597,7 @@ device_parsers:
3349
3597
  # @note: MID tablets might get matched by CobyKyros first
3350
3598
  # @models: (T107|MID(?:700[2-5]|7031|7108|7132|750[02]|8001|8500|9001|971[12])
3351
3599
  #########
3352
- - regex: '; *OMEGA[ _\-](MID[^;/]+) Build'
3600
+ - regex: '; *OMEGA[ _\-](MID[^;/]+?)(?: Build|\) AppleWebKit)'
3353
3601
  device_replacement: 'Omega $1'
3354
3602
  brand_replacement: 'Omega'
3355
3603
  model_replacement: '$1'
@@ -3362,7 +3610,7 @@ device_parsers:
3362
3610
  # OpenPeak
3363
3611
  # @ref: https://support.google.com/googleplay/answer/1727131?hl=en
3364
3612
  #########
3365
- - regex: '; *((?:CIUS|cius)[^;/]*) Build'
3613
+ - regex: '; *((?:CIUS|cius)[^;/]*)(?: Build|\) AppleWebKit)'
3366
3614
  device_replacement: 'Openpeak $1'
3367
3615
  brand_replacement: 'Openpeak'
3368
3616
  model_replacement: '$1'
@@ -3371,33 +3619,40 @@ device_parsers:
3371
3619
  # Oppo
3372
3620
  # @ref: http://en.oppo.com/products/
3373
3621
  #########
3374
- - regex: '; *(Find ?(?:5|7a)|R8[012]\d{1,2}|T703\d{0,1}|U70\d{1,2}T?|X90\d{1,2}) Build'
3622
+ - regex: '; *(Find ?(?:5|7a)|R8[012]\d{1,2}|T703\d?|U70\d{1,2}T?|X90\d{1,2}|[AFR]\d{1,2}[a-z]{1,2})(?: Build|\) AppleWebKit)'
3623
+ device_replacement: 'Oppo $1'
3624
+ brand_replacement: 'Oppo'
3625
+ model_replacement: '$1'
3626
+ - regex: '; *OPPO ?([^;/]+?)(?: Build|\) AppleWebKit)'
3375
3627
  device_replacement: 'Oppo $1'
3376
3628
  brand_replacement: 'Oppo'
3377
3629
  model_replacement: '$1'
3378
- - regex: '; *OPPO ?([^;/]+) Build/'
3630
+ - regex: '; *(CPH\d{1,4}|RMX\d{1,4}|P[A-Z]{3}\d{2})(?: Build|\) AppleWebKit)'
3379
3631
  device_replacement: 'Oppo $1'
3380
3632
  brand_replacement: 'Oppo'
3633
+ - regex: '; *(A1601)(?: Build|\) AppleWebKit)'
3634
+ device_replacement: 'Oppo F1s'
3635
+ brand_replacement: 'Oppo'
3381
3636
  model_replacement: '$1'
3382
3637
 
3383
3638
  #########
3384
3639
  # Odys
3385
3640
  # @ref: http://odys.de
3386
3641
  #########
3387
- - regex: '; *(?:Odys\-|ODYS\-|ODYS )([^;/]+) Build'
3642
+ - regex: '; *(?:Odys\-|ODYS\-|ODYS )([^;/]+?)(?: Build|\) AppleWebKit)'
3388
3643
  device_replacement: 'Odys $1'
3389
3644
  brand_replacement: 'Odys'
3390
3645
  model_replacement: '$1'
3391
- - regex: '; *(SELECT) ?(7) Build'
3646
+ - regex: '; *(SELECT) ?(7)(?: Build|\) AppleWebKit)'
3392
3647
  device_replacement: 'Odys $1 $2'
3393
3648
  brand_replacement: 'Odys'
3394
3649
  model_replacement: '$1 $2'
3395
- - regex: '; *(PEDI)_(PLUS)_(W) Build'
3650
+ - regex: '; *(PEDI)_(PLUS)_(W)(?: Build|\) AppleWebKit)'
3396
3651
  device_replacement: 'Odys $1 $2 $3'
3397
3652
  brand_replacement: 'Odys'
3398
3653
  model_replacement: '$1 $2 $3'
3399
3654
  # Weltbild - Tablet PC 4 = Cat Phoenix = Odys Tablet PC 4?
3400
- - regex: '; *(AEON|BRAVIO|FUSION|FUSION2IN1|Genio|EOS10|IEOS[^;/]*|IRON|Loox|LOOX|LOOX Plus|Motion|NOON|NOON_PRO|NEXT|OPOS|PEDI[^;/]*|PRIME[^;/]*|STUDYTAB|TABLO|Tablet-PC-4|UNO_X8|XELIO[^;/]*|Xelio ?\d+ ?[Pp]ro|XENO10|XPRESS PRO) Build'
3655
+ - regex: '; *(AEON|BRAVIO|FUSION|FUSION2IN1|Genio|EOS10|IEOS[^;/]*|IRON|Loox|LOOX|LOOX Plus|Motion|NOON|NOON_PRO|NEXT|OPOS|PEDI[^;/]*|PRIME[^;/]*|STUDYTAB|TABLO|Tablet-PC-4|UNO_X8|XELIO[^;/]*|Xelio ?\d+ ?[Pp]ro|XENO10|XPRESS PRO)(?: Build|\) AppleWebKit)'
3401
3656
  device_replacement: 'Odys $1'
3402
3657
  brand_replacement: 'Odys'
3403
3658
  model_replacement: '$1'
@@ -3406,11 +3661,11 @@ device_parsers:
3406
3661
  # OnePlus
3407
3662
  # @ref https://oneplus.net/
3408
3663
  #########
3409
- - regex: '; (ONE [a-zA-Z]\d+) Build/'
3664
+ - regex: '; (ONE [a-zA-Z]\d+)(?: Build|\) AppleWebKit)'
3410
3665
  device_replacement: 'OnePlus $1'
3411
3666
  brand_replacement: 'OnePlus'
3412
3667
  model_replacement: '$1'
3413
- - regex: '; (ONEPLUS [a-zA-Z]\d+) Build/'
3668
+ - regex: '; (ONEPLUS [a-zA-Z]\d+)(?: Build|\) AppleWebKit)'
3414
3669
  device_replacement: 'OnePlus $1'
3415
3670
  brand_replacement: 'OnePlus'
3416
3671
  model_replacement: '$1'
@@ -3419,7 +3674,7 @@ device_parsers:
3419
3674
  # Orion
3420
3675
  # @ref: http://www.orion.ua/en/products/computer-products/tablet-pcs.html
3421
3676
  #########
3422
- - regex: '; *(TP-\d+) Build/'
3677
+ - regex: '; *(TP-\d+)(?: Build|\) AppleWebKit)'
3423
3678
  device_replacement: 'Orion $1'
3424
3679
  brand_replacement: 'Orion'
3425
3680
  model_replacement: '$1'
@@ -3428,7 +3683,7 @@ device_parsers:
3428
3683
  # PackardBell
3429
3684
  # @ref: http://www.packardbell.com/pb/en/AE/content/productgroup/tablets
3430
3685
  #########
3431
- - regex: '; *(G100W?) Build/'
3686
+ - regex: '; *(G100W?)(?: Build|\) AppleWebKit)'
3432
3687
  device_replacement: 'PackardBell $1'
3433
3688
  brand_replacement: 'PackardBell'
3434
3689
  model_replacement: '$1'
@@ -3439,17 +3694,17 @@ device_parsers:
3439
3694
  # @models: T11, T21, T31, P11, P51, Eluga Power, Eluga DL1
3440
3695
  # @models: (tab) Toughpad FZ-A1, Toughpad JT-B1
3441
3696
  #########
3442
- - regex: '; *(Panasonic)[_ ]([^;/]+) Build'
3697
+ - regex: '; *(Panasonic)[_ ]([^;/]+?)(?: Build|\) AppleWebKit)'
3443
3698
  device_replacement: '$1 $2'
3444
3699
  brand_replacement: '$1'
3445
3700
  model_replacement: '$2'
3446
3701
  # Toughpad
3447
- - regex: '; *(FZ-A1B|JT-B1) Build'
3702
+ - regex: '; *(FZ-A1B|JT-B1)(?: Build|\) AppleWebKit)'
3448
3703
  device_replacement: 'Panasonic $1'
3449
3704
  brand_replacement: 'Panasonic'
3450
3705
  model_replacement: '$1'
3451
3706
  # Eluga Power
3452
- - regex: '; *(dL1|DL1) Build'
3707
+ - regex: '; *(dL1|DL1)(?: Build|\) AppleWebKit)'
3453
3708
  device_replacement: 'Panasonic $1'
3454
3709
  brand_replacement: 'Panasonic'
3455
3710
  model_replacement: '$1'
@@ -3460,11 +3715,11 @@ device_parsers:
3460
3715
  # @href: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA
3461
3716
  # @models: ADR8995, ADR910L, ADR930VW, C790, CDM8992, CDM8999, IS06, IS11PT, P2000, P2020, P2030, P4100, P5000, P6010, P6020, P6030, P7000, P7040, P8000, P8010, P9020, P9050, P9060, P9070, P9090, PT001, PT002, PT003, TXT8040, TXT8045, VEGA PTL21
3462
3717
  #########
3463
- - regex: '; *(SKY[ _])?(IM\-[AT]\d{3}[^;/]+).* Build/'
3718
+ - regex: '; *(SKY[ _]|)(IM\-[AT]\d{3}[^;/]+).* Build/'
3464
3719
  device_replacement: 'Pantech $1$2'
3465
3720
  brand_replacement: 'Pantech'
3466
3721
  model_replacement: '$1$2'
3467
- - regex: '; *((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G)?) Build/'
3722
+ - regex: '; *((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G|)) Build/'
3468
3723
  device_replacement: '$1'
3469
3724
  brand_replacement: 'Pantech'
3470
3725
  model_replacement: '$1'
@@ -3477,7 +3732,7 @@ device_parsers:
3477
3732
  # Papayre
3478
3733
  # @ref: http://grammata.es/
3479
3734
  #########
3480
- - regex: '; *(papyre)[ _\-]([^;/]+) Build/'
3735
+ - regex: '; *(papyre)[ _\-]([^;/]+?)(?: Build|\) AppleWebKit)'
3481
3736
  regex_flag: 'i'
3482
3737
  device_replacement: '$1 $2'
3483
3738
  brand_replacement: 'Papyre'
@@ -3487,7 +3742,7 @@ device_parsers:
3487
3742
  # Pearl
3488
3743
  # @ref: http://www.pearl.de/c-1540.shtml
3489
3744
  #########
3490
- - regex: '; *(?:Touchlet )?(X10\.[^;/]+) Build/'
3745
+ - regex: '; *(?:Touchlet )?(X10\.[^;/]+?)(?: Build|\) AppleWebKit)'
3491
3746
  device_replacement: 'Pearl $1'
3492
3747
  brand_replacement: 'Pearl'
3493
3748
  model_replacement: '$1'
@@ -3496,15 +3751,15 @@ device_parsers:
3496
3751
  # Phicomm
3497
3752
  # @ref: http://www.phicomm.com.cn/
3498
3753
  #########
3499
- - regex: '; PHICOMM (i800) Build/'
3754
+ - regex: '; PHICOMM (i800)(?: Build|\) AppleWebKit)'
3500
3755
  device_replacement: 'Phicomm $1'
3501
3756
  brand_replacement: 'Phicomm'
3502
3757
  model_replacement: '$1'
3503
- - regex: '; PHICOMM ([^;/]+) Build/'
3758
+ - regex: '; PHICOMM ([^;/]+?)(?: Build|\) AppleWebKit)'
3504
3759
  device_replacement: 'Phicomm $1'
3505
3760
  brand_replacement: 'Phicomm'
3506
3761
  model_replacement: '$1'
3507
- - regex: '; *(FWS\d{3}[^;/]+) Build/'
3762
+ - regex: '; *(FWS\d{3}[^;/]+?)(?: Build|\) AppleWebKit)'
3508
3763
  device_replacement: 'Phicomm $1'
3509
3764
  brand_replacement: 'Phicomm'
3510
3765
  model_replacement: '$1'
@@ -3516,11 +3771,11 @@ device_parsers:
3516
3771
  # @ref: http://www.support.philips.com/support/catalog/products.jsp?_dyncharset=UTF-8&country=&categoryid=ENTERTAINMENT_TABLETS_SU_CN_CARE&userLanguage=en&navCount=0&groupId=&catalogType=&navAction=push&userCountry=cn&title=Entertainment+Tablets&cateId=TABLETS_CA_CN_CARE
3517
3772
  #########
3518
3773
  # @note: this a best guess according to available philips models. Need more User-Agents
3519
- - regex: '; *(D633|D822|D833|T539|T939|V726|W335|W336|W337|W3568|W536|W5510|W626|W632|W6350|W6360|W6500|W732|W736|W737|W7376|W820|W832|W8355|W8500|W8510|W930) Build'
3774
+ - regex: '; *(D633|D822|D833|T539|T939|V726|W335|W336|W337|W3568|W536|W5510|W626|W632|W6350|W6360|W6500|W732|W736|W737|W7376|W820|W832|W8355|W8500|W8510|W930)(?: Build|\) AppleWebKit)'
3520
3775
  device_replacement: '$1'
3521
3776
  brand_replacement: 'Philips'
3522
3777
  model_replacement: '$1'
3523
- - regex: '; *(?:Philips|PHILIPS)[ _]([^;/]+) Build'
3778
+ - regex: '; *(?:Philips|PHILIPS)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
3524
3779
  device_replacement: 'Philips $1'
3525
3780
  brand_replacement: 'Philips'
3526
3781
  model_replacement: '$1'
@@ -3529,7 +3784,7 @@ device_parsers:
3529
3784
  # Pipo
3530
3785
  # @ref: http://www.pipo.cn/En/
3531
3786
  #########
3532
- - regex: 'Android 4\..*; *(M[12356789]|U[12368]|S[123])\ ?(pro)? Build'
3787
+ - regex: 'Android 4\..*; *(M[12356789]|U[12368]|S[123])\ ?(pro)?(?: Build|\) AppleWebKit)'
3533
3788
  device_replacement: 'Pipo $1$2'
3534
3789
  brand_replacement: 'Pipo'
3535
3790
  model_replacement: '$1$2'
@@ -3538,7 +3793,7 @@ device_parsers:
3538
3793
  # Ployer
3539
3794
  # @ref: http://en.ployer.cn/
3540
3795
  #########
3541
- - regex: '; *(MOMO[^;/]+) Build'
3796
+ - regex: '; *(MOMO[^;/]+?)(?: Build|\) AppleWebKit)'
3542
3797
  device_replacement: '$1'
3543
3798
  brand_replacement: 'Ployer'
3544
3799
  model_replacement: '$1'
@@ -3547,11 +3802,11 @@ device_parsers:
3547
3802
  # Polaroid/ Acho
3548
3803
  # @ref: http://polaroidstore.com/store/start.asp?category_id=382&category_id2=0&order=title&filter1=&filter2=&filter3=&view=all
3549
3804
  #########
3550
- - regex: '; *(?:Polaroid[ _])?((?:MIDC\d{3,}|PMID\d{2,}|PTAB\d{3,})[^;/]*)(\/[^;/]*)? Build/'
3805
+ - regex: '; *(?:Polaroid[ _]|)((?:MIDC\d{3,}|PMID\d{2,}|PTAB\d{3,})[^;/]*?)(\/[^;/]*|)(?: Build|\) AppleWebKit)'
3551
3806
  device_replacement: '$1'
3552
3807
  brand_replacement: 'Polaroid'
3553
3808
  model_replacement: '$1'
3554
- - regex: '; *(?:Polaroid )(Tablet) Build/'
3809
+ - regex: '; *(?:Polaroid )(Tablet)(?: Build|\) AppleWebKit)'
3555
3810
  device_replacement: '$1'
3556
3811
  brand_replacement: 'Polaroid'
3557
3812
  model_replacement: '$1'
@@ -3570,11 +3825,11 @@ device_parsers:
3570
3825
  # Positivo
3571
3826
  # @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
3572
3827
  #########
3573
- - regex: '; *(TB07STA|TB10STA|TB07FTA|TB10FTA) Build/'
3828
+ - regex: '; *(TB07STA|TB10STA|TB07FTA|TB10FTA)(?: Build|\) AppleWebKit)'
3574
3829
  device_replacement: '$1'
3575
3830
  brand_replacement: 'Positivo'
3576
3831
  model_replacement: '$1'
3577
- - regex: '; *(?:Positivo )?((?:YPY|Ypy)[^;/]+) Build/'
3832
+ - regex: '; *(?:Positivo |)((?:YPY|Ypy)[^;/]+?)(?: Build|\) AppleWebKit)'
3578
3833
  device_replacement: '$1'
3579
3834
  brand_replacement: 'Positivo'
3580
3835
  model_replacement: '$1'
@@ -3584,15 +3839,15 @@ device_parsers:
3584
3839
  # @ref: http://www.pointofview-online.com/default2.php
3585
3840
  # @TODO: Smartphone Models MOB-3515, MOB-5045-B missing
3586
3841
  #########
3587
- - regex: '; *(MOB-[^;/]+) Build/'
3842
+ - regex: '; *(MOB-[^;/]+?)(?: Build|\) AppleWebKit)'
3588
3843
  device_replacement: '$1'
3589
3844
  brand_replacement: 'POV'
3590
3845
  model_replacement: '$1'
3591
- - regex: '; *POV[ _\-]([^;/]+) Build/'
3846
+ - regex: '; *POV[ _\-]([^;/]+?)(?: Build|\) AppleWebKit)'
3592
3847
  device_replacement: 'POV $1'
3593
3848
  brand_replacement: 'POV'
3594
3849
  model_replacement: '$1'
3595
- - regex: '; *((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\-]|TAB-P)[^;/]*) Build/'
3850
+ - regex: '; *((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\-]|TAB-P)[^;/]*)(?: Build|\) AppleWebKit)'
3596
3851
  device_replacement: 'POV $1'
3597
3852
  brand_replacement: 'POV'
3598
3853
  model_replacement: '$1'
@@ -3602,7 +3857,7 @@ device_parsers:
3602
3857
  # @ref: http://www.prestigio.com/catalogue/MultiPhones
3603
3858
  # @ref: http://www.prestigio.com/catalogue/MultiPads
3604
3859
  #########
3605
- - regex: '; *(?:Prestigio )?((?:PAP|PMP)\d[^;/]+) Build/'
3860
+ - regex: '; *(?:Prestigio |)((?:PAP|PMP)\d[^;/]+?)(?: Build|\) AppleWebKit)'
3606
3861
  device_replacement: 'Prestigio $1'
3607
3862
  brand_replacement: 'Prestigio'
3608
3863
  model_replacement: '$1'
@@ -3611,7 +3866,7 @@ device_parsers:
3611
3866
  # Proscan
3612
3867
  # @ref: http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr=
3613
3868
  #########
3614
- - regex: '; *(PLT[0-9]{4}.*) Build/'
3869
+ - regex: '; *(PLT[0-9]{4}.*?)(?: Build|\) AppleWebKit)'
3615
3870
  device_replacement: '$1'
3616
3871
  brand_replacement: 'Proscan'
3617
3872
  model_replacement: '$1'
@@ -3620,15 +3875,15 @@ device_parsers:
3620
3875
  # QMobile
3621
3876
  # @ref: http://www.qmobile.com.pk/
3622
3877
  #########
3623
- - regex: '; *(A2|A5|A8|A900)_?(Classic)? Build'
3878
+ - regex: '; *(A2|A5|A8|A900)_?(Classic|)(?: Build|\) AppleWebKit)'
3624
3879
  device_replacement: '$1 $2'
3625
3880
  brand_replacement: 'Qmobile'
3626
3881
  model_replacement: '$1 $2'
3627
- - regex: '; *(Q[Mm]obile)_([^_]+)_([^_]+) Build'
3882
+ - regex: '; *(Q[Mm]obile)_([^_]+)_([^_]+?)(?: Build|\) AppleWebKit)'
3628
3883
  device_replacement: 'Qmobile $2 $3'
3629
3884
  brand_replacement: 'Qmobile'
3630
3885
  model_replacement: '$2 $3'
3631
- - regex: '; *(Q\-?[Mm]obile)[_ ](A[^;/]+) Build'
3886
+ - regex: '; *(Q\-?[Mm]obile)[_ ](A[^;/]+?)(?: Build|\) AppleWebKit)'
3632
3887
  device_replacement: 'Qmobile $2'
3633
3888
  brand_replacement: 'Qmobile'
3634
3889
  model_replacement: '$2'
@@ -3637,11 +3892,11 @@ device_parsers:
3637
3892
  # Qmobilevn
3638
3893
  # @ref: http://qmobile.vn/san-pham.html
3639
3894
  #########
3640
- - regex: '; *(Q\-Smart)[ _]([^;/]+) Build/'
3895
+ - regex: '; *(Q\-Smart)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
3641
3896
  device_replacement: '$1 $2'
3642
3897
  brand_replacement: 'Qmobilevn'
3643
3898
  model_replacement: '$2'
3644
- - regex: '; *(Q\-?[Mm]obile)[ _\-](S[^;/]+) Build/'
3899
+ - regex: '; *(Q\-?[Mm]obile)[ _\-](S[^;/]+?)(?: Build|\) AppleWebKit)'
3645
3900
  device_replacement: '$1 $2'
3646
3901
  brand_replacement: 'Qmobilevn'
3647
3902
  model_replacement: '$2'
@@ -3650,7 +3905,7 @@ device_parsers:
3650
3905
  # Quanta
3651
3906
  # @ref: ?
3652
3907
  #########
3653
- - regex: '; *(TA1013) Build'
3908
+ - regex: '; *(TA1013)(?: Build|\) AppleWebKit)'
3654
3909
  device_replacement: '$1'
3655
3910
  brand_replacement: 'Quanta'
3656
3911
  model_replacement: '$1'
@@ -3659,11 +3914,11 @@ device_parsers:
3659
3914
  # RCA
3660
3915
  # @ref: http://rcamobilephone.com/
3661
3916
  #########
3662
- - regex: '; (RCT\w+) Build/'
3917
+ - regex: '; (RCT\w+)(?: Build|\) AppleWebKit)'
3663
3918
  device_replacement: '$1'
3664
3919
  brand_replacement: 'RCA'
3665
3920
  model_replacement: '$1'
3666
- - regex: '; RCA (\w+) Build/'
3921
+ - regex: '; RCA (\w+)(?: Build|\) AppleWebKit)'
3667
3922
  device_replacement: 'RCA $1'
3668
3923
  brand_replacement: 'RCA'
3669
3924
  model_replacement: '$1'
@@ -3673,7 +3928,7 @@ device_parsers:
3673
3928
  # @ref: http://www.rock-chips.com/a/cn/product/index.html
3674
3929
  # @note: manufacturer sells chipsets - I assume that these UAs are dev-boards
3675
3930
  #########
3676
- - regex: '; *(RK\d+),? Build/'
3931
+ - regex: '; *(RK\d+),?(?: Build|\) AppleWebKit)'
3677
3932
  device_replacement: '$1'
3678
3933
  brand_replacement: 'Rockchip'
3679
3934
  model_replacement: '$1'
@@ -3686,11 +3941,11 @@ device_parsers:
3686
3941
  # Samsung Android Devices
3687
3942
  # @ref: http://www.samsung.com/us/mobile/cell-phones/all-products
3688
3943
  #########
3689
- - regex: '; *(SAMSUNG |Samsung )?((?:Galaxy (?:Note II|S\d)|GT-I9082|GT-I9205|GT-N7\d{3}|SM-N9005)[^;/]*)\/?[^;/]* Build/'
3944
+ - regex: '; *(SAMSUNG |Samsung |)((?:Galaxy (?:Note II|S\d)|GT-I9082|GT-I9205|GT-N7\d{3}|SM-N9005)[^;/]*)\/?[^;/]* Build/'
3690
3945
  device_replacement: 'Samsung $1$2'
3691
3946
  brand_replacement: 'Samsung'
3692
3947
  model_replacement: '$2'
3693
- - regex: '; *(Google )?(Nexus [Ss](?: 4G)?) Build/'
3948
+ - regex: '; *(Google |)(Nexus [Ss](?: 4G|)) Build/'
3694
3949
  device_replacement: 'Samsung $1$2'
3695
3950
  brand_replacement: 'Samsung'
3696
3951
  model_replacement: '$2'
@@ -3698,15 +3953,15 @@ device_parsers:
3698
3953
  device_replacement: 'Samsung $2'
3699
3954
  brand_replacement: 'Samsung'
3700
3955
  model_replacement: '$2'
3701
- - regex: '; *(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G)?) Build/'
3956
+ - regex: '; *(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G|)) Build/'
3702
3957
  device_replacement: 'Samsung $1'
3703
3958
  brand_replacement: 'Samsung'
3704
3959
  model_replacement: '$1'
3705
- - regex: '; *(SAMSUNG[ _\-] *)+([^;/]+) Build'
3960
+ - regex: '; *(SAMSUNG[ _\-]|)(?:SAMSUNG[ _\-])([^;/]+) Build'
3706
3961
  device_replacement: 'Samsung $2'
3707
3962
  brand_replacement: 'Samsung'
3708
3963
  model_replacement: '$2'
3709
- - regex: '; *(SAMSUNG-)?(GT\-[BINPS]\d{4}[^\/]*)(\/[^ ]*) Build'
3964
+ - regex: '; *(SAMSUNG-|)(GT\-[BINPS]\d{4}[^\/]*)(\/[^ ]*) Build'
3710
3965
  device_replacement: 'Samsung $1$2$3'
3711
3966
  brand_replacement: 'Samsung'
3712
3967
  model_replacement: '$2'
@@ -3718,11 +3973,15 @@ device_parsers:
3718
3973
  device_replacement: 'Samsung $1$2'
3719
3974
  brand_replacement: 'Samsung'
3720
3975
  model_replacement: '$2'
3721
- - regex: '; *((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\-[A-Za-z0-9 ]+)(/?[^ ]*)? Build'
3976
+ - regex: '; *((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\-[A-Za-z0-9 ]+)(/?[^ ]*|) Build'
3977
+ device_replacement: 'Samsung $1'
3978
+ brand_replacement: 'Samsung'
3979
+ model_replacement: '$1'
3980
+ - regex: '; *((?:SC)\-[A-Za-z0-9 ]+)(/?[^ ]*|)\)'
3722
3981
  device_replacement: 'Samsung $1'
3723
3982
  brand_replacement: 'Samsung'
3724
3983
  model_replacement: '$1'
3725
- - regex: ' ((?:SCH)\-[A-Za-z0-9 ]+)(/?[^ ]*)? Build'
3984
+ - regex: ' ((?:SCH)\-[A-Za-z0-9 ]+)(/?[^ ]*|) Build'
3726
3985
  device_replacement: 'Samsung $1'
3727
3986
  brand_replacement: 'Samsung'
3728
3987
  model_replacement: '$1'
@@ -3730,17 +3989,21 @@ device_parsers:
3730
3989
  device_replacement: 'Samsung $1'
3731
3990
  brand_replacement: 'Samsung'
3732
3991
  model_replacement: '$1'
3992
+ - regex: '; *((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\-[A-Za-z0-9]{5,6})[\)]'
3993
+ device_replacement: 'Samsung $1'
3994
+ brand_replacement: 'Samsung'
3995
+ model_replacement: '$1'
3733
3996
 
3734
3997
  #########
3735
3998
  # Sharp
3736
3999
  # @ref: http://www.sharp-phone.com/en/index.html
3737
4000
  # @ref: http://www.android.com/devices/?country=all&m=sharp
3738
4001
  #########
3739
- - regex: '; *(SH\-?\d\d[^;/]+|SBM\d[^;/]+) Build'
4002
+ - regex: '; *(SH\-?\d\d[^;/]+|SBM\d[^;/]+?)(?: Build|\) AppleWebKit)'
3740
4003
  device_replacement: '$1'
3741
4004
  brand_replacement: 'Sharp'
3742
4005
  model_replacement: '$1'
3743
- - regex: '; *(SHARP[ -])([^;/]+) Build'
4006
+ - regex: '; *(SHARP[ -])([^;/]+?)(?: Build|\) AppleWebKit)'
3744
4007
  device_replacement: '$1$2'
3745
4008
  brand_replacement: 'Sharp'
3746
4009
  model_replacement: '$2'
@@ -3749,15 +4012,15 @@ device_parsers:
3749
4012
  # Simvalley
3750
4013
  # @ref: http://www.simvalley-mobile.de/
3751
4014
  #########
3752
- - regex: '; *(SPX[_\-]\d[^;/]*) Build/'
4015
+ - regex: '; *(SPX[_\-]\d[^;/]*)(?: Build|\) AppleWebKit)'
3753
4016
  device_replacement: '$1'
3754
4017
  brand_replacement: 'Simvalley'
3755
4018
  model_replacement: '$1'
3756
- - regex: '; *(SX7\-PEARL\.GmbH) Build/'
4019
+ - regex: '; *(SX7\-PEARL\.GmbH)(?: Build|\) AppleWebKit)'
3757
4020
  device_replacement: '$1'
3758
4021
  brand_replacement: 'Simvalley'
3759
4022
  model_replacement: '$1'
3760
- - regex: '; *(SP[T]?\-\d{2}[^;/]*) Build/'
4023
+ - regex: '; *(SP[T]?\-\d{2}[^;/]*)(?: Build|\) AppleWebKit)'
3761
4024
  device_replacement: '$1'
3762
4025
  brand_replacement: 'Simvalley'
3763
4026
  model_replacement: '$1'
@@ -3767,7 +4030,7 @@ device_parsers:
3767
4030
  # @ref: http://www.sk-w.com/phone/phone_list.jsp
3768
4031
  # @ref: http://www.android.com/devices/?country=all&m=sk-telesys
3769
4032
  #########
3770
- - regex: '; *(SK\-.*) Build/'
4033
+ - regex: '; *(SK\-.*?)(?: Build|\) AppleWebKit)'
3771
4034
  device_replacement: '$1'
3772
4035
  brand_replacement: 'SKtelesys'
3773
4036
  model_replacement: '$1'
@@ -3776,11 +4039,11 @@ device_parsers:
3776
4039
  # Skytex
3777
4040
  # @ref: http://skytex.com/android
3778
4041
  #########
3779
- - regex: '; *(?:SKYTEX|SX)-([^;/]+) Build'
4042
+ - regex: '; *(?:SKYTEX|SX)-([^;/]+?)(?: Build|\) AppleWebKit)'
3780
4043
  device_replacement: '$1'
3781
4044
  brand_replacement: 'Skytex'
3782
4045
  model_replacement: '$1'
3783
- - regex: '; *(IMAGINE [^;/]+) Build'
4046
+ - regex: '; *(IMAGINE [^;/]+?)(?: Build|\) AppleWebKit)'
3784
4047
  device_replacement: '$1'
3785
4048
  brand_replacement: 'Skytex'
3786
4049
  model_replacement: '$1'
@@ -3790,7 +4053,7 @@ device_parsers:
3790
4053
  # @ref: http://en.smartdevices.com.cn/Products/
3791
4054
  # @models: Z8, X7, U7H, U7, T30, T20, Ten3, V5-II, T7-3G, SmartQ5, K7, S7, Q8, T19, Ten2, Ten, R10, T7, R7, V5, V7, SmartQ7
3792
4055
  #########
3793
- - regex: '; *(SmartQ) ?([^;/]+) Build/'
4056
+ - regex: '; *(SmartQ) ?([^;/]+?)(?: Build|\) AppleWebKit)'
3794
4057
  device_replacement: '$1 $2'
3795
4058
  brand_replacement: '$1'
3796
4059
  model_replacement: '$2'
@@ -3800,7 +4063,7 @@ device_parsers:
3800
4063
  # @ref: http://www.smartbitt.com/
3801
4064
  # @missing: SBT Useragents
3802
4065
  #########
3803
- - regex: '; *(WF7C|WF10C|SBT[^;/]+) Build'
4066
+ - regex: '; *(WF7C|WF10C|SBT[^;/]+?)(?: Build|\) AppleWebKit)'
3804
4067
  device_replacement: '$1'
3805
4068
  brand_replacement: 'Smartbitt'
3806
4069
  model_replacement: '$1'
@@ -3843,7 +4106,7 @@ device_parsers:
3843
4106
  device_replacement: 'Trekstor $1'
3844
4107
  brand_replacement: 'Trekstor'
3845
4108
  model_replacement: '$1'
3846
- - regex: '; *(ST\d{4}.*) Build/'
4109
+ - regex: '; *(ST\d{4}.*?)(?: Build|\) AppleWebKit)'
3847
4110
  device_replacement: 'Trekstor $1'
3848
4111
  brand_replacement: 'Trekstor'
3849
4112
  model_replacement: '$1'
@@ -3859,7 +4122,7 @@ device_parsers:
3859
4122
  device_replacement: '$1$2'
3860
4123
  brand_replacement: 'SonyEricsson'
3861
4124
  model_replacement: '$2'
3862
- - regex: '; *((?:SK|ST|E|X|LT|MK|MT|WT)\d{2}[a-z0-9]*(?:-o)?|R800i|U20i) Build'
4125
+ - regex: '; *((?:SK|ST|E|X|LT|MK|MT|WT)\d{2}[a-z0-9]*(?:-o|)|R800i|U20i) Build'
3863
4126
  device_replacement: '$1'
3864
4127
  brand_replacement: 'SonyEricsson'
3865
4128
  model_replacement: '$1'
@@ -3876,31 +4139,31 @@ device_parsers:
3876
4139
  # @ref: http://www.sonymobile.com/global-en/products/phones/
3877
4140
  # @ref: http://www.sony.jp/tablet/
3878
4141
  #########
3879
- - regex: '; Sony (Tablet[^;/]+) Build'
4142
+ - regex: '; Sony (Tablet[^;/]+?)(?: Build|\) AppleWebKit)'
3880
4143
  device_replacement: 'Sony $1'
3881
4144
  brand_replacement: 'Sony'
3882
4145
  model_replacement: '$1'
3883
- - regex: '; Sony ([^;/]+) Build'
4146
+ - regex: '; Sony ([^;/]+?)(?: Build|\) AppleWebKit)'
3884
4147
  device_replacement: 'Sony $1'
3885
4148
  brand_replacement: 'Sony'
3886
4149
  model_replacement: '$1'
3887
- - regex: '; *(Sony)([A-Za-z0-9\-]+) Build'
4150
+ - regex: '; *(Sony)([A-Za-z0-9\-]+)(?: Build|\) AppleWebKit)'
3888
4151
  device_replacement: '$1 $2'
3889
4152
  brand_replacement: '$1'
3890
4153
  model_replacement: '$2'
3891
- - regex: '; *(Xperia [^;/]+) Build'
4154
+ - regex: '; *(Xperia [^;/]+?)(?: Build|\) AppleWebKit)'
3892
4155
  device_replacement: '$1'
3893
4156
  brand_replacement: 'Sony'
3894
4157
  model_replacement: '$1'
3895
- - regex: '; *(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\d{3}|D6[56]\d{2}) Build'
4158
+ - regex: '; *(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\d{3}|D6[56]\d{2})(?: Build|\) AppleWebKit)'
3896
4159
  device_replacement: '$1'
3897
4160
  brand_replacement: 'Sony'
3898
4161
  model_replacement: '$1'
3899
- - regex: '; *(SGP\d{3}|SGPT\d{2}) Build'
4162
+ - regex: '; *(SGP\d{3}|SGPT\d{2})(?: Build|\) AppleWebKit)'
3900
4163
  device_replacement: '$1'
3901
4164
  brand_replacement: 'Sony'
3902
4165
  model_replacement: '$1'
3903
- - regex: '; *(NW-Z1000Series) Build'
4166
+ - regex: '; *(NW-Z1000Series)(?: Build|\) AppleWebKit)'
3904
4167
  device_replacement: '$1'
3905
4168
  brand_replacement: 'Sony'
3906
4169
  model_replacement: '$1'
@@ -3923,7 +4186,7 @@ device_parsers:
3923
4186
  # Spice
3924
4187
  # @ref: http://www.spicemobilephones.co.in/
3925
4188
  #########
3926
- - regex: '; *((?:CSL_Spice|Spice|SPICE|CSL)[ _\-]?)?([Mm][Ii])([ _\-])?(\d{3}[^;/]*) Build/'
4189
+ - regex: '; *((?:CSL_Spice|Spice|SPICE|CSL)[ _\-]?|)([Mm][Ii])([ _\-]|)(\d{3}[^;/]*)(?: Build|\) AppleWebKit)'
3927
4190
  device_replacement: '$1$2$3$4'
3928
4191
  brand_replacement: 'Spice'
3929
4192
  model_replacement: 'Mi$4'
@@ -3945,7 +4208,7 @@ device_parsers:
3945
4208
  # Tagi
3946
4209
  # @ref: ??
3947
4210
  #########
3948
- - regex: '; *(TAGI[ ]?)(MID) ?([^;/]+) Build/'
4211
+ - regex: '; *(TAGI[ ]?)(MID) ?([^;/]+?)(?: Build|\) AppleWebKit)'
3949
4212
  device_replacement: '$1$2$3'
3950
4213
  brand_replacement: 'Tagi'
3951
4214
  model_replacement: '$2$3'
@@ -3954,7 +4217,7 @@ device_parsers:
3954
4217
  # Tecmobile
3955
4218
  # @ref: http://www.tecmobile.com/
3956
4219
  #########
3957
- - regex: '; *(Oyster500|Opal 800) Build'
4220
+ - regex: '; *(Oyster500|Opal 800)(?: Build|\) AppleWebKit)'
3958
4221
  device_replacement: 'Tecmobile $1'
3959
4222
  brand_replacement: 'Tecmobile'
3960
4223
  model_replacement: '$1'
@@ -3963,7 +4226,7 @@ device_parsers:
3963
4226
  # Tecno
3964
4227
  # @ref: www.tecno-mobile.com/‎
3965
4228
  #########
3966
- - regex: '; *(TECNO[ _])([^;/]+) Build/'
4229
+ - regex: '; *(TECNO[ _])([^;/]+?)(?: Build|\) AppleWebKit)'
3967
4230
  device_replacement: '$1$2'
3968
4231
  brand_replacement: 'Tecno'
3969
4232
  model_replacement: '$2'
@@ -3983,7 +4246,7 @@ device_parsers:
3983
4246
  # @ref: http://www.telstra.com.au/home-phone/thub-2/
3984
4247
  # @ref: https://support.google.com/googleplay/answer/1727131?hl=en
3985
4248
  #########
3986
- - regex: '; *(T-Hub2) Build/'
4249
+ - regex: '; *(T-Hub2)(?: Build|\) AppleWebKit)'
3987
4250
  device_replacement: '$1'
3988
4251
  brand_replacement: 'Telstra'
3989
4252
  model_replacement: '$1'
@@ -3992,7 +4255,7 @@ device_parsers:
3992
4255
  # Terra
3993
4256
  # @ref: http://www.wortmann.de/
3994
4257
  #########
3995
- - regex: '; *(PAD) ?(100[12]) Build/'
4258
+ - regex: '; *(PAD) ?(100[12])(?: Build|\) AppleWebKit)'
3996
4259
  device_replacement: 'Terra $1$2'
3997
4260
  brand_replacement: 'Terra'
3998
4261
  model_replacement: '$1$2'
@@ -4001,7 +4264,7 @@ device_parsers:
4001
4264
  # Texet
4002
4265
  # @ref: http://www.texet.ru/tablet/
4003
4266
  #########
4004
- - regex: '; *(T[BM]-\d{3}[^;/]+) Build/'
4267
+ - regex: '; *(T[BM]-\d{3}[^;/]+?)(?: Build|\) AppleWebKit)'
4005
4268
  device_replacement: '$1'
4006
4269
  brand_replacement: 'Texet'
4007
4270
  model_replacement: '$1'
@@ -4010,7 +4273,7 @@ device_parsers:
4010
4273
  # Thalia
4011
4274
  # @ref: http://www.thalia.de/shop/tolino-shine-ereader/show/
4012
4275
  #########
4013
- - regex: '; *(tolino [^;/]+) Build'
4276
+ - regex: '; *(tolino [^;/]+?)(?: Build|\) AppleWebKit)'
4014
4277
  device_replacement: '$1'
4015
4278
  brand_replacement: 'Thalia'
4016
4279
  model_replacement: '$1'
@@ -4024,11 +4287,11 @@ device_parsers:
4024
4287
  # @ref: http://en.thl.com.cn/Mobile
4025
4288
  # @ref: http://thlmobilestore.com
4026
4289
  #########
4027
- - regex: '; *(?:CJ[ -])?(ThL|THL)[ -]([^;/]+) Build/'
4290
+ - regex: '; *(?:CJ[ -])?(ThL|THL)[ -]([^;/]+?)(?: Build|\) AppleWebKit)'
4028
4291
  device_replacement: '$1 $2'
4029
4292
  brand_replacement: 'Thl'
4030
4293
  model_replacement: '$2'
4031
- - regex: '; *(T100|T200|T5|W100|W200|W8s) Build/'
4294
+ - regex: '; *(T100|T200|T5|W100|W200|W8s)(?: Build|\) AppleWebKit)'
4032
4295
  device_replacement: '$1'
4033
4296
  brand_replacement: 'Thl'
4034
4297
  model_replacement: '$1'
@@ -4062,7 +4325,7 @@ device_parsers:
4062
4325
  device_replacement: '$1'
4063
4326
  brand_replacement: 'HTC'
4064
4327
  model_replacement: 'Dream'
4065
- - regex: '\b(T-Mobile ?)?(myTouch)[ _]?([34]G)[ _]?([^\/]*) (?:Mozilla|Build)'
4328
+ - regex: '\b(T-Mobile ?|)(myTouch)[ _]?([34]G)[ _]?([^\/]*) (?:Mozilla|Build)'
4066
4329
  device_replacement: '$1$2 $3 $4'
4067
4330
  brand_replacement: 'HTC'
4068
4331
  model_replacement: '$2 $3 $4'
@@ -4079,7 +4342,7 @@ device_parsers:
4079
4342
  # Tomtec
4080
4343
  # @ref: http://www.tom-tec.eu/pages/tablets.php
4081
4344
  #########
4082
- - regex: ' (ATP[0-9]{4}) Build'
4345
+ - regex: ' (ATP[0-9]{4})(?: Build|\) AppleWebKit)'
4083
4346
  device_replacement: '$1'
4084
4347
  brand_replacement: 'Tomtec'
4085
4348
  model_replacement: '$1'
@@ -4088,7 +4351,7 @@ device_parsers:
4088
4351
  # Tooky
4089
4352
  # @ref: http://www.tookymobile.com/
4090
4353
  #########
4091
- - regex: ' *(TOOKY)[ _\-]([^;/]+) ?(?:Build|;)'
4354
+ - regex: ' *(TOOKY)[ _\-]([^;/]+?) ?(?:Build|;)'
4092
4355
  regex_flag: 'i'
4093
4356
  device_replacement: '$1 $2'
4094
4357
  brand_replacement: 'Tooky'
@@ -4103,11 +4366,11 @@ device_parsers:
4103
4366
  device_replacement: '$1'
4104
4367
  brand_replacement: 'Toshiba'
4105
4368
  model_replacement: 'Folio 100'
4106
- - regex: '; *([Ff]olio ?100) Build/'
4369
+ - regex: '; *([Ff]olio ?100)(?: Build|\) AppleWebKit)'
4107
4370
  device_replacement: '$1'
4108
4371
  brand_replacement: 'Toshiba'
4109
4372
  model_replacement: 'Folio 100'
4110
- - regex: '; *(AT[0-9]{2,3}(?:\-A|LE\-A|PE\-A|SE|a)?|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]+|THRiVE|Thrive) Build/'
4373
+ - regex: '; *(AT[0-9]{2,3}(?:\-A|LE\-A|PE\-A|SE|a|)|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]+|THRiVE|Thrive)(?: Build|\) AppleWebKit)'
4111
4374
  device_replacement: 'Toshiba $1'
4112
4375
  brand_replacement: 'Toshiba'
4113
4376
  model_replacement: '$1'
@@ -4116,12 +4379,12 @@ device_parsers:
4116
4379
  # Touchmate
4117
4380
  # @ref: http://touchmatepc.com/new/
4118
4381
  #########
4119
- - regex: '; *(TM-MID\d+[^;/]+|TOUCHMATE|MID-750) Build'
4382
+ - regex: '; *(TM-MID\d+[^;/]+|TOUCHMATE|MID-750)(?: Build|\) AppleWebKit)'
4120
4383
  device_replacement: '$1'
4121
4384
  brand_replacement: 'Touchmate'
4122
4385
  model_replacement: '$1'
4123
4386
  # @todo: needs verification user-agents missing
4124
- - regex: '; *(TM-SM\d+[^;/]+) Build'
4387
+ - regex: '; *(TM-SM\d+[^;/]+?)(?: Build|\) AppleWebKit)'
4125
4388
  device_replacement: '$1'
4126
4389
  brand_replacement: 'Touchmate'
4127
4390
  model_replacement: '$1'
@@ -4130,11 +4393,11 @@ device_parsers:
4130
4393
  # Treq
4131
4394
  # @ref: http://www.treq.co.id/product
4132
4395
  #########
4133
- - regex: '; *(A10 [Bb]asic2?) Build/'
4396
+ - regex: '; *(A10 [Bb]asic2?)(?: Build|\) AppleWebKit)'
4134
4397
  device_replacement: '$1'
4135
4398
  brand_replacement: 'Treq'
4136
4399
  model_replacement: '$1'
4137
- - regex: '; *(TREQ[ _\-])([^;/]+) Build'
4400
+ - regex: '; *(TREQ[ _\-])([^;/]+?)(?: Build|\) AppleWebKit)'
4138
4401
  regex_flag: 'i'
4139
4402
  device_replacement: '$1$2'
4140
4403
  brand_replacement: 'Treq'
@@ -4146,12 +4409,12 @@ device_parsers:
4146
4409
  # @models: A936|A603|X-5|X-3
4147
4410
  #########
4148
4411
  # @todo: guessed markers
4149
- - regex: '; *(X-?5|X-?3) Build/'
4412
+ - regex: '; *(X-?5|X-?3)(?: Build|\) AppleWebKit)'
4150
4413
  device_replacement: '$1'
4151
4414
  brand_replacement: 'Umeox'
4152
4415
  model_replacement: '$1'
4153
4416
  # @todo: guessed markers
4154
- - regex: '; *(A502\+?|A936|A603|X1|X2) Build/'
4417
+ - regex: '; *(A502\+?|A936|A603|X1|X2)(?: Build|\) AppleWebKit)'
4155
4418
  device_replacement: '$1'
4156
4419
  brand_replacement: 'Umeox'
4157
4420
  model_replacement: '$1'
@@ -4160,7 +4423,7 @@ device_parsers:
4160
4423
  # Versus
4161
4424
  # @ref: http://versusuk.com/support.html
4162
4425
  #########
4163
- - regex: '(TOUCH(?:TAB|PAD).+?) Build/'
4426
+ - regex: '(TOUCH(?:TAB|PAD).+?)(?: Build|\) AppleWebKit)'
4164
4427
  regex_flag: 'i'
4165
4428
  device_replacement: 'Versus $1'
4166
4429
  brand_replacement: 'Versus'
@@ -4170,7 +4433,7 @@ device_parsers:
4170
4433
  # Vertu
4171
4434
  # @ref: http://www.vertu.com/
4172
4435
  #########
4173
- - regex: '(VERTU) ([^;/]+) Build/'
4436
+ - regex: '(VERTU) ([^;/]+?)(?: Build|\) AppleWebKit)'
4174
4437
  device_replacement: '$1 $2'
4175
4438
  brand_replacement: 'Vertu'
4176
4439
  model_replacement: '$2'
@@ -4179,11 +4442,11 @@ device_parsers:
4179
4442
  # Videocon
4180
4443
  # @ref: http://www.videoconmobiles.com
4181
4444
  #########
4182
- - regex: '; *(Videocon)[ _\-]([^;/]+) *(?:Build|;)'
4445
+ - regex: '; *(Videocon)[ _\-]([^;/]+?) *(?:Build|;)'
4183
4446
  device_replacement: '$1 $2'
4184
4447
  brand_replacement: 'Videocon'
4185
4448
  model_replacement: '$2'
4186
- - regex: ' (VT\d{2}[A-Za-z]*) Build'
4449
+ - regex: ' (VT\d{2}[A-Za-z]*)(?: Build|\) AppleWebKit)'
4187
4450
  device_replacement: '$1'
4188
4451
  brand_replacement: 'Videocon'
4189
4452
  model_replacement: '$1'
@@ -4192,15 +4455,15 @@ device_parsers:
4192
4455
  # Viewsonic
4193
4456
  # @ref: http://viewsonic.com
4194
4457
  #########
4195
- - regex: '; *((?:ViewPad|ViewPhone|VSD)[^;/]+) Build/'
4458
+ - regex: '; *((?:ViewPad|ViewPhone|VSD)[^;/]+?)(?: Build|\) AppleWebKit)'
4196
4459
  device_replacement: '$1'
4197
4460
  brand_replacement: 'Viewsonic'
4198
4461
  model_replacement: '$1'
4199
- - regex: '; *(ViewSonic-)([^;/]+) Build/'
4462
+ - regex: '; *(ViewSonic-)([^;/]+?)(?: Build|\) AppleWebKit)'
4200
4463
  device_replacement: '$1$2'
4201
4464
  brand_replacement: 'Viewsonic'
4202
4465
  model_replacement: '$2'
4203
- - regex: '; *(GTablet.*) Build/'
4466
+ - regex: '; *(GTablet.*?)(?: Build|\) AppleWebKit)'
4204
4467
  device_replacement: '$1'
4205
4468
  brand_replacement: 'Viewsonic'
4206
4469
  model_replacement: '$1'
@@ -4209,7 +4472,7 @@ device_parsers:
4209
4472
  # vivo
4210
4473
  # @ref: http://vivo.cn/
4211
4474
  #########
4212
- - regex: '; *([Vv]ivo)[ _]([^;/]+) Build'
4475
+ - regex: '; *([Vv]ivo)[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
4213
4476
  device_replacement: '$1 $2'
4214
4477
  brand_replacement: 'vivo'
4215
4478
  model_replacement: '$2'
@@ -4218,7 +4481,7 @@ device_parsers:
4218
4481
  # Vodafone (Operator Branded Devices)
4219
4482
  # @ref: ??
4220
4483
  #########
4221
- - regex: '(Vodafone) (.*) Build/'
4484
+ - regex: '(Vodafone) (.*?)(?: Build|\) AppleWebKit)'
4222
4485
  device_replacement: '$1 $2'
4223
4486
  brand_replacement: '$1'
4224
4487
  model_replacement: '$2'
@@ -4227,7 +4490,7 @@ device_parsers:
4227
4490
  # Walton
4228
4491
  # @ref: http://www.waltonbd.com/
4229
4492
  #########
4230
- - regex: '; *(?:Walton[ _\-])?(Primo[ _\-][^;/]+) Build'
4493
+ - regex: '; *(?:Walton[ _\-]|)(Primo[ _\-][^;/]+?)(?: Build|\) AppleWebKit)'
4231
4494
  regex_flag: 'i'
4232
4495
  device_replacement: 'Walton $1'
4233
4496
  brand_replacement: 'Walton'
@@ -4237,7 +4500,7 @@ device_parsers:
4237
4500
  # Wiko
4238
4501
  # @ref: http://fr.wikomobile.com/collection.php?s=Smartphones
4239
4502
  #########
4240
- - regex: '; *(?:WIKO[ \-])?(CINK\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]+) Build/'
4503
+ - regex: '; *(?:WIKO[ \-]|)(CINK\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]+?)(?: Build|\) AppleWebKit)'
4241
4504
  regex_flag: 'i'
4242
4505
  device_replacement: 'Wiko $1'
4243
4506
  brand_replacement: 'Wiko'
@@ -4247,7 +4510,7 @@ device_parsers:
4247
4510
  # WellcoM
4248
4511
  # @ref: ??
4249
4512
  #########
4250
- - regex: '; *WellcoM-([^;/]+) Build'
4513
+ - regex: '; *WellcoM-([^;/]+?)(?: Build|\) AppleWebKit)'
4251
4514
  device_replacement: 'Wellcom $1'
4252
4515
  brand_replacement: 'Wellcom'
4253
4516
  model_replacement: '$1'
@@ -4265,7 +4528,7 @@ device_parsers:
4265
4528
  # Wolfgang
4266
4529
  # @ref: http://wolfgangmobile.com/
4267
4530
  #########
4268
- - regex: '; *(AT-AS[^;/]+) Build'
4531
+ - regex: '; *(AT-AS[^;/]+?)(?: Build|\) AppleWebKit)'
4269
4532
  device_replacement: 'Wolfgang $1'
4270
4533
  brand_replacement: 'Wolfgang'
4271
4534
  model_replacement: '$1'
@@ -4274,7 +4537,7 @@ device_parsers:
4274
4537
  # Woxter
4275
4538
  # @ref: http://www.woxter.es/es-es/categories/index
4276
4539
  #########
4277
- - regex: '; *(?:Woxter|Wxt) ([^;/]+) Build'
4540
+ - regex: '; *(?:Woxter|Wxt) ([^;/]+?)(?: Build|\) AppleWebKit)'
4278
4541
  device_replacement: 'Woxter $1'
4279
4542
  brand_replacement: 'Woxter'
4280
4543
  model_replacement: '$1'
@@ -4283,7 +4546,7 @@ device_parsers:
4283
4546
  # Yarvik Zania
4284
4547
  # @ref: http://yarvik.com
4285
4548
  #########
4286
- - regex: '; *(?:Xenta |Luna )?(TAB[234][0-9]{2}|TAB0[78]-\d{3}|TAB0?9-\d{3}|TAB1[03]-\d{3}|SMP\d{2}-\d{3}) Build/'
4549
+ - regex: '; *(?:Xenta |Luna |)(TAB[234][0-9]{2}|TAB0[78]-\d{3}|TAB0?9-\d{3}|TAB1[03]-\d{3}|SMP\d{2}-\d{3})(?: Build|\) AppleWebKit)'
4287
4550
  device_replacement: 'Yarvik $1'
4288
4551
  brand_replacement: 'Yarvik'
4289
4552
  model_replacement: '$1'
@@ -4306,7 +4569,19 @@ device_parsers:
4306
4569
  # XiaoMi
4307
4570
  # @ref: http://www.xiaomi.com/event/buyphone
4308
4571
  #########
4309
- - regex: '; *((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note )?[^;/]*) (Build|MIUI)/'
4572
+ - regex: '; *((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/]*) (Build|MIUI)/'
4573
+ device_replacement: 'XiaoMi $1'
4574
+ brand_replacement: 'XiaoMi'
4575
+ model_replacement: '$1'
4576
+ - regex: '; *((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/\)]*)'
4577
+ device_replacement: 'XiaoMi $1'
4578
+ brand_replacement: 'XiaoMi'
4579
+ model_replacement: '$1'
4580
+ - regex: '; *(MIX) (Build|MIUI)/'
4581
+ device_replacement: 'XiaoMi $1'
4582
+ brand_replacement: 'XiaoMi'
4583
+ model_replacement: '$1'
4584
+ - regex: '; *((MIX) ([^;/]*)) (Build|MIUI)/'
4310
4585
  device_replacement: 'XiaoMi $1'
4311
4586
  brand_replacement: 'XiaoMi'
4312
4587
  model_replacement: '$1'
@@ -4315,17 +4590,17 @@ device_parsers:
4315
4590
  # Xolo
4316
4591
  # @ref: http://www.xolo.in/
4317
4592
  #########
4318
- - regex: '; *XOLO[ _]([^;/]*tab.*) Build'
4593
+ - regex: '; *XOLO[ _]([^;/]*tab.*)(?: Build|\) AppleWebKit)'
4319
4594
  regex_flag: 'i'
4320
4595
  device_replacement: 'Xolo $1'
4321
4596
  brand_replacement: 'Xolo'
4322
4597
  model_replacement: '$1'
4323
- - regex: '; *XOLO[ _]([^;/]+) Build'
4598
+ - regex: '; *XOLO[ _]([^;/]+?)(?: Build|\) AppleWebKit)'
4324
4599
  regex_flag: 'i'
4325
4600
  device_replacement: 'Xolo $1'
4326
4601
  brand_replacement: 'Xolo'
4327
4602
  model_replacement: '$1'
4328
- - regex: '; *(q\d0{2,3}[a-z]?) Build'
4603
+ - regex: '; *(q\d0{2,3}[a-z]?)(?: Build|\) AppleWebKit)'
4329
4604
  regex_flag: 'i'
4330
4605
  device_replacement: 'Xolo $1'
4331
4606
  brand_replacement: 'Xolo'
@@ -4335,7 +4610,7 @@ device_parsers:
4335
4610
  # Xoro
4336
4611
  # @ref: http://www.xoro.de/produkte/
4337
4612
  #########
4338
- - regex: '; *(PAD ?[79]\d+[^;/]*|TelePAD\d+[^;/]) Build'
4613
+ - regex: '; *(PAD ?[79]\d+[^;/]*|TelePAD\d+[^;/])(?: Build|\) AppleWebKit)'
4339
4614
  device_replacement: 'Xoro $1'
4340
4615
  brand_replacement: 'Xoro'
4341
4616
  model_replacement: '$1'
@@ -4344,7 +4619,7 @@ device_parsers:
4344
4619
  # Zopo
4345
4620
  # @ref: http://www.zopomobiles.com/products.html
4346
4621
  #########
4347
- - regex: '; *(?:(?:ZOPO|Zopo)[ _]([^;/]+)|(ZP ?(?:\d{2}[^;/]+|C2))|(C[2379])) Build'
4622
+ - regex: '; *(?:(?:ZOPO|Zopo)[ _]([^;/]+?)|(ZP ?(?:\d{2}[^;/]+|C2))|(C[2379]))(?: Build|\) AppleWebKit)'
4348
4623
  device_replacement: '$1$2$3'
4349
4624
  brand_replacement: 'Zopo'
4350
4625
  model_replacement: '$1$2$3'
@@ -4353,11 +4628,11 @@ device_parsers:
4353
4628
  # ZiiLabs
4354
4629
  # @ref: http://www.ziilabs.com/products/platforms/androidreferencetablets.php
4355
4630
  #########
4356
- - regex: '; *(ZiiLABS) (Zii[^;/]*) Build'
4631
+ - regex: '; *(ZiiLABS) (Zii[^;/]*)(?: Build|\) AppleWebKit)'
4357
4632
  device_replacement: '$1 $2'
4358
4633
  brand_replacement: 'ZiiLabs'
4359
4634
  model_replacement: '$2'
4360
- - regex: '; *(Zii)_([^;/]*) Build'
4635
+ - regex: '; *(Zii)_([^;/]*)(?: Build|\) AppleWebKit)'
4361
4636
  device_replacement: '$1 $2'
4362
4637
  brand_replacement: 'ZiiLabs'
4363
4638
  model_replacement: '$2'
@@ -4366,40 +4641,40 @@ device_parsers:
4366
4641
  # ZTE
4367
4642
  # @ref: http://www.ztedevices.com/
4368
4643
  #########
4369
- - regex: '; *(ARIZONA|(?:ATLAS|Atlas) W|D930|Grand (?:[SX][^;]*|Era|Memo[^;]*)|JOE|(?:Kis|KIS)\b[^;]*|Libra|Light [^;]*|N8[056][01]|N850L|N8000|N9[15]\d{2}|N9810|NX501|Optik|(?:Vip )Racer[^;]*|RacerII|RACERII|San Francisco[^;]*|V9[AC]|V55|V881|Z[679][0-9]{2}[A-z]?) Build'
4644
+ - regex: '; *(ARIZONA|(?:ATLAS|Atlas) W|D930|Grand (?:[SX][^;]*?|Era|Memo[^;]*?)|JOE|(?:Kis|KIS)\b[^;]*?|Libra|Light [^;]*?|N8[056][01]|N850L|N8000|N9[15]\d{2}|N9810|NX501|Optik|(?:Vip )Racer[^;]*?|RacerII|RACERII|San Francisco[^;]*?|V9[AC]|V55|V881|Z[679][0-9]{2}[A-z]?)(?: Build|\) AppleWebKit)'
4370
4645
  device_replacement: '$1'
4371
4646
  brand_replacement: 'ZTE'
4372
4647
  model_replacement: '$1'
4373
- - regex: '; *([A-Z]\d+)_USA_[^;]* Build'
4648
+ - regex: '; *([A-Z]\d+)_USA_[^;]*(?: Build|\) AppleWebKit)'
4374
4649
  device_replacement: '$1'
4375
4650
  brand_replacement: 'ZTE'
4376
4651
  model_replacement: '$1'
4377
- - regex: '; *(SmartTab\d+)[^;]* Build'
4652
+ - regex: '; *(SmartTab\d+)[^;]*(?: Build|\) AppleWebKit)'
4378
4653
  device_replacement: '$1'
4379
4654
  brand_replacement: 'ZTE'
4380
4655
  model_replacement: '$1'
4381
- - regex: '; *(?:Blade|BLADE|ZTE-BLADE)([^;/]*) Build'
4656
+ - regex: '; *(?:Blade|BLADE|ZTE-BLADE)([^;/]*)(?: Build|\) AppleWebKit)'
4382
4657
  device_replacement: 'ZTE Blade$1'
4383
4658
  brand_replacement: 'ZTE'
4384
4659
  model_replacement: 'Blade$1'
4385
- - regex: '; *(?:Skate|SKATE|ZTE-SKATE)([^;/]*) Build'
4660
+ - regex: '; *(?:Skate|SKATE|ZTE-SKATE)([^;/]*)(?: Build|\) AppleWebKit)'
4386
4661
  device_replacement: 'ZTE Skate$1'
4387
4662
  brand_replacement: 'ZTE'
4388
4663
  model_replacement: 'Skate$1'
4389
- - regex: '; *(Orange |Optimus )(Monte Carlo|San Francisco) Build'
4664
+ - regex: '; *(Orange |Optimus )(Monte Carlo|San Francisco)(?: Build|\) AppleWebKit)'
4390
4665
  device_replacement: '$1$2'
4391
4666
  brand_replacement: 'ZTE'
4392
4667
  model_replacement: '$1$2'
4393
- - regex: '; *(?:ZXY-ZTE_|ZTE\-U |ZTE[\- _]|ZTE-C[_ ])([^;/]+) Build'
4668
+ - regex: '; *(?:ZXY-ZTE_|ZTE\-U |ZTE[\- _]|ZTE-C[_ ])([^;/]+?)(?: Build|\) AppleWebKit)'
4394
4669
  device_replacement: 'ZTE $1'
4395
4670
  brand_replacement: 'ZTE'
4396
4671
  model_replacement: '$1'
4397
4672
  # operator specific
4398
- - regex: '; (BASE) (lutea|Lutea 2|Tab[^;]*) Build'
4673
+ - regex: '; (BASE) (lutea|Lutea 2|Tab[^;]*?)(?: Build|\) AppleWebKit)'
4399
4674
  device_replacement: '$1 $2'
4400
4675
  brand_replacement: 'ZTE'
4401
4676
  model_replacement: '$1 $2'
4402
- - regex: '; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link) Build'
4677
+ - regex: '; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link)(?: Build|\) AppleWebKit)'
4403
4678
  regex_flag: 'i'
4404
4679
  device_replacement: '$1'
4405
4680
  brand_replacement: 'ZTE'
@@ -4413,7 +4688,7 @@ device_parsers:
4413
4688
  # Zync
4414
4689
  # @ref: http://www.zync.in/index.php/our-products/tablet-phablets
4415
4690
  ##########
4416
- - regex: '; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900) Build/'
4691
+ - regex: '; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900)(?: Build|\) AppleWebKit)'
4417
4692
  device_replacement: '$1'
4418
4693
  brand_replacement: 'Zync'
4419
4694
  model_replacement: '$1'
@@ -4472,7 +4747,7 @@ device_parsers:
4472
4747
  device_replacement: 'Kindle'
4473
4748
  brand_replacement: 'Amazon'
4474
4749
  model_replacement: 'Kindle'
4475
- - regex: '; ?(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))? Build\b'
4750
+ - regex: '; ?(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+)|) Build\b'
4476
4751
  device_replacement: 'Kindle Fire'
4477
4752
  brand_replacement: 'Amazon'
4478
4753
  model_replacement: 'Kindle Fire$2'
@@ -4524,7 +4799,7 @@ device_parsers:
4524
4799
  #########
4525
4800
  # Alcatel Windows Phones
4526
4801
  #########
4527
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:ALCATEL)[^;]*; *([^;,\)]+)'
4802
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:ALCATEL)[^;]*; *([^;,\)]+)'
4528
4803
  device_replacement: 'Alcatel $1'
4529
4804
  brand_replacement: 'Alcatel'
4530
4805
  model_replacement: '$1'
@@ -4532,8 +4807,8 @@ device_parsers:
4532
4807
  #########
4533
4808
  # Asus Windows Phones
4534
4809
  #########
4535
- #~ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:ASUS|Asus)[^;]*; *([^;,\)]+)'
4536
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:ASUS|Asus)[^;]*; *([^;,\)]+)'
4810
+ #~ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:ASUS|Asus)[^;]*; *([^;,\)]+)'
4811
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:ASUS|Asus)[^;]*; *([^;,\)]+)'
4537
4812
  device_replacement: 'Asus $1'
4538
4813
  brand_replacement: 'Asus'
4539
4814
  model_replacement: '$1'
@@ -4541,7 +4816,7 @@ device_parsers:
4541
4816
  #########
4542
4817
  # Dell Windows Phones
4543
4818
  #########
4544
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:DELL|Dell)[^;]*; *([^;,\)]+)'
4819
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:DELL|Dell)[^;]*; *([^;,\)]+)'
4545
4820
  device_replacement: 'Dell $1'
4546
4821
  brand_replacement: 'Dell'
4547
4822
  model_replacement: '$1'
@@ -4549,7 +4824,7 @@ device_parsers:
4549
4824
  #########
4550
4825
  # HTC Windows Phones
4551
4826
  #########
4552
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:HTC|Htc|HTC_blocked[^;]*)[^;]*; *(?:HTC)?([^;,\)]+)'
4827
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:HTC|Htc|HTC_blocked[^;]*)[^;]*; *(?:HTC|)([^;,\)]+)'
4553
4828
  device_replacement: 'HTC $1'
4554
4829
  brand_replacement: 'HTC'
4555
4830
  model_replacement: '$1'
@@ -4557,7 +4832,7 @@ device_parsers:
4557
4832
  #########
4558
4833
  # Huawei Windows Phones
4559
4834
  #########
4560
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:HUAWEI)[^;]*; *(?:HUAWEI )?([^;,\)]+)'
4835
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:HUAWEI)[^;]*; *(?:HUAWEI |)([^;,\)]+)'
4561
4836
  device_replacement: 'Huawei $1'
4562
4837
  brand_replacement: 'Huawei'
4563
4838
  model_replacement: '$1'
@@ -4565,7 +4840,7 @@ device_parsers:
4565
4840
  #########
4566
4841
  # LG Windows Phones
4567
4842
  #########
4568
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:LG|Lg)[^;]*; *(?:LG[ \-])?([^;,\)]+)'
4843
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:LG|Lg)[^;]*; *(?:LG[ \-]|)([^;,\)]+)'
4569
4844
  device_replacement: 'LG $1'
4570
4845
  brand_replacement: 'LG'
4571
4846
  model_replacement: '$1'
@@ -4573,15 +4848,15 @@ device_parsers:
4573
4848
  #########
4574
4849
  # Noka Windows Phones
4575
4850
  #########
4576
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:rv:11; )?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*(\d{3,}[^;\)]*)'
4851
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:rv:11; |)(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)(\d{3,10}[^;\)]*)'
4577
4852
  device_replacement: 'Lumia $1'
4578
4853
  brand_replacement: 'Nokia'
4579
4854
  model_replacement: 'Lumia $1'
4580
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(RM-\d{3,})'
4855
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]*; *(RM-\d{3,})'
4581
4856
  device_replacement: 'Nokia $1'
4582
4857
  brand_replacement: 'Nokia'
4583
4858
  model_replacement: '$1'
4584
- - regex: '(?:Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*([^;\)]+)'
4859
+ - regex: '(?:Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)([^;\)]+)'
4585
4860
  device_replacement: 'Nokia $1'
4586
4861
  brand_replacement: 'Nokia'
4587
4862
  model_replacement: '$1'
@@ -4589,7 +4864,7 @@ device_parsers:
4589
4864
  #########
4590
4865
  # Microsoft Windows Phones
4591
4866
  #########
4592
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:Microsoft(?: Corporation)?)[^;]*; *([^;,\)]+)'
4867
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:Microsoft(?: Corporation|))[^;]*; *([^;,\)]+)'
4593
4868
  device_replacement: 'Microsoft $1'
4594
4869
  brand_replacement: 'Microsoft'
4595
4870
  model_replacement: '$1'
@@ -4597,7 +4872,7 @@ device_parsers:
4597
4872
  #########
4598
4873
  # Samsung Windows Phones
4599
4874
  #########
4600
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:SAMSUNG)[^;]*; *(?:SAMSUNG )?([^;,\.\)]+)'
4875
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:SAMSUNG)[^;]*; *(?:SAMSUNG |)([^;,\.\)]+)'
4601
4876
  device_replacement: 'Samsung $1'
4602
4877
  brand_replacement: 'Samsung'
4603
4878
  model_replacement: '$1'
@@ -4605,7 +4880,7 @@ device_parsers:
4605
4880
  #########
4606
4881
  # Toshiba Windows Phones
4607
4882
  #########
4608
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]*; *([^;,\)]+)'
4883
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]*; *([^;,\)]+)'
4609
4884
  device_replacement: 'Toshiba $1'
4610
4885
  brand_replacement: 'Toshiba'
4611
4886
  model_replacement: '$1'
@@ -4613,7 +4888,7 @@ device_parsers:
4613
4888
  #########
4614
4889
  # Generic Windows Phones
4615
4890
  #########
4616
- - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?([^;]+); *([^;,\)]+)'
4891
+ - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)([^;]+); *([^;,\)]+)'
4617
4892
  device_replacement: '$1 $2'
4618
4893
  brand_replacement: '$1'
4619
4894
  model_replacement: '$2'
@@ -4633,7 +4908,7 @@ device_parsers:
4633
4908
  #########
4634
4909
  # Firefox OS
4635
4910
  #########
4636
- - regex: '\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]+)(?:/[^;]+)?; rv:[^\)]+\) Gecko/[^\/]+ Firefox/'
4911
+ - regex: '\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]+?)(?:/[^;]+|); rv:[^\)]+\) Gecko/[^\/]+ Firefox/'
4637
4912
  device_replacement: 'Alcatel $1 $2 $3'
4638
4913
  brand_replacement: 'Alcatel'
4639
4914
  model_replacement: 'One Touch $3'
@@ -4642,11 +4917,27 @@ device_parsers:
4642
4917
  brand_replacement: 'ZTE'
4643
4918
  model_replacement: '$1$2'
4644
4919
 
4920
+ #########
4921
+ # KaiOS
4922
+ #########
4923
+ - regex: '\(Mobile; ALCATEL([A-Za-z0-9\-]+); rv:[^\)]+\) Gecko/[^\/]+ Firefox/[^\/]+ KaiOS/'
4924
+ device_replacement: 'Alcatel $1'
4925
+ brand_replacement: 'Alcatel'
4926
+ model_replacement: '$1'
4927
+ - regex: '\(Mobile; LYF\/([A-Za-z0-9\-]+)\/.+;.+rv:[^\)]+\) Gecko/[^\/]+ Firefox/[^\/]+ KAIOS/'
4928
+ device_replacement: 'LYF $1'
4929
+ brand_replacement: 'LYF'
4930
+ model_replacement: '$1'
4931
+ - regex: '\(Mobile; Nokia_([A-Za-z0-9\-]+)_.+; rv:[^\)]+\) Gecko/[^\/]+ Firefox/[^\/]+ KAIOS/'
4932
+ device_replacement: 'Nokia $1'
4933
+ brand_replacement: 'Nokia'
4934
+ model_replacement: '$1'
4935
+
4645
4936
  ##########
4646
4937
  # NOKIA
4647
4938
  # @note: NokiaN8-00 comes before iphone. Sometimes spoofs iphone
4648
4939
  ##########
4649
- - regex: 'Nokia(N[0-9]+)([A-z_\-][A-z0-9_\-]*)'
4940
+ - regex: 'Nokia(N[0-9]+)([A-Za-z_\-][A-Za-z0-9_\-]*)'
4650
4941
  device_replacement: 'Nokia $1'
4651
4942
  brand_replacement: 'Nokia'
4652
4943
  model_replacement: '$1$2'
@@ -4659,12 +4950,12 @@ device_parsers:
4659
4950
  brand_replacement: 'Nokia'
4660
4951
  model_replacement: 'Lumia $1'
4661
4952
  # UCWEB Browser on Symbian
4662
- - regex: '\(Symbian; U; S60 V5; [A-z]{2}\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]+)\)'
4953
+ - regex: '\(Symbian; U; S60 V5; [A-z]{2}\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]+?)\)'
4663
4954
  device_replacement: '$1 $2'
4664
4955
  brand_replacement: '$1'
4665
4956
  model_replacement: '$2'
4666
4957
  # Nokia Symbian
4667
- - regex: '\(Symbian(?:/3)?; U; ([^;]+);'
4958
+ - regex: '\(Symbian(?:/3|); U; ([^;]+);'
4668
4959
  device_replacement: 'Nokia $1'
4669
4960
  brand_replacement: 'Nokia'
4670
4961
  model_replacement: '$1'
@@ -4709,7 +5000,7 @@ device_parsers:
4709
5000
  device_replacement: 'Palm Treo $1'
4710
5001
  brand_replacement: 'Palm'
4711
5002
  model_replacement: 'Treo $1'
4712
- - regex: 'webOS.*(P160U(?:NA)?)/(\d+).(\d+)'
5003
+ - regex: 'webOS.*(P160U(?:NA|))/(\d+).(\d+)'
4713
5004
  device_replacement: 'HP Veer'
4714
5005
  brand_replacement: 'HP'
4715
5006
  model_replacement: 'Veer'
@@ -4768,6 +5059,10 @@ device_parsers:
4768
5059
  device_replacement: '$1'
4769
5060
  brand_replacement: 'Apple'
4770
5061
  model_replacement: '$1'
5062
+ - regex: '(Watch)(\d+,\d+)'
5063
+ device_replacement: 'Apple $1'
5064
+ brand_replacement: 'Apple'
5065
+ model_replacement: '$1$2'
4771
5066
  - regex: '(Apple Watch)(?:;| Simulator;)'
4772
5067
  device_replacement: '$1'
4773
5068
  brand_replacement: 'Apple'
@@ -4836,7 +5131,11 @@ device_parsers:
4836
5131
  device_replacement: 'Asus $1'
4837
5132
  brand_replacement: 'Asus'
4838
5133
  model_replacement: '$1'
4839
- - regex: '(?:asus.*?ASUS|Asus|ASUS|asus)[\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _])?[A-Za-z0-9]+)'
5134
+ - regex: '(?:asus.*?ASUS|Asus|ASUS|asus)[\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _]|)[A-Za-z0-9]+)'
5135
+ device_replacement: 'Asus $1'
5136
+ brand_replacement: 'Asus'
5137
+ model_replacement: '$1'
5138
+ - regex: '(?:ASUS)_([A-Za-z0-9\-]+)'
4840
5139
  device_replacement: 'Asus $1'
4841
5140
  brand_replacement: 'Asus'
4842
5141
  model_replacement: '$1'
@@ -4877,7 +5176,7 @@ device_parsers:
4877
5176
  ##########
4878
5177
  # htc
4879
5178
  ##########
4880
- - regex: '\b(?:HTC/|HTC/[a-z0-9]+/)?HTC[ _\-;]? *(.*?)(?:-?Mozilla|fingerPrint|[;/\(\)]|$)'
5179
+ - regex: '\b(?:HTC/|HTC/[a-z0-9]+/|)HTC[ _\-;]? *(.*?)(?:-?Mozilla|fingerPrint|[;/\(\)]|$)'
4881
5180
  device_replacement: 'HTC $1'
4882
5181
  brand_replacement: 'HTC'
4883
5182
  model_replacement: '$1'
@@ -4893,6 +5192,10 @@ device_parsers:
4893
5192
  device_replacement: 'Huawei $1'
4894
5193
  brand_replacement: 'Huawei'
4895
5194
  model_replacement: '$1'
5195
+ - regex: 'HUAWEI ([A-Za-z0-9\-]+)'
5196
+ device_replacement: 'Huawei $1'
5197
+ brand_replacement: 'Huawei'
5198
+ model_replacement: '$1'
4896
5199
  - regex: 'vodafone([A-Za-z0-9]+)'
4897
5200
  device_replacement: 'Huawei Vodafone $1'
4898
5201
  brand_replacement: 'Huawei'
@@ -4930,22 +5233,22 @@ device_parsers:
4930
5233
  # HbbTV (European and Australian standard)
4931
5234
  # written before the LG regexes, as LG is making HbbTV too
4932
5235
  ##########
4933
- - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+ \([^;]*; *(LG)E *; *([^;]*) *;[^;]*;[^;]*;\)'
5236
+ - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+ \( ?;(LG)E ?;([^;]{0,30})'
4934
5237
  device_replacement: '$1'
4935
5238
  brand_replacement: '$2'
4936
5239
  model_replacement: '$3'
4937
- - regex: '(HbbTV)/1\.1\.1.*CE-HTML/1\.\d;(Vendor/)*(THOM[^;]*?)[;\s](?:.*SW-Version/.*)*(LF[^;]+);?'
5240
+ - regex: '(HbbTV)/1\.1\.1.*CE-HTML/1\.\d;(Vendor/|)(THOM[^;]*?)[;\s].{0,30}(LF[^;]+);?'
4938
5241
  device_replacement: '$1'
4939
5242
  brand_replacement: 'Thomson'
4940
5243
  model_replacement: '$4'
4941
- - regex: '(HbbTV)(?:/1\.1\.1)?(?: ?\(;;;;;\))?; *CE-HTML(?:/1\.\d)?; *([^ ]+) ([^;]+);'
5244
+ - regex: '(HbbTV)(?:/1\.1\.1|) ?(?: \(;;;;;\)|); *CE-HTML(?:/1\.\d|); *([^ ]+) ([^;]+);'
4942
5245
  device_replacement: '$1'
4943
5246
  brand_replacement: '$2'
4944
5247
  model_replacement: '$3'
4945
5248
  - regex: '(HbbTV)/1\.1\.1 \(;;;;;\) Maple_2011'
4946
5249
  device_replacement: '$1'
4947
5250
  brand_replacement: 'Samsung'
4948
- - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+ \([^;]*; *(?:CUS:([^;]*)|([^;]+)) *; *([^;]*) *;.*;'
5251
+ - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+ \([^;]{0,30}; ?(?:CUS:([^;]*)|([^;]+)) ?; ?([^;]{0,30})'
4949
5252
  device_replacement: '$1'
4950
5253
  brand_replacement: '$2$3'
4951
5254
  model_replacement: '$4'
@@ -4955,7 +5258,7 @@ device_parsers:
4955
5258
  ##########
4956
5259
  # LGE NetCast TV
4957
5260
  ##########
4958
- - regex: 'LGE; (?:Media\/)?([^;]*);[^;]*;[^;]*;?\); "?LG NetCast(\.TV|\.Media)?-\d+'
5261
+ - regex: 'LGE; (?:Media\/|)([^;]*);[^;]*;[^;]*;?\); "?LG NetCast(\.TV|\.Media|)-\d+'
4959
5262
  device_replacement: 'NetCast$2'
4960
5263
  brand_replacement: 'LG'
4961
5264
  model_replacement: '$1'
@@ -4984,7 +5287,7 @@ device_parsers:
4984
5287
  brand_replacement: '$1'
4985
5288
  model_replacement: '$2'
4986
5289
  # other LG phones
4987
- - regex: '\b(?:LGE[ \-]LG\-(?:AX)?|LGE |LGE?-LG|LGE?[ \-]|LG[ /\-]|lg[\-])([A-Za-z0-9]+)\b'
5290
+ - regex: '\b(?:LGE[ \-]LG\-(?:AX|)|LGE |LGE?-LG|LGE?[ \-]|LG[ /\-]|lg[\-])([A-Za-z0-9]+)\b'
4988
5291
  device_replacement: 'LG $1'
4989
5292
  brand_replacement: 'LG'
4990
5293
  model_replacement: '$1'
@@ -5129,7 +5432,7 @@ device_parsers:
5129
5432
  device_replacement: '$2 $1'
5130
5433
  brand_replacement: '$2'
5131
5434
  model_replacement: '$1'
5132
- - regex: '(Sony)(?:BDP\/|\/)?([^ /;\)]+)[ /;\)]'
5435
+ - regex: '(Sony)(?:BDP\/|\/|)([^ /;\)]+)[ /;\)]'
5133
5436
  device_replacement: '$1 $2'
5134
5437
  brand_replacement: '$1'
5135
5438
  model_replacement: '$2'
@@ -5159,27 +5462,33 @@ device_parsers:
5159
5462
  #########
5160
5463
  # Android General Device Matching (far from perfect)
5161
5464
  #########
5162
- - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+) Build[/ ]'
5465
+ - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+)( Build[/ ]|\))'
5163
5466
  brand_replacement: 'Generic_Android'
5164
5467
  model_replacement: '$1'
5165
- - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2} *; *(.+?) Build[/ ]'
5468
+ - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2} *; *(.+?)( Build[/ ]|\))'
5166
5469
  brand_replacement: 'Generic_Android'
5167
5470
  model_replacement: '$1'
5168
- - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{2}[_\-][A-Za-z]{0,2}\-? *; *(.+?) Build[/ ]'
5471
+ - regex: 'Android[\- ][\d]+(?:\.[\d]+)(?:\.[\d]+|); *[A-Za-z]{2}[_\-][A-Za-z]{0,2}\-? *; *(.+?)( Build[/ ]|\))'
5169
5472
  brand_replacement: 'Generic_Android'
5170
5473
  model_replacement: '$1'
5171
- - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{0,2}\- *; *(.+?) Build[/ ]'
5474
+ - regex: 'Android[\- ][\d]+(?:\.[\d]+)(?:\.[\d]+|); *[A-Za-z]{0,2}\- *; *(.+?)( Build[/ ]|\))'
5172
5475
  brand_replacement: 'Generic_Android'
5173
5476
  model_replacement: '$1'
5174
5477
  # No build info at all - "Build" follows locale immediately
5175
- - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[a-z]{0,2}[_\-]?[A-Za-z]{0,2};? Build[/ ]'
5478
+ - regex: 'Android[\- ][\d]+(?:\.[\d]+)(?:\.[\d]+|); *[a-z]{0,2}[_\-]?[A-Za-z]{0,2};?( Build[/ ]|\))'
5176
5479
  device_replacement: 'Generic Smartphone'
5177
5480
  brand_replacement: 'Generic'
5178
5481
  model_replacement: 'Smartphone'
5179
- - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *\-?[A-Za-z]{2}; *(.+?) Build[/ ]'
5482
+ - regex: 'Android[\- ][\d]+(?:\.[\d]+)(?:\.[\d]+|); *\-?[A-Za-z]{2}; *(.+?)( Build[/ ]|\))'
5180
5483
  brand_replacement: 'Generic_Android'
5181
5484
  model_replacement: '$1'
5182
- - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}(?:;.*)?; *(.+?) Build[/ ]'
5485
+ - regex: 'Android \d+?(?:\.\d+|)(?:\.\d+|); ([^;]+?)(?: Build|\) AppleWebKit).+? Mobile Safari'
5486
+ brand_replacement: 'Generic_Android'
5487
+ model_replacement: '$1'
5488
+ - regex: 'Android \d+?(?:\.\d+|)(?:\.\d+|); ([^;]+?)(?: Build|\) AppleWebKit).+? Safari'
5489
+ brand_replacement: 'Generic_Android_Tablet'
5490
+ model_replacement: '$1'
5491
+ - regex: 'Android \d+?(?:\.\d+|)(?:\.\d+|); ([^;]+?)(?: Build|\))'
5183
5492
  brand_replacement: 'Generic_Android'
5184
5493
  model_replacement: '$1'
5185
5494
 
@@ -5224,9 +5533,9 @@ device_parsers:
5224
5533
  model_replacement: 'Smartphone'
5225
5534
 
5226
5535
  ##########
5227
- # Spiders (this is hack...)
5536
+ # Spiders (this is a hack...)
5228
5537
  ##########
5229
- - regex: '(bot|BUbiNG|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Daum|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.*/\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler|Pingdom|StatusCake|WhatsApp|masscan|Google Web Preview|Qwantify|Yeti)'
5538
+ - regex: '(bot|BUbiNG|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Daum|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.*/\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler|Pingdom|StatusCake|WhatsApp|masscan|Google Web Preview|Qwantify|Yeti|OgScrper)'
5230
5539
  regex_flag: 'i'
5231
5540
  device_replacement: 'Spider'
5232
5541
  brand_replacement: 'Spider'
@@ -5265,3 +5574,14 @@ device_parsers:
5265
5574
  device_replacement: 'Generic Feature Phone'
5266
5575
  brand_replacement: 'Generic'
5267
5576
  model_replacement: 'Feature Phone'
5577
+
5578
+ #########
5579
+ # Apple
5580
+ # @ref: https://www.apple.com/mac/
5581
+ # @note: lookup Mac OS, but exclude iPad, Apple TV, a HTC phone, Kindle, LG
5582
+ # @note: put this at the end, since it is hard to implement contains foo, but not contain bar1, bar 2, bar 3 in go's re2
5583
+ #########
5584
+ - regex: 'Mac OS'
5585
+ device_replacement: 'Mac'
5586
+ brand_replacement: 'Apple'
5587
+ model_replacement: 'Mac'