0

I'm trying to remove a variable from a query string. This is my current approach:

var str = "http://example.com/tal.php?sec=16&name=xxxx&size=xxxx";
str = str.replace(/([&])name=.*?(&|$)/g,"");

There are two problems with this code:

  • Both the & at the beginning of name and at the end get removed. I'd like only one to be removed

  • It should also work when the variable name is at the beginning or at the end of the query string.

How can I tell the regex to delete the second & only if it has matched the first one?

2 Answers 2

2

I suggest using capturing groups and then using them in the callback function to re-insert the & character appropriately:

([?&])name=.*?($|&)

See demo

Here is a JavaScript snippet showing replacement process in all the 3 positions:

function removeQueryArg(str) {
  var re = /([?&])name=.*?($|&)/; 
  return str.replace(re, function(m, grp1, grp2, offset, input) {
     return grp1 === "?" ? "?" : (grp2 === "&" ? "&" : "");
  });
}

document.write(removeQueryArg('http://example.com/tal.php?name=xxxx&sec=16&size=xxxx') + "<br/>" +
   removeQueryArg('http://example.com/tal.php?sec=16&name=xxxx&size=xxxx') + "<br/>" +
   removeQueryArg('http://example.com/tal.php?sec=16&size=xxxx&name=xxxx'));

Let me explain:

  • The ([?&])name=.*?($|&) regex contains 2 capturing groups ([?&]) (matching either ? or &) and ($|&) (matching end of string or &).
  • Inside the replace method, we can pass the contents of these groups to the callback function where we can further analyze what to do with the replacement.
  • function(m, grp1, grp2, offset, input) actually uses the whole match m, and grp1 and grp2 are the captured texts. offset (match index in the original string) and input (the whole input string) are not used here, but they might turn out useful some day.
  • In the callback, I am checking if group 1 is equal to "?". If yes, the argument is in the beginning of the query string, and we need to restore the ? in front.
  • If not, we need to check the contents of the 2nd group. If it is equal to &, the match is in the middle of the query string, we need to add &. If not, we are at the end, do not add anything, we remove the whole match.

See more at Specifying a function as a parameter at MDN replace method help page.

Sign up to request clarification or add additional context in comments.

4 Comments

I made a correction, as I don't really want to match the first "?", after this change, if you put the variable as first of the querystring, it doesn't get matched...
True, all this can be solved with capturing groups and logic inside a callback function. Please check the updated answer.
Looks good bu I don't understand what the function you give to replace is doing...
Is it now clearer? Callback functions are very handy in JS as its regex engine is one of the poorest.
1

A simple way to solve this is to delete the name parameter together with the question mark or ampersand that precedes it. If the question mark gets deleted, put it back in by replacing the first ampersand with a question mark.

s = s.replace(/([?&]name=[^&]*)/, '');
if (s.indexOf('?') == -1) {
  s = s.replace(/[&]/, '?');
}

Demonstration:

function print(s) {
  document.write(s + '<br \>');
}

function deleteName(s) {
  print(s);
  s = s.replace(/([?&]name=[^&]*)/, '');
  if (s.indexOf('?') == -1) {
    s = s.replace(/[&]/, '?');
  }
  print(s);
  print('');
}

deleteName('http://example.com/tal.php?name=xxxx&sec=16&size=xxxx');

deleteName('http://example.com/tal.php?sec=16&name=xxxx&size=xxxx');

deleteName('http://example.com/tal.php?sec=16&size=xxxx&name=xxxx');
body {
  font-family: sans-serif;
}

2 Comments

Yeah, basically, this is an similar solution, but using 2 regexp replacements instead of one.
<br \> is a valid tag.

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.