开发者

Struggling with regex logic: how do I remove a param from a url query string?

I'm comparing 2 URL query strings to see if they're equal; however, I want to ignore a specific query parameter (always with a numeric value) if it exists. So, these 2 query strings should be equal:

firstName=bobby&lastName=tables&paramToIgnore=2

firstName=bobby&lastName=tables&paramToIgnore=5

So, I tried to use a regex replace using the REReplaceNoCase function:

REReplaceNoCase(myQueryString, "&paramToIgnore=[0-9]*", "")

This works fine for the above example. I apply the replace to both strings and then compare. The problem is that I can't be sure that the param will be the last one in the string... the following 2 query strings should also be equal:

firstName=bobby&lastName=tables&paramToIgnore=2

paramToIgnore=5&firstName=bobby&lastName=tables

So, I changed the regex to make the preceding ampersand optional... "&?paramToIgnore=[0-9]*". But - these strings will still not be equal as I'll be left with an extra ampersand in one of the strings but not the other:

firstName=bobby&lastName=tables

&firstName=bobby&lastName=tables

Similarly, I can't just remove preceding and following ampersands ("&?paramToIgnore=[0-9]*&?") as if the query param is in the middle of开发者_如何学C the string I'll strip one ampersand too many in one string and not the other - e.g.

firstName=bobby&lastName=tables&paramToIgnore=2

firstName=bobby&paramToIgnore=5&lastName=tables

will become

firstName=bobby&lastName=tables

firstName=bobbylastName=tables

I can't seem to get my head around the logic of this... Can anyone help me out with a solution?


If you can't be sure of the order the parameters appear i would recommend, that you don't compare them by the string itsself.

I recommend splitting the string up like this:

String stringA = "firstName=bobby&lastName=tables&paramToIgnore=2";
String stringB = "firstName=bobby&lastName=tables&paramToIgnore=5";

String[] partsA = stringA.split("&");
String[] partsB = stringB.split("&");

Then go through arrays and make the paramToIgnore somehow euqal:

for(int i = 0; i < partsA.length; i++)
{
  if(partsA[i].startsWith("paramToIgnore"){
   partsA[i] = "IgnoreMePlease";
  }
}

for(int j = 0; j < partsB.length; j++)
{
  if(partsB[i].startsWith("paramToIgnore"){
   partsB[i] = "IgnoreMePlease";
  }
}

Then you can sort and compare the arrays to see if they are equal:

Arrays.sort(partsA);
Arrays.sort(partsB);
boolean b = Arrays.equals(partsA, partsB);

I'm pretty sure it's possible to make this more compact and give it a better performance. But with comparing strings like you do, you somehow alsways have to care about the order of your parameters.


You can use the QueryStringDeleteVar UDF on cflib to remove the query string variables you want to ignore from both strings, then compare them.


Make it in two steps:

  1. first remove your param, as you described in example
  2. then remove ampersand which is left at the begining or the end of query with separate regex, or any double/triple/... ampersands in the middle of the query


How about having an 'or' in the RegEx to match an ampersand at the start or the end?

&paramToIgnore=[0-9]*|paramToIgnore=[0-9]*&

Seems to do the job when testing in regexpal.com


try changing it to:

REReplaceNoCase(myQueryString, "&?paramToIgnore=[0-9]+", "")

plus instead of star should capture 1 or more of the preceding matched characters. It won't match anything but 0-9 so if there is another parameter after that it'll stop when it can't match any more digits.

Alternatively, you could use:

REReplaceNoCase(myQueryString, "&?paramToIgnore=[^&]", "")

This will match anything but an ampersand. It will cover the case if the parameter exists but there is no value; which is probably something you'd want to account for.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜