JavaScript regex trick: Parse a query string into an object

Have you ever needed to get query string values using JavaScript? This task is usually a painful split, split, split, iterate, indexOf hack that is really slow and terribly ugly to look at. It also tends to pile up lines of code really fast.

Here is a really sweet way to parse the query string into a JavaScript object with two lines of code using regular expressions to populate an object. I discovered this trick a few years ago and filed it away in my code snippets folder.

The Code

The JavaScript code itself uses the replace() method with a regular expression to target the name/value pairs in the URI string that you are working with. The replace value is actually a function which will be executed for each pair. This little function simply pushes the name/value pair into the queryString object.

var queryString = {};
anchor.href.replace(
	new RegExp("([^?=&]+)(=([^&]*))?", "g"),
	function($0, $1, $2, $3) { queryString[$1] = $3; }
);

Isn’t it beautiful? In this example anchor is some anchor tag on a page that I have already defined with a document.getElementById. However it works just as well with window.location.href.

Using it

Using this simple trick you can access query string parameters by saying queryString['name']. Let’s say that your URI looks like this:

http://your.domain/product.aspx?category=4&product_id=2140&query=lcd+tv

Want that product ID? Simple, queryString['product_id'] will return “2140”. Nice and simple.

If the query string parameter that you are searching for does not exist then it will return undefined without throwing an error.

Full example

Copy and paste this into your Firebug console and run it to see it in action:

var uri = 'http://your.domain/product.aspx?category=4&product_id=2140&query=lcd+tv';
var queryString = {};
uri.replace(
	new RegExp("([^?=&]+)(=([^&]*))?", "g"),
	function($0, $1, $2, $3) { queryString[$1] = $3; }
);
console.log('ID: ' + queryString['product_id']);     // ID: 2140
console.log('Name: ' + queryString['product_name']); // Name: undefined
console.log('Category: ' + queryString['category']); // Category: 4

By:
Updated: Jun 5th, 2011

Comments

  1. Brilliant.

  2. Scott

    here is another way (converts query string to object):

    qso = eval(“({” + location.search.slice(1).replace(/=/g, “:”).replace(/&/g, “,”) + “})”);

  3. lee

    For your regex to work with hrefs that include a hash fragment
    eg http://mysite.com/here/there.html#now
    Change the regex to
    new RegExp(“([^?=&]+)(=([^&#]*))?”, “g”),

  4. Simple and well written.
    It would be great if you update the article with the change suggested by Scott. :)

  5. Can I use this to pass an item_name to a new web page,… but then to print (document.write?) the item_name *and* provide a link to an image (which is item_name.jpg)? What would the html look like? My brain does not work like a programmers!

  6. David W

    Don’t forget window.decodeUriComponent() to handle unescaping.

  7. Nice and simple, I like it. But once you’ve got the queryString object, you don’t have to use the array-style notation, just queryString.product_id will work just fine, making it even cleaner.

  8. I recently had to implement a function similar to this for a jquery plugin. However, my function ended up being quite a bit more complicated, because it also handled nested objects such as:

    my[nested][object]=hi //=> {my: {nested: {object: ‘hi’}}}

    As well as arrays:

    my_array[]=hi&my_array[]=there //=> {my_array: [‘hi’, ‘there’]}

    …and any combination thereof.

  9. Robert

    They should include this feature into jQuery, would be so incredibly useful.

  10. Josh

    Made a jsPerf for it, only difference is I’m using a RegEx literal rather than invoking the RegExp constructor:

    http://jsperf.com/query-str-parsing-regex-vs-split

  11. Scott’s eval based parsing has a major risk:

    Consider the query string: ?foo=alert(‘oh hai, xss!’)

    Before running the query string through that eval, you would have to sanitize it, and by that point, I think you’re better off with Steven’s original regex based solution.

  12. Can’t believe no one has caught this yet. The code above does not work as expected if you pass a URL with no query string. It’ll just return an object containing the URL as key and undefined as value.

    To fix, use this regex instead: RegExp(“\\?([^?=&]+)(=([^&#]*))?”, “g”)

  13. @William K That still doesn’t work for me

    Add a simple check to ignore invalid matches – https://gist.github.com/simonsmith/5152680

  14. ?this=1&this=2&this=3

    is not covered.

  15. Dave

    Is there any reason this is stripping out data from my string?

    http://example.com/2nd-form-page/?age=87&value=195%2C000&lien=107%2C500&sendbutton=#.UYSKDaKG2So

    I am using:

    function showAlert() {
    var age = queryString[‘age’];
    var homeval = queryString[‘value’];
    var lien = queryString[‘lien’];
    alert(‘The age is ‘ + age + ‘ and value is ‘ + homeval + ‘ and the liens are ‘ + lien + ‘.’);
    }

    And if the number has a 0, 3, or 8 (from what I can tell so far) the value is cut off. So 70 shows as 7, 100,000 shows as 1, 89 shows as “” (nothing), etc., etc.

    Thanks.

  16. John Denney

    Great job and thanks! It has saved me a lot of time. I adjusted it to suit my needs (see below)

    // I have altered the function to accept a query string that may have to be parsed to the function
    // sample url : “http://shopping.crepidam.com/parts/add_to_cart.php?sku=16030&description=Cylinder%C2%A0Assembly”

    function(qryStr){

    // this was to fix a problem where the NON Breaking whitespace was not being removed properly and I could not
    // get the regex to work where I had multiple instance within the original URL and returned object value

    qryStr.replace(‘%C2%A0′,’ ‘);

    var queryString = {};
    qryStr.replace(
    new RegExp(“([^?=&]+)(=([^&#]*))?”, “gi”),
    function($0, $1, $2, $3) { queryString[$1] = $3; }
    );
    }

    You can build a string like the example below

    // build GET string
    var locationStr = “add_to_cart.php?sku=” + queryString[‘sku’] + “&description=” + queryString[‘description’].replace(‘%C2%A0′,’ ‘);

    or you can call the object directly as per the original post above

    queryString[‘product_id’] and store in a variable for use later

  17. Iurii

    Was write parser for that https://github.com/PxyUp/uri-parse-lib, support nested query and array

Leave a reply

Pages linking to this article