Regex in URL Rewriting according to Querystring Values ββin any order?
Many url rewriting utilities allow you to match Regex. I need some urls to be mapped to multiple basic guerrilla parameter values ββno matter what order they appear in. For example, consider a URL that has two key parameters ID = and Lang = in a specific order, and perhaps some other non-key parameters are interspersed.
Example URL to match key parameters in any order:
- http://www.example.com/SurveyController.aspx ? ID = 500 & Lang = 4 or
- http://www.example.com/SurveyController.aspx Lang = 4 & ID = 500
Maybe with some interspersed non-key parameters:
- http://www.example.com/SurveyController.aspx Lang = 3 & ID = 1 & misc = 3 & misc = 4 or
- http://www.example.com/SurveyController.aspx ID = 1 & misc = 4 & Lang = 3 or
- http://www.example.com/SurveyController.aspx?misc=4& Lang = 3 & ID = 1 or
- etc.
Is there a good regex pattern to match against the querystring parameter value in any order, or is it best to duplicate some rules or should you look for other ways altogether?
Note . Basic query values ββwill also be written using parentheses, that is, ID = (3) & Lang = (500), and replaced with the target URL, but this is out of focus.
a source to share
I would suggest parsing the query string in a dictionary and working from there, but if you want a regex you can use alternation + repetition to match in any order (without overlapping all possible sequences). Python example:
>>> import re
>>> p = re.compile(r'(?:[?&](?:abc=([^&]*)|xyz=([^&]*)|[^&]*))+$')
>>> p.findall('x?abc=1&jjj=2&xyz=3')
[('1', '3')]
>>> p.findall('x?abc=1&xyz=3&jjj=2')
[('1', '3')]
>>> p.findall('x?xyz=3&abc=1&jjj=2')
[('1', '3')]
a source to share
Regular expression matching is highly dependent on the sequential nature of the string. The position of the match is not important, but the order is definitely there.
This means that you cannot write a regular expression pattern that matches different parts of it in any order. You can write a template that matches its parts in any predefined order, however - you will need to include all possible permutations in the template. This gets awkward very quickly:
(a,b)
you need to matcha,b|b,a
(a,b,c)
you need to matcha,b,c|a,c,b|b,a,c|b,c,a|c,a,b|c,b,a
- etc.
And that means you're better off trying to approach the problem consistently while matching one parameter at a time. It depends on the capabilities of your rewrite engine, how it will work.
a source to share
This is beyond the scope of regular expression (most variants). You will actually need to duplicate every rewrite rule for every possible order of parameters, which is practical for two and ... less practical for ten.
Also, regular expressions won't do the kind of parsing you need to process all possible input parameters. For instance:
http://www.example.com/SurveyController.aspx?ID=500&L%61ng=4
is usually a valid synonym, while
http://www.example.com/SurveyController.aspx?Hello=3&ID=400&Lang=4&ID=500
can often be synonymous with ID 400 or 500 depending on the analyzer. Simple regex matches might be ok if you only want to 301 load a stale old-format address with a shiny new one, but not enough to catch all possible inputs.
So, for more complex cases like this, you'd be better off having a real SurveyController.aspx
one that looks at its parameters and redirects you where you need to go.
a source to share
If the underlying regex implementation understands both named groups and null perspective , you can get things to work using something like aspx\?(?=ID=(?<ID>\d+))(?=Lang=(?<Lang>\d+))
(this is untested speculation), but the result is likely to be both unattainable and probably underutilizes even a naive implementation which uses multiple regex to parse the string.
I would suggest that query strings are best parsed with a simple tokenizer, or even just split operations might be best for it.
a source to share