如何解析URL?

时间:2011-05-29 14:21:00

标签: javascript regex

如果有一件事我无法理解,那就是正则表达式。

经过大量的搜索,我终于找到了适合我需要的那个:

function get_domain_name()
    { 
    aaaa="http://www.somesite.se/blah/sdgsdgsdgs";
    //aaaa="http://somesite.se/blah/sese";
        domain_name_parts = aaaa.match(/:\/\/(.[^/]+)/)[1].split('.');
        if(domain_name_parts.length >= 3){
            domain_name_parts[0] = '';
        }
        var domain = domain_name_parts.join('.');
        if(domain.indexOf('.') == 0)
            alert("1"+ domain.substr(1));
        else
            alert("2"+ domain);
    }
它基本上给了我回域名,反正我还能得到域名之后的所有东西吗?在这种情况下,/blah/sdgsdgsdgs变量为aaaa

6 个答案:

答案 0 :(得分:72)

您应该使用JavaScript DOM API提供的内置URL解析器,而不是依赖于可能不可靠的*正则表达式:

var url = document.createElement('a');
url.href = "http://www.example.com/some/path?name=value#anchor";

这就是解析URL所需要做的全部工作。其他一切只是访问解析的值:

url.protocol; //(http:)
url.hostname; //(www.example.com)
url.pathname; //(/some/path)
url.search; // (?name=value)
url.hash; //(#anchor)

在这种情况下,如果您正在寻找/blah/sdgsdgsdgs,则可以url.pathname

访问它

基本上,您只是在JavaScript中创建一个链接(技术上,锚元素),然后您可以直接调用已解析的部分。 (因为您没有将它添加到DOM中,所以它不会在任何地方添加任何不可见的链接。)它的访问方式与location对象上的值相同。

(灵感来自this wonderful answer。)

编辑:一个重要的注意事项:似乎Internet Explorer有一个错误,它忽略了像这样的对象的pathname属性的前导斜杠。您可以通过执行以下操作将其标准化:

 url.pathname = url.pathname.replace(/(^\/?)/,"/");

注意: *:我说“可能不可靠”,因为尝试构建或找到一个包罗万象的URL解析器很诱人,但有许多条件,边缘情况和宽容的解析技术可能不被考虑或得到适当支持;浏览器可能最擅长实现(因为解析URL对于它们的正常操作至关重要)这个逻辑,所以我们应该保持简单并留给它们。

答案 1 :(得分:27)

RFC(参见附录B)提供了一个正则表达式来解析URI部分:

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
 12            3  4          5       6  7        8 9

,其中

scheme    = $2
authority = $4
path      = $5
query     = $7
fragment  = $9

示例:

function parse_url(url) {
    var pattern = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
    var matches =  url.match(pattern);
    return {
        scheme: matches[2],
        authority: matches[4],
        path: matches[5],
        query: matches[7],
        fragment: matches[9]
    };
}
console.log(parse_url("http://www.somesite.se/blah/sdgsdgsdgs"));

给出

Object
    authority: "www.somesite.se"
    fragment: undefined
    path: "/blah/sdgsdgsdgs"
    query: undefined
    scheme: "http"

DEMO

答案 2 :(得分:3)

请注意,此解决方案并非最佳解决方案。我这样做只是为了满足OP的要求。我个人建议查看其他答案。

以下正则表达式将为您提供域名和其他权限。 :\/\/(.[^\/]+)(.*)

  1. www.google.com
  2. / goosomething
  3. 我建议您在此处学习RegExp文档:http://www.regular-expressions.info/reference.html

    使用您的功能:

    function get_domain_name()
        { 
        aaaa="http://www.somesite.se/blah/sdgsdgsdgs";
        //aaaa="http://somesite.se/blah/sese";
            var matches = aaaa.match(/:\/\/(?:www\.)?(.[^/]+)(.*)/);
            alert(matches[1]);
            alert(matches[2]);
        }
    

答案 3 :(得分:2)

您只需稍微修改正则表达式即可。例如:

var aaaa="http://www.somesite.se/blah/sdgsdgsdgs";
var m = aaaa.match(/^[^:]*:\/\/([^\/]+)(\/.*)$/);
然后,

m将包含以下部分:

["http://www.somesite.se/blah/sdgsdgsdgs", "www.somesite.se", "/blah/sdgsdgsdgs"]

以下是相同的示例,但经过修改后将分割出“www”。部分。我认为应该写出正则表达式,这样无论你是否拥有“www”,匹配都会起作用。部分。所以看看这个:

var aaaa="http://www.somesite.se/blah/sdgsdgsdgs";
var m = aaaa.match(/^[^:]*:\/\/(www\.)?([^\/]+)(\/.*)$/);
然后,

m将包含以下部分:

["http://www.somesite.se/blah/sdgsdgsdgs", "www.", "somesite.se", "/blah/sdgsdgsdgs"]

现在查看相同的正则表达式,但是使用不以“www。”开头的网址:

var bbbb="http://somesite.se/blah/sdgsdgsdgs";
var m = .match(/^[^:]*:\/\/(www\.)?([^\/]+)(\/.*)$/);

现在你的比赛看起来像这样:

["http://somesite.se/blah/sdgsdgsdgs", undefined, "somesite.se", "/blah/sdgsdgsdgs"]

所以你可以看到它在两种情况下都会做正确的事。

答案 4 :(得分:2)

有一个很好的jQuery插件可用于解析URL:Purl

所有正则表达式内容都隐藏在内部,你会得到类似的东西:

> url = $.url("http://markdown.com/awesome/language/markdown.html?show=all#top");

> url.attr('source');
"http://markdown.com/awesome/language/markdown.html?show=all#top"

> url.attr('protocol');
"http"

> url.attr('host');
"markdown.com"

> url.attr('relative');
"/awesome/language/markdown.html?show=all#top"

> url.attr('path');
"/awesome/language/markdown.html"

> url.attr('directory');
"/awesome/language/"

> url.attr('file');
"markdown.html"

> url.attr('query');
"show=all"

> url.attr('fragment');
"top"

答案 5 :(得分:0)

自从首次提出这个问题以来,浏览器已经走了很长一段路。现在,您可以使用本地URL界面来完成此操作:

const url = new URL('http://www.somesite.se/blah/sdgsdgsdgs')

console.log(url.host) // "www.somesite.se"
console.log(url.href) // "http://www.somesite.se/blah/sdgsdgsdgs"
console.log(url.origin) // "http://www.somesite.se"
console.log(url.pathname) // "/blah/sdgsdgsdgs"
console.log(url.protocol) // "http:"
// etc.

请注意,IE不支持此API。但是,您可以轻松地用polyfill.io对其进行填充:

<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?flags=gated&features=URL"></script>