【问题标题】:Regex to match URL正则表达式匹配 URL
【发布时间】:2009-07-17 07:32:24
【问题描述】:

我正在使用以下正则表达式来匹配 URL:

$search  = "/([\S]+\.(MUSEUM|TRAVEL|AERO|ARPA|ASIA|COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|AC|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|au|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BL|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|EH|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|IO|IQ|IR|IS|IT|JE|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MF|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TL|TM|TN|TO|R|H|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|YU|ZA|ZM|ZW)([\S]*))/i";

但它有点搞砸了,因为它也匹配我不想要的“abc.php”。和 abc...test 之类的东西。我希望它与 abc.com 匹配。和 www.abc.com 以及 http://abc.com。

最后只需要稍作调整,但我不确定是什么。 (它现在不检查的任何域名后面应该有一个斜杠,它只检查 \S)

感谢您的宝贵时间。

【问题讨论】:

    标签: regex


    【解决方案1】:
    $search  = "#^((?#
        the scheme:
      )(?:https?://)(?#
        second level domains and beyond:
      )(?:[\S]+\.)+((?#
        top level domains:
      )MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|(?#
      )COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|(?#
      )A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|(?#
      )C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|(?#
      )E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|(?#
      )H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|(?#
      )K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|(?#
      )N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|(?#
      )S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|(?#
      )U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(?#
        the path, can be there or not:
      )(/[a-z0-9\._/~%\-\+&\#\?!=\(\)@]*)?)$#i";
    

    刚刚清理了一下。这将匹配仅 HTTP(s) 地址,并且,只要您从 IANA 正确复制所有顶级域,只有那些标准化的(它将不匹配 http://localhost ) 和 声明了 http://。

    最后你应该以路径部分结束,如果它存在的话,它总是以 / 开头。

    不过,我建议您关注 Cerebrus:如果您对此不确定,请以更温和的方式学习正则表达式,并将经过验证的模式用于复杂的任务。

    干杯,

    顺便说一句:您的正则表达式还将匹配something.r 和something.h(在您的示例中,介于|TO| 和|TR| 之间)。我在我的版本中省略了它们,因为我猜这是一个错字。

    重新阅读问题时:更改

      )(?:https?://)(?#
    

    到

      )(?:https?://)?(?#
    

    (有一个 ? 额外)匹配没有方案的“URL”。

    【讨论】:

    • 但我不希望一开始的 http:// 是强制性的。因为我希望它也匹配“abc.com”。
    • 您能否将 [\S]* 改进为可能没有空格 + 只有单词 + 只有数字或 URL 中允许的任何内容?
    • \S 永远不应匹配空格...我将其更新为 Wikipedia en.wikipedia.org/wiki/How_to_edit#Links_and_URLs 在其 URL 中允许的内容。这看起来很合理。
    • :-) 是的,不幸的是所有其他通用 TLD。这将使没有自然语言处理的自动链接检测几乎不可能......
    • 是的,我怀疑这会捕获所有像 big.wong 这样的开放域 tld
    【解决方案2】:

    不完全是 OP 所要求的,但这是一个更简单的正则表达式,不需要在 IANA 每次引入新 TLD 时进行更新。我相信这更适合大多数简单的需求:

    ^(?:https?://)?(?:[\w]+\.)(?:\.?[\w]{2,})+$
    

    没有TLD列表,本地主机不匹配,子部分的数量必须> = 2并且每个子部分的长度必须> = 2(fx:“a.a”将不匹配但“a.ab”将匹配)。

    【讨论】:

    • 所以这与 url 的路径和查询参数部分不匹配?
    • 也无法匹配 URL 中的连字符。
    • 您需要在https?:// 中转义斜线,但它仍然过于宽泛。你可以在这里测试它:regexr.com
    【解决方案3】:

    这个问题很难找到答案。我发现的正则表达式太复杂而难以理解,而任何更多的正则表达式都是矫枉过正且难以实现的。

    终于想出来了:

    /(\S+\.(com|net|org|edu|gov)(\/\S+)?)/
    

    适用于http://example.com、https://example.com、example.com、http://example.com/foo。

    解释:

    • 查找 .com 等。
    • 将其前面的所有内容与空格匹配
    • 匹配后面的所有内容到空格

    【讨论】:

    • 如果出现像“.com”这样的字符串但不属于域的一部分(如在“example.zork/foo/.com/bar”中)也将匹配,并省略所有特定于县的顶级域(如.uk、.ca 等)等。
    【解决方案4】:

    这将获取完整的任何 url,包括 ?= 和 #/ 如果它们存在:

    /[A-Za-z]+:\/\/[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_:%&;\?\#\/.=]+/g
    

    【讨论】:

    • 也匹配hap://foo.com/ :)
    • 这省略了一些允许的字符,例如撇号、!、双引号和加号;和 % 仅在后跟 2 个十六进制数字时才允许使用。更不用说国际化的 URIS (IRI)/.
    【解决方案5】:

    使用单个正则表达式来匹配 URL 字符串会使代码难以理解。我建议使用parse_url 将 URL 拆分为其组件(这不是一项简单的任务),并使用正则表达式检查每个部分。

    【讨论】:

      【解决方案6】:

      将正则表达式的结尾更改为(/\S*)?)$ 应该可以解决您的问题。

      解释它在做什么 -

      • 它正在寻找/ 后跟一些字符(不是空格)
      • 此匹配是可选的,? 表示 0 或 1 次
      • 最后应该跟一个字符串结尾(或将其更改为\b 以匹配单词边界)。

      【讨论】:

        【解决方案7】:

        我觉得这个简单高效/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/

        【讨论】:

          【解决方案8】:

          $ :美元表示字符串的结尾。
          例如 \d*$ 将匹配以数字结尾的字符串。 所以你需要添加 $!

          【讨论】:

            【解决方案9】:

            匹配所有 url 的正则表达式(带 www、不带 www、带 http 或 https、不带 http 或 https,包括所有 2-6 个字母的顶级域名 [for countries, ex 'ly','us']、ports 、查询字符串和锚点 ['#'])。 这不是 100%,但它比我在网上看到的任何东西都要好。

            它使用第一个答案中的顶级域,并结合了我搜索中发现的其他技术。它将返回任何有边界的有效 url,这就是 \b 发挥作用的地方。由于尾随 '/' 也是由 \b 触发的,所以最后一个匹配一个或多个 '?'。

            /\b((http(s?):\/\/)?([a-z0-9\-]+\.)+(MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(:[0-9]{1,5})?((\/([a-z0-9_\-\.~]*)*)?((\/)?\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)/gi
            

            【讨论】:

            • 什么是“/?”意思是接近正则表达式的末尾?您是说“\/”吗?
            • 似乎不适用于“s3.amazonaws.com/plivocloud/…”之类的东西
            【解决方案10】:

            这是唯一的:

            _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS
            

            【讨论】:

              【解决方案11】:

              试试Regexy::Web::Url

              r = Regexy::Web::Url.new # matches 'http://foo.com', 'www.foo.com' and 'foo.com'

              【讨论】:

                【解决方案12】:
                [ftp:\/\/www\/.-https:\/\/-http:\/\/][a-zA-Z0-9u00a1-uffff0]{1,3}[^ ]{1,1000} 
                

                这在 js 中对我来说很好用

                var regex = new RegExp('[ftp:\/\/www\/.-https:\/\/-http:\/\/][a-zA-Z0-9u00a1-uffff0]{1,3}[^ ]{1,1000}');
                regex.exec('https://www.youtube.com/watch?v=FM7MFYoylVs&feature=youtu.be&t=20s');
                

                【讨论】:

                • 你能更好地格式化你的答案吗?这很难理解。
                【解决方案13】:
                "(?<=https?://)([^/\n\s]+)(?=/|\n\b)"
                

                应匹配以 http:// 或 https:// 开头的任何域。这个想法是设置一个“lookbehind”和一个“lookahead”匹配 https:// 和右边的第一个斜杠之间的部分。肯定有缺陷,但比我见过的其他表达方式要简单得多。

                【讨论】:

                • lookbehind 中的量词使其宽度不固定,因此无效。您还必须转义/。此外,您没有检查 URL 是否包含任何点,这是 OP 要求的。
                【解决方案14】:

                只是为了添加一些东西。我知道这并不能完全直接地回答这个特定问题,但这是我能找到的添加此信息的最佳位置。不久前我写了一个 jQuery 插件来匹配 url 用于类似目的,但是在当前状态下(随着时间的推移会更新它)它仍然会认为像“http://abc.php”这样的地址是有效的。但是,如果 url 开始处没有 http、https 或 ftp,则不会返回 'valid'。虽然我应该澄清一下,这个 jQuery 方法返回一个对象,而不仅仅是一个字符串或布尔值。该对象将事物分解,分解中是一个 .valid 布尔值。在底部的链接中查看完整的小提琴和测试。如果您只是想抓住插件然后走,请参见下文:

                jQuery 插件

                (function($){$.matchUrl||$.extend({matchUrl:function(c){var b=void 0,d="url,,scheme,,authority,path,,query,,fragment".split(","),e=/^(([^\:\/\?\#]+)\:)?(\/\/([^\/\?\#]*))?([^\?\#]*)(\?([^\#]*))?(\#(.*))?/,a={url:void 0,scheme:void 0,authority:void 0,path:void 0,query:void 0,fragment:void 0,valid:!1};"string"===typeof c&&""!=c&&(b=c.match(e));if("object"===typeof b)for(x in b)d[x]&&""!=d[x]&&(a[d[x]]=b[x]);a.scheme&&a.authority&&(a.valid=!0);return a}});})(jQuery);
                

                jsFiddle 示例:

                http://jsfiddle.net/SpYk3/e4Ank/

                【讨论】:

                  【解决方案15】:

                  (http|www)\S+

                  只需使用这个正则表达式来匹配所有 url 的

                  【讨论】:

                  • 这是一个非常糟糕的正则表达式。我不敢相信人们真的投票支持它。这很糟糕,因为它还将完全无效的httpcheese 匹配为有效的 url。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-02-19
                  • 2015-09-14
                  • 2021-12-31
                  • 2016-12-12
                  • 2012-02-04
                  相关资源
                  最近更新 更多