Javascript 如何解析一个 URL?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6168260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:32:06  来源:igfitidea点击:

How to parse a URL?

javascriptregex

提问by Ryan

If there is one thing I just cant get my head around, it's regex.

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

So after a lot of searching I finally found this one that suits my needs:

因此,经过大量搜索,我终于找到了适合我的需求:

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);
    }

It basically gives me back the domain name, is there anyway I can also get all the stuff after the domain name? in this case it would be /blah/sdgsdgsdgsfrom the aaaavariable.

它基本上给了我域名,反正我也可以得到域名后的所有东西吗?在这种情况下,它将/blah/sdgsdgsdgs来自aaaa变量。

采纳答案by MarioRicalde

Please note that this solution is not the best. I made this just to match the requirements of the OP. I personally would suggest looking into the other answers.

请注意,此解决方案不是最好的。我这样做只是为了符合 OP 的要求。我个人建议查看其他答案。

THe following regexp will give you back the domain and the rest. :\/\/(.[^\/]+)(.*):

以下正则表达式将返回域和其余部分。:\/\/(.[^\/]+)(.*)

  1. www.google.com
  2. /goosomething
  1. www.google.com
  2. /goosomething

I suggest you studying the RegExp documentation here: http://www.regular-expressions.info/reference.html

我建议你在这里学习 RegExp 文档:http: //www.regular-expressions.info/reference.html

Using your function:

使用您的功能:

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]);
    }

回答by Yahel

Instead of relying on a potentially unreliable* regex, you should instead use the built-in URL parser that the JavaScript DOM API provides:

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

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

That's all you need to do to parse the URL. Everything else is just accessing the parsed values:

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

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

In this case, if you're looking for /blah/sdgsdgsdgs, you'd access it with url.pathname

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

Basically, you're just creating a link (technically, anchor element) in JavaScript, and then you can make calls to the parsed pieces directly. (Since you're not adding it to the DOM, it doesn't add any invisible links anywhere.) It's accessed in the same way that values on the locationobject are.

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

(Inspired by this wonderful answer.)

(受到这个精彩答案的启发。)

EDIT: An important note: it appears that Internet Explorer has a bug where it omits the leading slash on the pathnameattribute on objects like this. You could normalize it by doing something like:

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

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

Note: *: I say "potentially unreliable", since it can be tempting to try to build or find an all-encompassing URL parser, but there are many, many conditions, edge cases and forgiving parsing techniques that might not be considered or properly supported; browsers are probably best at implementing (since parsing URLs is critical to their proper operation) this logic, so we should keep it simple and leave it to them.

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

回答by Felix Kling

The RFC(see appendix B) provides a regular expression to parse the URI parts:

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

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

where

在哪里

scheme    = 
authority = 
path      = 
query     = 
fragment  = 


Example:

例子:

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"));

gives

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

DEMO

演示

回答by gordyt

You just need to modify your regex a bit. For example:

你只需要稍微修改你的正则表达式。例如:

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

m will then contain the following parts:

m 将包含以下部分:

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

Here is the same example, but modified so that it will split out the "www." part. I think the regular expression should be written so that the match will work whether or not you you have the "www." part. So check this out:

这是相同的示例,但进行了修改,以便将“www”分开。部分。我认为应该编写正则表达式,以便无论您是否拥有“www”,匹配都将起作用。部分。所以看看这个:

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

m will then contain the following parts:

m 将包含以下部分:

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

Now check out the same regular expression but with a url that does not start with "www.":

现在检查相同的正则表达式,但网址不以“www.”开头:

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

Now your match looks like this:

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

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

So as you can see it will do the right thing in both cases.

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

回答by weekens

There is a nice jQuery plugin for parsing URLs: Purl.

有一个很好的 jQuery 插件来解析 URL:Purl

All the regex stuff is hidden inside, and you get something like:

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

> 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"

回答by zgreen

Browsers have come a long way since this question was first asked. You can now use the native URLinterface to accomplish this:

自从第一次提出这个问题以来,浏览器已经走了很长一段路。您现在可以使用本机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.

Be aware that IE does not support this API. But, you can easily polyfill it with polyfill.io:

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

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