【问题标题】:Specific domain URL validation with Regular Expression使用正则表达式的特定域 URL 验证
【发布时间】:2009-07-02 14:00:47
【问题描述】:

我一直在尝试自己,并在网上搜索,写这个正则表达式但没有成功。

我需要验证给定 URL 是否来自特定域和格式正确的链接(在 PHP 中)。例如:

好域名:example.com

example.com 的 URL 非常好:

不是来自 example.com 的糟糕 URL:

一些注意事项: 我不在乎“http”与“https”,但如果对您很重要,请始终假设“http” 将使用此正则表达式的代码是 PHP,所以要加分。

2010 年更新:

Gruber 添加了一个很棒的 URL 正则表达式:

?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))

查看他的帖子:An Improved Liberal, Accurate Regex Pattern for Matching URLs

【问题讨论】:

  • 您的“Good Domain”示例不是有效的 URL(缺少路径)。
  • @Nikolar Ruhe:路径实际上是可选的:"http://" hostport [ "/" hpath [ "?"搜索 ]](参见 RFC 1738)
  • 这并不表示有效的 URL,而是表示示例 URL 使用的有效域,但也许我应该只说“blah.com”,仅此而已。无论哪种方式,我都认为这是有道理的。
  • example.com:25 是好是坏?还有user@example.com ?

标签: php regex


【解决方案1】:

你必须使用正则表达式吗? PHP 有很多内置函数可以做这种事情。

filter_var($url, FILTER_VALIDATE_URL)

会告诉你一个 URL 是否有效,并且

    $domain = parse_url($url, PHP_URL_HOST);

会告诉你它所指的域。

它可能比一些疯狂的正则表达式更清晰,更易于维护。

【讨论】:

    【解决方案2】:

    我的努力

    <?php
    
    $pattern = "#^https?://([a-z0-9-]+\.)*blah\.com(/.*)?$#";
    
    $tests = array(
        'http://blah.com/so/this/is/good'
      , 'http://blah.com/so/this/is/good/index.html'
      , 'http://www.blah.com/so/this/is/good/mice.html#anchortag'
      , 'http://anysubdomain.blah.com/so/this/is/good/wow.php'
      , 'http://anysubdomain.blah.com/so/this/is/good/wow.php?search=doozy'
      , 'http://any.sub-domain.blah.com/so/this/is/good/wow.php?search=doozy' // I added this case
      , 'http://999.sub-domain.blah.com/so/this/is/good/wow.php?search=doozy' // I added this case
      , 'http://obviousexample.com'
      , 'http://bbc.co.uk/blah.com/whatever/you/get/the/idea'
      , 'http://blah.com.example'
      , 'not/even/a/blah.com/url'
    );
    
    foreach ( $tests as $test )
    {
      if ( preg_match( $pattern, $test ) )
      {
        echo $test, " <strong>matched!</strong><br>";
      } else {
        echo $test, " <strong>did not match.</strong><br>";
      }
    }
    
    //  Here's another way
    echo '<hr>';
    foreach ( $tests as $test )
    {
      if ( $filtered = filter_var( $test, FILTER_VALIDATE_URL ) )
      {
        $host = parse_url( $filtered, PHP_URL_HOST );
        if ( $host && preg_match( "/blah\.com$/", $host ) )
        {
          echo $filtered, " <strong>matched!</strong><br>";
        } else {
          echo $filtered, " <strong>did not match.</strong><br>";
        }
      } else {
        echo $test, " <strong>did not match.</strong><br>";
      }
    }
    

    【讨论】:

    • parse_url 函数的文档声明它并不意味着验证 URL:无效的 URL 仍可能被解析。所以你需要一些额外的检查。
    • 哦,我同意 - 它可能需要更严格的测试。不过,我的正则表达式解决方案同样有效。
    • 我在我的第二个算法中采用了你的帖子的逻辑。看起来效果不错!
    • Brilliant Peter :) - 正是我想要的。
    【解决方案3】:

    也许:

    ^https?://[^/]*blah\.com(|/.*)$
    

    编辑:

    防止http://editblah.com

    ^https?://(([^/]*\.)|)blah\.com(|/.*)$
    

    【讨论】:

    • 关闭!但这会误报像 fooblah.com 这样的域
    【解决方案4】:
    \b(https?)://([-A-Z0-9]+\.)*blah.com(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:,.;]*)?
    

    【讨论】:

    【解决方案5】:
    !^https?://(?:[a-zA-Z0-9-]+\.)*blah\.com(?:/[^#]*(?:#[^#]+)?)?$!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      相关资源
      最近更新 更多