我真的不知道我需要修复这个问题,但是我试图从以下浏览器用户中提取操作系统,操作系统版本以及iPhone,Macintosh等品牌:
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.34 (KHTML, like Gecko) Dooble/1.40 Safari/534.34
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A
Mozilla/5.0 (iPhone; U; CPU like Mac OS X) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; tr-TR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Linux; U; Android 2.2.1; zh-tw; HTC_Sensation_S710e Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; nl) AppleWebKit/522.13.1 (KHTML, like Gecko) Version/3.0.2 Safari/522.13.1
Mozilla/5.0 (BlackBerry; U; BlackBerry 9700; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.380 Mobile Safari/534.8+
我不知道我是否需要match_all,match,replace,split。 字符串并不完全相同,我正在尝试以下正则表达式:
preg_match_all('/\((.*?);|\((.*?)\) AppleWebKit/im', $user_agent, $brandmatch, PREG_PATTERN_ORDER);
哪个有这个结果,这很好:
Macintosh
iPhone
Macintosh
Windows
Linux
Windows
BlackBerry
Windows NT 5.1
preg_match_all('/\(.*?; (.*?)\)/im', $user_agent, $brandmatch, PREG_PATTERN_ORDER);
结果如下:(我希望1 - 6变得像0)
0 => Intel Mac OS X 10_9_3
1 => U; CPU like Mac OS X
2 => U; Intel Mac OS X 10_6_8; de-at
3 => U; Windows NT 6.1; tr-TR
4 => U; Android 2.2.1; zh-tw; HTC_Sensation_S710e Build/FRG83D
5 => U; Windows NT 6.0; nl
6 => U; BlackBerry 9700; en-US
所以我尝试了以下内容:
preg_match_all('/U; (.*?);/im', $user_agent, $brandmatch, PREG_PATTERN_ORDER);
结果如下:(它比上面的2还少,这很糟糕)
0 => Intel Mac OS X 10_6_8
1 => Windows NT 6.1
2 => Android 2.2.1
3 => Windows NT 6.0
4 => BlackBerry 9700
所以我要做的是:我想要OS + OS版本。我也尝试过:
\(.*?; (.*?)\)|U; (.*?);
结果如下:
0 => Intel Mac OS X 10_9_3
1 => U; CPU like Mac OS X
2 => U; Intel Mac OS X 10_6_8; de-at
3 => U; Windows NT 6.1; tr-TR
4 => U; Android 2.2.1; zh-tw; HTC_Sensation_S710e Build/FRG83D
5 => U; Windows NT 6.0; nl
6 => U; BlackBerry 9700; en-US
所以我需要的结果是:
0 => Intel Mac OS X 10_9_3
1 => CPU like Mac OS X
2 => Intel Mac OS X 10_6_8
3 => Windows NT 6.1
4 => Android 2.2.1
5 => Windows NT 6.0
6 => BlackBerry 9700
答案 0 :(得分:2)
您可以使用此正则表达式:
/^\S+ +\((?:[^;\n]*;)?(?: U; )?([^;)]+)/m
(
,然后匹配0个或多个字符,直到换行符或;
后跟;
。U;
)
或;
答案 1 :(得分:2)
分支重置功能可能会让您感兴趣,因为它允许多个备选方案,但每个备选方案与其他方案共享相同的捕获组。
分支重置是这样的:
(?|alternat(ive1)|alternati(ve2)|alternat(ive3)|e(tc.))
您可以看到四个捕获组,但在此构造中,捕获组是相同的(因此只定义了一个捕获组,其内容取决于成功的分支)。
对于你的问题,你可以尝试写这样的东西:
~^[^(]*\((?|[^);]*;(?: U;)? ([^;)]+)|([^)]+))~m
您需要的只是提取捕获组1
另一种方式:使用\K
功能
\K
从匹配结果中删除之前匹配的所有内容。因此无需定义捕获组,整个匹配可以是结果:
~^[^(]*\((?:[^);]*;(?: U;)? \K[^;)]+|\K[^)]+)~m
但是有一个更轻松的方法:让第一个轮换的开始可选并删除第二个:
^[^(]*\((?:[^);]*;(?: U;)? )?\K[^;)]+~m