I am trying to build a custom string (JQL) validator based on my biz requirement for building the query (Just like JIRA - JQL) I got success in building the regex for positive scenarios. but there are some corner cases where i am finding hard to validate and pass the query string. Ex.
Product = 'Pepsi' AND Category = 'Beverages'
(Regex Passes and validated)Product = "L'Oreal Professionnel Anti-hair Loss Regime" AND Category = 'Shampoo'
(Regex failed and shows invalid string)
I have built the below regex for building the string like JQL.
/^\(*(NOT )*(\(*((([A-Za-z]\s*)|('[^']*'\s*)) ((?:^|\W)in\s*(\('[^']*'\s*([,]\s*'[^']*'\s*)*\))|(?:^|\W)not\s*in\s*([A-Za-z] \s*)|(?:^|\W)in\s*([A-Za-z] \s*)|(?:^|\W)= '[^']*'|(?:^|\W)!= '[^']*'|(?:^|\W)> '[^']*'|(?:^|\W)< '[^']*'|(?:^|\W)<= '[^']*'|(?:^|\W)>= '[^']*'|(?:^|\W)is '[^']*'|(?:^|\W)not is '[^']*')\)*((?:^|\W)AND\W|(?:^|\W)OR\W) (NOT\W)*)*\(*((([A-Za-z])|('[^']*')) ((?:^|\W)in (\('[^']*' *([,] *'[^']*')*\))|(?:^|\W)in ([A-Za-z] )|(?:^|\W)not in (\('[^']*'([,]'[^']*')*\))|(?:^|\W)not in ([A-Za-z] )|(?:^|\W)= '[^']*'|(?:^|\W)!= '[^']*'|(?:^|\W)> '[^']*'|(?:^|\W)< '[^']*'|(?:^|\W)<= '[^']*'|(?:^|\W)>= '[^']*'|(?:^|\W)is '[^']*'|(?:^|\W)not is '[^']*'))*\)*)* *\(*(((ORDER BY '[^']*')*)|((ORDER BY [A-Za-z]*)*) *(ASC|DESC)*)*\)*\)*$/gi
I know, I have missed few corner use cases. thats the reason i need your guidance and input on the same. Thanks in advance.
CodePudding user response:
One approach you could take is to use a regex that captures the different parts of the query string and then validate them separately. For example, you could use a regex like the following to capture the different clauses in the query string:
/((\b[A-Za-z] \b)\s*(=|!=|in|not in|>|<|<=|>=|is|not is)\s*(('[^']*')|([A-Za-z] )))|((ORDER BY)\s*(('[^']*')|([A-Za-z] ))\s*(ASC|DESC))/gi
This regex captures clauses that have the form field operator value
or ORDER BY field direction
. The field
can be a string enclosed in single quotes (e.g. 'Product'
) or a word (e.g. Category
). The value
can be a string enclosed in single quotes (e.g. 'Beverages'
) or a word (e.g. ASC
).
You can then iterate over the matches and validate each clause separately. For example, you could check that the field
is a valid field name, that the operator
is a valid operator, and that the value
is a valid value for the given field and operator.
CodePudding user response:
0
One approach you could take is to use a regex that captures the different parts of the query string and then validate them separately. For example, you could use a regex like the following to capture the different clauses in the query string:
/((\b[A-Za-z] \b)\s*(=|!=|in|not in|>|<|<=|>=|is|not is)\s*(('[^']')|([A-Za-z] )))|((ORDER BY)\s(('[^']')|([A-Za-z] ))\s(ASC|DESC))/gi This regex captures clauses that have the form field operator value or ORDER BY field direction. The field can be a string enclosed in single quotes (e.g. 'Product') or a word (e.g. Category). The value can be a string enclosed in single quotes (e.g. 'Beverages') or a word (e.g. ASC).
You can then iterate over the matches and validate each clause separately. For example, you could check that the field is a valid field name, that the operator is a valid operator, and that the value is a valid value for the given field and operator.