最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

RegEx to extract parameters from url hash in JavaScript - Stack Overflow

programmeradmin1浏览0评论

My urls will look like:

;locale=hu&y=2
;locale=hu

=



I'd like to get the locale parameter or empty string if it's not set.

I'm trying something like:

locale = location.hash.replace(/.*(?:[?&]locale=([^&]*))?.*/, "$2");

But my problem is that I couldn't find the right RegExp that works for all cases (both when there's locale= in the hash and when there isn't)

My urls will look like:

http://example.com/whatever#page?x=1&locale=hu&y=2
http://example.com/whatever#page?x=1&locale=hu
http://example.com/whatever#page?locale=hu
http://example.com/whatever#page?locale=
http://example.com/whatever#page?x=1
http://example.com/whatever#page
http://example.com/whatever

I'd like to get the locale parameter or empty string if it's not set.

I'm trying something like:

locale = location.hash.replace(/.*(?:[?&]locale=([^&]*))?.*/, "$2");

But my problem is that I couldn't find the right RegExp that works for all cases (both when there's locale= in the hash and when there isn't)

Share Improve this question asked May 16, 2012 at 18:48 GavrielGavriel 19.2k12 gold badges71 silver badges115 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 16

Here's a piece of code that will extract it from the hash and avoid it anywhere else in the URL:

function getLocaleFromHash(url) {
    var match = url.match(/#.*[?&]locale=([^&]+)(&|$)/);
    return(match ? match[1] : "");
}

And, you can see it work on all your test cases here: http://jsfiddle.net/jfriend00/p37Mx/


If you want to be able to look for any parm in the hash, you would use this:

function getParmFromHash(url, parm) {
    var re = new RegExp("#.*[?&]" + parm + "=([^&]+)(&|$)");
    var match = url.match(re);
    return(match ? match[1] : "");
}

See it work here: http://jsfiddle.net/jfriend00/6kgUk/


A more generic function that will fetch all parameters in the URL would look like this. For normal URLs where the hash is after the query and the parameters are in the query string, it would look like this. This is a bit more code because it does more. It fetches all the parameters into an object where you can look up any parameter by it's key and it URL decodes them all too:

function getParmsFromURL(url) {
    var parms = {}, pieces, parts, i;
    var hash = url.lastIndexOf("#");
    if (hash !== -1) {
        // remove hash value
        url = url.slice(0, hash);
    }
    var question = url.lastIndexOf("?");
    if (question !== -1) {
        url = url.slice(question + 1);
        pieces = url.split("&");
        for (i = 0; i < pieces.length; i++) {
            parts = pieces[i].split("=");
            if (parts.length < 2) {
                parts.push("");
            }
            parms[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
        }
    }
    return parms;
}

For a special version that handles parameters in a hash value and after a ? in the hash value like in the OP's question (which isn't the typical case), one could use this:

function getParmsFromURLHash(url) {
    var parms = {}, pieces, parts, i;
    var hash = url.lastIndexOf("#");
    if (hash !== -1) {
        // isolate just the hash value
        url = url.slice(hash + 1);
    }
    var question = url.indexOf("?");
    if (question !== -1) {
        url = url.slice(question + 1);
        pieces = url.split("&");
        for (i = 0; i < pieces.length; i++) {
            parts = pieces[i].split("=");
            if (parts.length < 2) {
                parts.push("");
            }
            parms[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
        }
    }
    return parms;
}

Working demo: http://jsfiddle.net/jfriend00/v8cd5/

And, then if you wanted the local option, you'd just do this:

var parms = getParmsFromURL(url);
var locale = parms["locale"];
locale = location.hash.match( /[?&]locale=([^&]*)?/ );
locale = ( locale == null ? "" : locale[1] || "" );

Will do the trick. I don't think the .* are needed, because you do not specify a start or an end of the string. I tested this regular expression on all your examples and they all worked correctly :)

Edit: sorry, it was invalid in some cases. It is now correct in all cases.

If you really want to do it in one regex:

locale = location.hash.match(/([?&]locale=|^((?![?&]locale=).)+$)([^&]*)/)[3];

It works against all of your examples, though I imagine it's horribly inefficient.

发布评论

评论列表(0)

  1. 暂无评论