RegEx to extract parameters from url hash in JavaScript

20,590

Solution 1

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

Solution 2

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.

Share:
20,590
Gavriel
Author by

Gavriel

I code for living and for fun

Updated on April 01, 2020

Comments

  • Gavriel
    Gavriel about 4 years

    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)