Efficient regular expression to detect 3 attributes in URL
Hello community,
First of all thanks for your time reading and answering this post:
We have read the following topics:
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
https://community.intersystems.com/post/using-regular-expressions-cach%C...
https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic....
https://community.intersystems.com/post/string-manipulation
https://community.intersystems.com/post/string-manipulation
We have the following need:
There is an URL which has 3 parameters:
[URL REST]/ServiceRequest?[EXTERNAL HEALTH CENTER CODE]:authoredOn=ge[START DATE RANGE (GREATER THAN OR EQUAL TO)]:authoredOn=le[END DATE RANGE (LESS THAN OR EQUAL TO)]
A real example is:
http://IP:19XXX/ServiceRequest?1111111111:authoredOn=ge2022-01-10:authoredOn=le2022-01-13
However, the health centers may interchange the order of the date attributes:
[URL REST]/ServiceRequest?[EXTERNAL HEALTH CENTER CODE]:authoredOn=le[END DATE RANGE (LESS THAN OR EQUAL TO)]:authoredOn=ge[START DATE RANGE (GREATER THAN OR EQUAL TO)]
Being a real example:
http://IP:19XXX/ServiceRequest?1111111111:authoredOn=le2022-01-13:authoredOn=ge2022-01-10
We have thought about the following rudimentary logic to obtain the 3 attributes:
set externalCenterCode = $PIECE($PIECE(url, :authoredOn=, 1) , /ServiceRequest? , 2)
set startDateRange = $PIECE($PIECE( url, :authoredOn=ge, 2) , :authoredOn=le , 1)
set endDateRange = $PIECE($PIECE( url, :authoredOn=le, 2) , :authoredOn=ge , 1)
📌📍 Is there a more readable, understandable, simple and correct way using regular expressions to obtain the 3 attributes?
We would be grateful if you could provide us with documentation, manuals, examples, references, explanations or any other means and/or tool that would allow us to solve this need in the most understandable, legible and correct way possible.
Thank you in advance
Best regards
We ask you because you are more experimented, skilled and you have more familiarity with ObjectScript and Ensemble.
In addition we have checked that the previous sentence:
set startDateRange = $PIECE($PIECE( url, ":authoredOn=ge", 2) , ":authoredOn=le", 1)
Would fail when ge is at the ending as in the following url:
set url = "http://IP:19XXX/ServiceRequest?1111111111:authoredOn=le2022-01-13:author..."
Plus, it would fail in the next line:
set endDateRange = $PIECE($PIECE( url, ":authoredOn=le", 2) ," :authoredOn=ge" , 1)
When le is at the ending, in the URL:
set url = "http://IP:19XXX/ServiceRequest?1111111111:authoredOn=ge2022-01-10:author..."
🔘 Could you help us please?
Thank you in advance
Best regards
Say you have this string:
How do you want to slice it:
what's 1111111111 doing there?
Something like this should work:
set str = "1111111111:authoredOn=ge2022-01-10:authoredOn=le2022-01-13" set str = $lfs(str, ":") for i=1:1:$ll(str) { set param = $lg(str,i) if $l(param,"=")=2 { set key = $p(param,"=",1) set value = $p(param,"=",2) set params(key, $i(params(key)))=value } } zw params
ClassMethod OnPage() As %Status [ ServerOnly = 1 ] { //just the query string... set qs=%request.CgiEnvs("QUERY_STRING") //SOLUTION 1: $piece only set externalCenterCode=$p(qs,":") set startDateRange=$p($p(qs,":authoredOn=le",2),":") set endDataRange=$p($p(qs,":authoredOn=ge",2),":") //SOLUTION 2: generic solution if params grow for i=1:1:$l(qs,":") { set nvp=$p(qs,":",i),name=$p(nvp,"=",1),value=$p(nvp,"=",2) //fix the quirks if value="" set value="name",name="ecc" if name="authoredOn" set name=$e(value,1,2),value=$e(value,3,*) set params(name)=value } //SOLUTION 3: regex(ish) solution set code=$p(qs,":") set loc=$locate(qs,"le\d{4}-\d{2}-\d{2}") set start=$e(qs,loc+2,loc+11) set loc=$locate(qs,"ge\d{4}-\d{2}-\d{2}") set end=$e(qs,loc+2,loc+11) //some helper code to dump the variables into the CSP page write !,"<pre>" zwrite //use this to take a good look at the request object... zwrite %request write !,"</pre>" quit $$$OK }
Here are three solutions and a couple of inline tips, including your request for regex example
I wouldn't worry too much about using $piece, its very common to use it in this way
Eduards comment above also has a fourth suggestion to use $lfs (list from string) which is also commonly used as a way of piecing out data