2

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)

3 Answers 3

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"];
Sign up to request clarification or add additional context in comments.

9 Comments

I like this one, because it's easily reusable by passing the parameter I'm looking for to the function :)
@Gavriel - I added a more generic function that lets you pass in not only the URL, but also the parameter you're looking for in it.
thanks, I've already done it alone :) Just came back to post it, but it's identical to your 2nd function.
It would be better if you have written a function that takes Seperator,url,param as parameter
@RezaRahmati - I added two versions of more generic code that parse all the parameters either out of a normal query string or out of a hash query.
|
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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.