我有一个这样的网址:
我想将该网址拆分为仅获取主机部分。为此,我正在使用
parse_url($url,PHP_URL_HOST);
它返回www.w3schools.com。 我想只获得'w3schools.com'。 是否有任何功能或我必须手动完成?
答案 0 :(得分:6)
有很多方法可以做到这一点。如果您知道总是想要剥离“www。”
,那么简单的替换是最快的$stripped=str_replace('www.', '', $domain);
正则表达式替换允许您将该匹配绑定到字符串的开头:
$stripped=preg_replace('/^www\./', '', $domain);
如果它始终是域的第一部分,无论其是否为www,您都可以使用explode / implode。虽然它很容易阅读,但它是效率最低的方法:
$parts=explode('.', $domain);
array_shift($parts); //eat first element
$stripped=implode('.', $parts);
正则表达式可以更有效地实现相同的目标:
$stripped=preg_replace('/^\w+\./', '', $domain);
现在您可能会想到以下内容比上述正则表达式更有效:
$period=strpos($domain, '.');
if ($period!==false)
{
$stripped=substr($domain,$period+1);
}
else
{
$stripped=$domain; //there was no period
}
但我对它进行了基准测试,发现超过一百万次迭代,preg_replace
版本始终如一地击败它。典型结果,归一化为最快(因此它的无单位时间为1):
/^\w+\./
:1.494 以上代码示例总是剥离第一个域组件,因此可以在“www.example.com”和“www.example.co.uk”等域上正常工作,但不能“example.com”或“www。 department.example.com”。如果您需要处理可能已经是主域的域,或者有多个子域(例如“foo.bar.baz.example.com”)并希望将它们简化为主域(“example.com”) ,尝试以下。每种方法中的第一个样本仅返回最后两个域组件,因此不适用于“co.uk”类域。
explode
:
$parts = explode('.', $domain);
$parts = array_slice($parts, -2);
$stripped = implode('.', $parts);
由于explode
始终是最慢的方法,因此编写处理“co.uk”的版本没什么意义。
正则表达式:
$stripped=preg_replace('/^.*?([^.]+\.[^.]*)$/', '$1', $domain);
这将捕获域中的最后两个部分,并用捕获的部分替换完整的字符串值。对于多个子域,所有主要部分都将被剥离。
要使用“.co.uk”类似的域以及可变数量的子域,请尝试:
$stripped=preg_replace('/^.*?([^.]+\.(?:[^.]*|[^.]{2}\.[^.]{2}))$/', '$1', $domain);
STR:
$end = strrpos($domain, '.') - strlen($domain) - 1;
$period = strrpos($domain, '.', $end);
if ($period !== false) {
$stripped = substr($domain,$period+1);
} else {
$stripped = $domain;
}
允许co.uk域名:
$len = strlen($domain);
if ($len < 7) {
$stripped = $domain;
} else {
if ($domain[$len-3] === '.' && $domain[$len-6] === '.') {
$offset = -7;
} else {
$offset = -5;
}
$period = strrpos($domain, '.', $offset);
if ($period !== FALSE) {
$stripped = substr($domain,$period+1);
} else {
$stripped = $domain;
}
}
通过牺牲边缘情况(主域组件是单个字母,例如“a.com”),可以使得基于正则表达式和str的实现速度更快一些:
正则表达式:
$stripped=preg_replace('/^.*?([^.]{3,}\.(?:[^.]+|[^.]{2}\.[^.]{2}))$/', '$1', $domain);
STR:
$period = strrpos($domain, '.', -7);
if ($period !== FALSE) {
$stripped = substr($domain,$period+1);
} else {
$stripped = $domain;
}
虽然行为发生了变化,但排名并非(大部分时间)。他们在这里,时间标准化为最快。
在这里,时间之间的差异非常小,以至于并不罕见。例如,快速.co.uk正则表达式经常击败基本的多子域正则表达式。因此,确切的实施不应对速度产生明显影响。相反,选择一个基于简单性和清晰度。只要您不需要处理.co.uk域,那就是多子域正则表达式方法。
答案 1 :(得分:0)
您必须自己剥离子域部分 - 没有内置函数。
// $domain beeing www.w3scools.com
$domain = implode('.', array_slice(explode('.', $domain), -2));
以上示例也适用于无限深度的子域,因为它将返回最后两个域部分(域和顶级域)。
如果您只想剥离 www。,您只需执行str_replace()
,这样会更快:
$domain = str_replace('www.', '', $domain);
答案 2 :(得分:0)
当且仅当返回的字符串中出现[。]超过1次时,您需要在[。]字符的第一个出现之前删除任何字符(以及[。]本身)。
例如,如果返回的字符串是www-139.in.ibm.com,则正则表达式应该返回in.ibm.com,因为那将是域。
如果返回的字符串是music.domain.com,则正则表达式应返回domain.com
在极少数情况下,您可以访问没有服务器前缀的站点,您可以使用http://domain.com/pageurl访问该站点,在这种情况下,您可以直接将域名作为domain.com获取,在这种情况下,正则表达式不应剥离任何东西
IMO这应该是正则表达式的伪逻辑,如果你想我可以为你形成一个包含这些东西的正则表达式。