【问题标题】:RegEx Result Differ Between a 6 Character and a 7(+) Character Domain6 个字符和 7(+) 个字符域之间的正则表达式结果不同
【发布时间】:2016-11-23 23:14:15
【问题描述】:

我有一个非常简单的函数来获取 URL 的域。我从返回的字符串中寻找的只是域名(不是“www.example.com”,而是“example.com”)。

我正在测试该功能,除了长度小于 7 个字符的域外,它似乎没问题。

这是我的示例输入和输出:

输入:http://www.example.com/asdf.html -- 输出:example.com

输入:http://www.1234.com/asdf -- 输出:1234.com

输入:http://www.exampl.com/asdf -- 输出 www.exampl.com

让我失望的是最后一个输入/输出。我不明白为什么当域少于 7 个字符时函数会返回 www.

代码如下:

function getDomain($url = STR_EMP) {
    preg_match("/[a-zA-Z0-9\-\_]{1,63}\.[a-z\.]{2,10}$/", parse_url($url, PHP_URL_HOST), $_domain_tld);
    return $_domain_tld[0];
}


$url1 = "http://www.example.com/asdf.html"; // example.com
$url2 = "http://www.1234.com/asdf"; //1234.com
$url3 = "http://www.exampl.com/asdf"; // www.exampl.com

var_dump(getDomain($url1), getDomain($url2), getDomain($url3));

(输出)

string(11) "example.com"
string(8) "1234.com"
string(14) "www.exampl.com"

我不是 RegEx 的专家,但看起来 6 个字母的域符合表达式中的 {1,63} 标准。有人可以解释为什么 6 字符 www.exampl.com 域返回 www. 吗?

有没有我可以使用的 RegEx 来防止较短的 URL 出现这种情况?

提前致谢。

更新:

域的标准:

some.site.com 应该输出site.com

a.nother.site.com 也应该输出site.com

【问题讨论】:

  • 首先,正确转义正则表达式
  • 您的预期输出标准是什么?如果输入是some.site.com,你想要site.com 还是some.site.com(应该只去掉www.)? a.longer.one.com 呢?你想要one.com吗? longer.one.com?
  • 我想要site.comone.com,对不起。
  • 我会试试@anubhava 谢谢

标签: php regex


【解决方案1】:

不要把你的生活过度复杂化,把getDomain改成

function getDomain($url = STR_EMP) {
    $parse = parse_url($url);
    return str_ireplace('www.', '', $parse['host']);;
}

现在的输出是:

string(11) "example.com"
string(8) "1234.com"
string(10) "exampl.com"

关于你的正则表达式,这不仅是一个长度问题,也是一个字符类问题demo here


关于您的编辑的更新,您可以使用此代码:

function getDomain($url = STR_EMP) {
    preg_match("/[\\w-]{1,63}\\.[a-z]{2,10}$/", parse_url($url, PHP_URL_HOST), $_domain_tld);
    return $_domain_tld[0];
}


$url1 = "http://www.example.com/asdf.html";
$url2 = "http://www.1234.com/asdf";
$url3 = "http://www.exampl.com/asdf";
$url4 = "http://a.nother.site.com";

var_dump(getDomain($url1), getDomain($url2), getDomain($url3), getDomain($url4));

我在其中更新了正则表达式以仅匹配 TLD 的最后一部分。

它产生:

string(11) "example.com"
string(8) "1234.com"
string(10) "exampl.com"
string(8) "site.com"

【讨论】:

  • 我在上面添加了更多信息...但是使用此功能,http://asdfasdf.example.com/asdf 给了我asdfasdf.example.com 的输出,我只是在寻找example.com
  • 这似乎是在正确的轨道上,但如果我输入www.exampl.co.uk,它只会返回co.uk。我注意到您从[a-z\.]{2,10} 部分中删除了\.。这适用于大多数情况@Thomas Ayoub
  • @TJB4rn3s 你将如何处理www.to.us vs www.example.co.uk
  • 我只想要to.usexample.co.uk
  • @TJB4rn3s 请阅读List of TLDlist of SLD(如.co.uk)和记录Single-letter second-level domain。你确定你已经准备好开发一个真正的防弹解决方案了吗?
【解决方案2】:

您的正则表达式匹配像 www.exampl.com 这样的短域:

www         [a-zA-Z0-9\-\_]{1,63}
.           \.
exampl.com  [a-z\.]{2,10}$

www.example.com 等较长的域,其中只有最后一部分符合 [a-z\.]{2,10} 的 10 个字符限制,匹配为:

www         NOT MATCHED
.           NOT MATCHED
example     [a-zA-Z0-9\-\_]{1,63}
.           \.
com         [a-z\.]{2,10}$

这些发生是因为正则表达式会尽可能早地进行匹配,所以只要有可能,www 就会被包含在内。

如果您通常想返回最后两个部分,但对于一些特殊情况(如 co.uk),则返回最后 3 个,您可以使用以下操作。但由于这需要在正则表达式中列出所有二级域,所以这不是一个好的解决方案。

'/[\w-]+\.(co\.uk|[a-z]+)$/'

【讨论】:

  • 哥们!我没有想到与较短域匹配的 {2,10} 标准......有道理,谢谢。我要将此标记为答案,因为您指出了这一点,但我根据此示例完全修改了 getDomain 函数gist.github.com/pocesar/5366899
猜你喜欢
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
  • 1970-01-01
  • 2012-05-30
相关资源
最近更新 更多