【问题标题】:Regular expression pattern to match URL with or without http://www正则表达式模式匹配带有或不带有 http://www 的 URL
【发布时间】:2014-01-25 07:05:27
【问题描述】:

我一点也不擅长正则表达式。

到目前为止,我一直在使用很多框架代码,但我找不到一个能够匹配像 http://www.example.com/etcetc 这样的 URL,但它也能够捕获像 www.example.com/etcetcexample.com/etcetc.

【问题讨论】:

  • 这个问题可能会对您有所帮助。 stackoverflow.com/questions/1141848/regex-to-match-url
  • 前两个选项可以匹配,但匹配最后一个 example.com/etcetc 几乎是不可能的。你基本上只需要匹配中间有一个点的任何东西。
  • @Balanivash - 将其标记为已关闭问题的副本有点苛刻。
  • 就像我直到昨天才回答这样的问题,但是如果今天存在任何这样的问题被要求标记为重复,这就是为什么这样做。

标签: php regex


【解决方案1】:

如果您想确保 URL 以 HTTP/HTTPS 开头,则使用正则表达式:

https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)

如果您不需要 HTTP 协议:

[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)

【讨论】:

    【解决方案2】:

    这个 PHP Composer 包 URL highlight 在 PHP 中做得很好:

    <?php
        use VStelmakh\UrlHighlight\UrlHighlight;
    
        $urlHighlight = new UrlHighlight();
        $matches = $urlHighlight->getUrls($string);
    ?>
    

    【讨论】:

      【解决方案3】:

      我一直在使用以下内容,它适用于我的所有测试用例,并修复了它会在句尾以句号 (end.) 开头的句子结尾触发的任何问题,或者有单字符首字母,例如 'CC管道'。

      下面的正则表达式包含多个{2,}s,表示两个或多个匹配上一个模式。

      ((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]{2,}\.([a-zA-Z0-9\&\.\/\?\:@\-_=#]){2,}
      

      匹配 URL,例如但不限于:

      不匹配非网址,例如但不限于:

      • C.C 水管工
      • 句末句号。
      • 单个字符,例如a.bx.y

      请注意:由于上述原因,这个不会匹配任何单个字符的网址,例如:a.co,但如果它前面有一个 URL 方案,例如:http://a.co

      【讨论】:

        【解决方案4】:

        由于最近的 PHP 允许在字符串中使用 $ 并且 preg 匹配不起作用,我在让 the answer from anubhava 工作时遇到了很多问题。

        这是我使用的:

        // Regular expression
        $re = '/((https?|ftp):\/\/)?([a-z0-9+!*(),;?&=.-]+(:[a-z0-9+!*(),;?&=.-]+)?@)?([a-z0-9\-\.]*)\.(([a-z]{2,4})|([0-9]{1,3}\.([0-9]{1,3})\.([0-9]{1,3})))(:[0-9]{2,5})?(\/([a-z0-9+%-]\.?)+)*\/?(\?[a-z+&$_.-][a-z0-9;:@&%=+\/.-]*)?(#[a-z_.-][a-z0-9+$%_.-]*)?/i';
        // Match all
        preg_match_all($re, $blob, $matches, PREG_SET_ORDER, 0);
        // Print the entire match result
        var_dump($matches);
        // The first element of the array is the full match
        

        【讨论】:

          【解决方案5】:

          你可以试试这个:

          r"(http[s]:\/\/)?([\w-]+\.)+([a-z]{2,5})(\/+\w+)? "
          

          选择:

          1. 可以以 http:// 或 https:// 开头(可选)

          2. 任何东西(单词)都以点 (.) 结尾

          3. 后跟 2 到 5 个字符 [a-z]

          4. 后跟“/[anything]”(可选)

          5. 后跟空格

          【讨论】:

            【解决方案6】:

            用途:

            /(https?://)?((?:(\w+-)*\w+)\.)+(?:[a-z]{2})(\/?\w?-?=?_?\??&?)+[\.]?([a-z0-9\?=&_\-%#])?/g
            

            它匹配something.comhttp(s)://www。虽然它与其他 [something]:// URL 不匹配,但出于我的目的,这不是必需的。

            正则表达式匹配例如:

            http://foo.co.uk/
            www.regex.com/foo.html?q=bar$some=thi-ng,regex
            regex.foo.com/blog
            

            【讨论】:

              【解决方案7】:

              这在我测试过的所有情况下都对我有用:

              $url_pattern = '/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/';
              

              测试:

              http://test.test-75.1474.stackoverflow.com/
              https://www.stackoverflow.com
              https://www.stackoverflow.com/
              http://wwww.stackoverflow.com/
              http://wwww.stackoverflow.com
              
              
              http://test.test-75.1474.stackoverflow.com/
              http://www.stackoverflow.com
              http://www.stackoverflow.com/
              stackoverflow.com/
              stackoverflow.com
              
              http://www.example.com/etcetc
              www.example.com/etcetc
              example.com/etcetc
              user:pass@example.com/etcetc
              
              example.com/etcetc?query=aasd
              example.com/etcetc?query=aasd&dest=asds
              
              http://stackoverflow.com/questions/6427530/regular-expression-pattern-to-match-url-with-or-without-http-www
              http://stackoverflow.com/questions/6427530/regular-expression-pattern-to-match-url-with-or-without-http-www/
              

              每个有效的 Internet URL 都至少有一个点,因此上述模式将简单地尝试查找任何至少两个由点链接的字符串,并且该 URL 可能具有有效的字符。

              【讨论】:

              • 稍微简化了这个正则表达式:/^[a-z0-9./?:@\-_=#]+\.([a-z0-9./?:@\-_=#])*$/i - 元字符不需要在方括号内转义 - 去掉前面的可选部分,不需要验证 url(在 don'在我的用例中不需要捕获的值)- 使用无大小写修饰符的简化模式,而不是重复字符组中的所有内容
              • 另一个小故障:上面的正则表达式不适用于包含参数(因此也是 &)的 url。也不支持编码参数 - % 符号。
              • /(http|https)\:\/\/+[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a -zA-Z0-9\&\.\/\?\:@\-_=#])*/ 请使用 + 而不是 ?在 (http|https)\:\/\/ 之后为 ?也通过了 http:/ 所以这种方式 http:/yahoo.com 是正确的,但实际上并非如此。添加+号将解决它。
              • 从原始模式中,我只用+ 替换了最后一个*,以避免word. 之类的字符串与表达式匹配。只有像 word.com 这样的字符串应该匹配。
              • 最后,我发现用{2,} 替换最后一个* 更好。
              【解决方案8】:

              如果它不必是正则表达式,您总是可以使用 PHP 中的 validate 过滤器。

              filter_var('http://example.com', FILTER_VALIDATE_URL);
              

              filter_var (mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]]);

              Types of Filters

              Validate Filters

              【讨论】:

              • 这似乎是我尝试时期望该 URL 有协议?
              • 将值验证为 URL(根据 faqs.org/rfcs/rfc2396),可选择使用必需的组件。请注意,有效的 URL 可能未指定 HTTP 协议 http://,因此可能需要进一步验证以确定 URL 使用预期的协议,例如ssh:// 或 mailto:。请注意,该函数只会查找有效的 ASCII URL;国际化域名(包含非 ASCII 字符)将失败。 -- 但是,由于它是内置于 PHP 中的,您可以期待它稍后会升级和更新以变得更有用。
              【解决方案9】:

              您可以在正则表达式后使用问号使其有条件,因此您可以使用:

              http:\/\/(www\.)?
              

              这将匹配具有 http://www 的任何内容。或 http://(没有 www.)

              您可以只使用替换方法来删除上述内容,从而获得域。这取决于您需要该域的用途。

              【讨论】:

                【解决方案10】:

                为了匹配所有类型的 URL,下面的代码应该可以工作:

                <?php
                    $regex = "((https?|ftp)://)?"; // SCHEME
                    $regex .= "([a-z0-9+!*(),;?&=$_.-]+(:[a-z0-9+!*(),;?&=$_.-]+)?@)?"; // User and Pass
                    $regex .= "([a-z0-9\-\.]*)\.(([a-z]{2,4})|([0-9]{1,3}\.([0-9]{1,3})\.([0-9]{1,3})))"; // Host or IP
                    $regex .= "(:[0-9]{2,5})?"; // Port
                    $regex .= "(/([a-z0-9+$_%-]\.?)+)*/?"; // Path
                    $regex .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+/$_.-]*)?"; // GET Query
                    $regex .= "(#[a-z_.-][a-z0-9+$%_.-]*)?"; // Anchor
                ?>
                

                那么,检查正则表达式的正确方法如下:

                <?php
                   if(preg_match("~^$regex$~i", 'www.example.com/etcetc', $m))
                      var_dump($m);
                
                   if(preg_match("~^$regex$~i", 'http://www.example.com/etcetc', $m))
                      var_dump($m);
                ?>
                

                礼貌: splattermania 在 PHP 手册中的评论:http://php.net/manual/en/function.preg-match.php

                RegEx Demo in regex101

                【讨论】:

                • +1 方法内的评论通常是代码异味的标志。但是,评论 in 正则表达式或复杂的 SQL 查询是可行的方法。
                • @Toto 我意识到存在争议,例如programmers.stackexchange.com/questions/1/…,但我真的无法理解 cmets 在任何情况下都是代码异味,除非 cmets 与代码不匹配.
                • 嗨,由于 youtube 之类的链接,我不得不在每个 a-z 旁边添加 A-Z。但我认为它仍然很棒
                • 我喜欢你用 cmets 分解它的方式。这有点像正则表达式自助餐,您可以在其中挑选要放在盘子上的东西
                • 如果你说试试看,我确信它会起作用,因为你不会犯错:)。谢谢阿努巴,它现在可以工作了,这就是我问你的原因:)。 +1
                【解决方案11】:

                试试这个:

                /^http:\/\/|(www\.)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/

                它完全按照人们想要的方式工作。

                不管有没有http://https://www

                【讨论】:

                  【解决方案12】:

                  试试这个

                  $url_reg = /(ftp|https?):\/\/(\w+:?\w*@)?(\S+)(:[0-9]+)?(\/([\w#!:.?+=&%@!\/-])?)?/;
                  

                  【讨论】:

                  • 这个表达式对除了那些误用 www 的表达式之外的所有表达式都有效。例如example.com/khafenxj
                  • 有没有办法制作“www.”部分也是可选的?,我对正则表达式了解一点,但我仍然觉得阅读起来很复杂,哈哈
                  • 这不应该适用于任何错过 http:// 的东西,或者任何其他错过协议的东西。
                  【解决方案13】:

                  试试这样的:

                  .*([\w-]+\.)+[a-z]{2,5}(/[\w-]+)*
                  

                  【讨论】:

                    猜你喜欢
                    • 2011-03-27
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-04-24
                    • 2016-07-26
                    • 1970-01-01
                    • 2017-06-21
                    • 2014-05-07
                    相关资源
                    最近更新 更多