【问题标题】:How can I use a regular expression to parse a generic, complex URL? [closed]如何使用正则表达式解析通用的复杂 URL? [关闭]
【发布时间】:2016-10-01 21:37:01
【问题描述】:

如何使用正则表达式解析通用的复杂 URL?

我想从 URL 字符串中获取信息,包括协议、主机名和路径。

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    使用正则表达式解析 URL

    您可以使用正则表达式解析 URL/URI。

    高级 URL 示例如下所示:

    http://login:password@www.example.org:80/demo/example.cgi?lang=de&foo=bar&empty#position
    

    用于解析高级 URL 的 RegExr 类似于:

    ([^ :]*):\/\/(?:([^:]*):([^@]*)@|)([^/:]{1,}):?(\d*)?(\/[^? ]*)\??((?:[^=&# ]*=?[^&# ]*&?)*)#?([^ ]*)?
    

    是的,太疯狂了。但是,您可以从中获取以下字段(组):

    #1 Protocol, #2 Login, #3 Password, #4 Host name, #5 Port, #6 Path, #7 Query, #8 Fragment
    

    假设您有一些 URL,并且只想知道一个主机名:

    var myURL = "http://www.example.org/demo/example.cgi?lang=de&foo=bar&empty";
    
    function getHostname(theURL) {
        var Expr = /([^ :]*):\/\/(?:([^:]*):([^@]*)@|)([^/:]{1,}):?(\d*)?(\/[^? ]*)\??((?:[^=&# ]*=?[^&# ]*&?)*)#?([^ ]*)?/g,
            match = Expr.exec(theURL);
        if(match && match[0]) {
            return match[4]; // #4th group of RegExpr
        }
    }
    
    var myHostname = getHostname(myURL);
    
    console.log(myHostname);

    我还创建了一个不错的表格,您可以在其中找到 URL 字符串的每个条目(在第 1 组)的 RegExpr:

    | URL entry name    | Example               | Regular Expression              |
    | ----------------- | --------------------- | ------------------------------- |
    | Protocol          | http                  | ([^ :]*):\/\/                   |
    | Login             | admin                 | \/\/([^:]*):[^@]*(?=@)          |
    | Password          | 12345                 | \/\/[^:]*:([^@]*)(?=@)          |
    | Host name         | www.example.org       | (?:@|\/\/)([^/:]{1,})           |
    | Domain parts      | www, example, org     | (?:@|\/\/|\.)([^./:]*)(?=[./:]) |
    | Port              | 80                    | :(\d*)\/[^/]                    |
    | Path              | /demo/example.cgi     | \/\/([^/][^? ]*)\??             |
    | File name         | example.cgi           | ([^?/]*(?!\/))\?                |
    | Query string      | lang=de&foo=bar&empty | \?((?:[^=&# ]*=?[^&# ]*&?)*)    |
    | Fragment/position | position              | #([^ ]*)                        |
    

    此外,您可以使用([^=&# ]*)=?([^&# ]*)&? 解析查询字符串并迭代匹配项:

    var myQueryString = "lang=de&foo=bar&empty";
    
    function parseQueryString(theQueryString) {
        var Expr = /([^=&# ]*)=?([^&# ]*)&?/g,
            QueryEntries = {},
            match;
        
        // If no match left it returns ["", undefinied, undefinied], 
        // ["", "", ""] or null - depends on JavaScript engine/web browser.
        // There is litte trick: "" and null is like false, so only check for [""].
        while((match = Expr.exec(theQueryString)) && match[0]) {
            QueryEntries[match[1]] = match[2] || '';
        }
        return QueryEntries;
    }
    
    var myQueryEntries = parseQueryString(myQueryString);
    
    console.log(myQueryEntries);

    您可以在http://regexr.com/ 上轻松测试您的 RegExpr。

    【讨论】:

      【解决方案2】:

      不要使用正则表达式。使用 URL 解析器。

      function parseURL(url) {
        var a = document.createElement('a');
        a.href = url;
        return a;
      }
      var urlData = parseURL('https://username:password@sub.example.com:123/foo/bar?a=b#c');
      console.log(urlData.protocol); // https:
      console.log(urlData.username); // username
      console.log(urlData.password); // password
      console.log(urlData.host);     // sub.example.com:123
      console.log(urlData.hostname); // sub.example.com
      console.log(urlData.port);     // 123
      console.log(urlData.pathname); // /foo/bar
      console.log(urlData.search);   // ?a=b
      console.log(urlData.hash);     // #c
      console.log(urlData.origin);   // https://sub.example.com:123
      console.log(urlData.href);     // https://username:password@sub.example.com:123/foo/bar?a=b#c

      还有URL interface。浏览器支持较少,但在语义上它可能比 DOM 元素更好。

      var urlData = new URL('https://username:password@sub.example.com:123/foo/bar?a=b#c');
      console.log(urlData.protocol); // https:
      console.log(urlData.username); // username
      console.log(urlData.password); // password
      console.log(urlData.host);     // sub.example.com:123
      console.log(urlData.hostname); // sub.example.com
      console.log(urlData.port);     // 123
      console.log(urlData.pathname); // /foo/bar
      console.log(urlData.search);   // ?a=b
      console.log(urlData.hash);     // #c
      console.log(urlData.origin);   // https://sub.example.com:123
      console.log(urlData.href);     // https://username:password@sub.example.com:123/foo/bar?a=b#c

      【讨论】:

      • “问题”中没有提到浏览器/dom。此方法不是基于 JavaScript。
      • @Amit DOM 是 JS 的一部分。它不是 ECMAScript 的一部分,如果你是这个意思的话。
      • 不不不。它是浏览器的一部分,如果有的话,是参考的附录。 Javascript 没有这些特性就存在(选框示例当然是 N​​ode)。
      • @Amit 从技术上讲,JavaScript 是 Netscape 和 Mozilla 的 ECMAScript 实现,所以是的,它是浏览器的东西。其他基于浏览器的实现,如 Microsoft 的 JScript,通常也称为 JavaScript。但我不会说 Node 是 JavaScript。
      • 这只是营销。他们说“JavaScript”是因为很多人听说过 JavaScript,但没有听说过 ECMAScript。同样(但出于兼容性目的),IE 在其用户代理中包含“Mozilla”,但这并不意味着 IE 是由 Mozilla 开发的......
      猜你喜欢
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 1970-01-01
      • 2014-02-14
      相关资源
      最近更新 更多