Regular expression to remove one parameter from query string
        Posted  
        
            by Kip
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Kip
        
        
        
        Published on 2009-12-03T20:27:54Z
        Indexed on 
            2010/04/12
            23:13 UTC
        
        
        Read the original article
        Hit count: 979
        
regex
|querystring
I'm looking for a regular expression to remove a single parameter from a query string, and I want to do it in a single regular expression if possible.
Say I want to remove the foo parameter. Right now I use this:
/&?foo\=[^&]+/
That works as long as foo is not the first parameter in the query string.  If it is, then my new query string starts with an ampersand. (For example, "foo=123&bar=456" gives a result of "&bar=456".) Right now, I'm just checking after the regex if the query string starts with ampersand, and chopping it off if it does.
Example edge cases:
Input                    |  Output
-------------------------+-----------------
foo=123                  |  (empty string)
foo=123&bar=456          |  bar=456
bar=456&foo=123          |  bar=456
abc=789&foo=123&bar=456  |  abc=789&bar=456
Edit
OK as pointed out in comments there are there are way more edge cases than I originally considered. I got the following regex to work with all of them:
/&foo(\=[^&]*)?(?=&|$)|^foo(\=[^&]*)?(&|$)/
This is modified from Mark Byers's answer, which is why I'm accepting that one, but Roger Pate's input helped a lot too.
Here is the full suite of test cases I'm using, and a Perl script which tests them.
Input                    | Output
-------------------------+-------------------
foo                      | 
foo&bar=456              | bar=456
bar=456&foo              | bar=456
abc=789&foo&bar=456      | abc=789&bar=456
foo=                     | 
foo=&bar=456             | bar=456
bar=456&foo=             | bar=456
abc=789&foo=&bar=456     | abc=789&bar=456
foo=123                  | 
foo=123&bar=456          | bar=456
bar=456&foo=123          | bar=456
abc=789&foo=123&bar=456  | abc=789&bar=456
xfoo                     | xfoo
xfoo&bar=456             | xfoo&bar=456
bar=456&xfoo             | bar=456&xfoo
abc=789&xfoo&bar=456     | abc=789&xfoo&bar=456
xfoo=                    | xfoo=
xfoo=&bar=456            | xfoo=&bar=456
bar=456&xfoo=            | bar=456&xfoo=
abc=789&xfoo=&bar=456    | abc=789&xfoo=&bar=456
xfoo=123                 | xfoo=123
xfoo=123&bar=456         | xfoo=123&bar=456
bar=456&xfoo=123         | bar=456&xfoo=123
abc=789&xfoo=123&bar=456 | abc=789&xfoo=123&bar=456
foox                     | foox
foox&bar=456             | foox&bar=456
bar=456&foox             | bar=456&foox
abc=789&foox&bar=456     | abc=789&foox&bar=456
foox=                    | foox=
foox=&bar=456            | foox=&bar=456
bar=456&foox=            | bar=456&foox=
abc=789&foox=&bar=456    | abc=789&foox=&bar=456
foox=123                 | foox=123
foox=123&bar=456         | foox=123&bar=456
bar=456&foox=123         | bar=456&foox=123
abc=789&foox=123&bar=456 | abc=789&foox=123&bar=456
Test script (Perl)
@in = ('foo'     , 'foo&bar=456'     , 'bar=456&foo'     , 'abc=789&foo&bar=456'
      ,'foo='    , 'foo=&bar=456'    , 'bar=456&foo='    , 'abc=789&foo=&bar=456'
      ,'foo=123' , 'foo=123&bar=456' , 'bar=456&foo=123' , 'abc=789&foo=123&bar=456'
      ,'xfoo'    , 'xfoo&bar=456'    , 'bar=456&xfoo'    , 'abc=789&xfoo&bar=456'
      ,'xfoo='   , 'xfoo=&bar=456'   , 'bar=456&xfoo='   , 'abc=789&xfoo=&bar=456'
      ,'xfoo=123', 'xfoo=123&bar=456', 'bar=456&xfoo=123', 'abc=789&xfoo=123&bar=456'
      ,'foox'    , 'foox&bar=456'    , 'bar=456&foox'    , 'abc=789&foox&bar=456'
      ,'foox='   , 'foox=&bar=456'   , 'bar=456&foox='   , 'abc=789&foox=&bar=456'
      ,'foox=123', 'foox=123&bar=456', 'bar=456&foox=123', 'abc=789&foox=123&bar=456'
      );
@exp = (''        , 'bar=456'         , 'bar=456'         , 'abc=789&bar=456'
       ,''        , 'bar=456'         , 'bar=456'         , 'abc=789&bar=456'
       ,''        , 'bar=456'         , 'bar=456'         , 'abc=789&bar=456'
       ,'xfoo'    , 'xfoo&bar=456'    , 'bar=456&xfoo'    , 'abc=789&xfoo&bar=456'
       ,'xfoo='   , 'xfoo=&bar=456'   , 'bar=456&xfoo='   , 'abc=789&xfoo=&bar=456'
       ,'xfoo=123', 'xfoo=123&bar=456', 'bar=456&xfoo=123', 'abc=789&xfoo=123&bar=456'
       ,'foox'    , 'foox&bar=456'    , 'bar=456&foox'    , 'abc=789&foox&bar=456'
       ,'foox='   , 'foox=&bar=456'   , 'bar=456&foox='   , 'abc=789&foox=&bar=456'
       ,'foox=123', 'foox=123&bar=456', 'bar=456&foox=123', 'abc=789&foox=123&bar=456'
       );
print "Succ | Input                    | Output                   | Expected                \n";
print "-----+--------------------------+--------------------------+-------------------------\n";
for($i=0; $i <= $#in; $i++)
{
  $out = $in[$i];
  $out =~ s/_PUT_REGEX_HERE_//;
  $succ = ($out eq $exp[$i] ? 'PASS' : 'FAIL');
  #if($succ eq 'FAIL')
  #{
    printf("%s | %- 24s | %- 24s | %- 24s\n", $succ, $in[$i], $out, $exp[$i]);
  #}
}
© Stack Overflow or respective owner