Currently, I have a Boolean expression which supports &
(logical AND), |
(logical OR), (
, )
(parentheses) operators along with status codes like s, f, d, n, t
and job names.
The status codes represent the status of a job. (Eg: s = success
, f = failure
, etc…) and the job name is enclosed within parentheses with an optional argument which is a number within quotes.
Example i/p:
( s(job_A, "11:00") & f(job_B) ) | ( s(job_C) & t(job_D) )
My requirement is for such a given string in Python, I need to replace the existing job names with new job names containing a prefix and everything else should remain the same:
Example o/p:
( s(prefix_job_A, "11:00") & f(prefix_job_B) ) | ( s(prefix_job_C) & t(prefix_job_D) )
This logical expression can be arbitrarily nested like any Boolean expression and being a non-regular language we can’t use regexes.
Please note: The job names are NOT known before-hand so we can’t statically store the names in a dictionary and perform a replacement.
The current approach I have thought of is to generate an expression tree and perform replacements in the OPERAND nodes of that tree, however I am not sure how to proceed with this. Is there any library in python which can help me to define the grammar to build this tree? How do I specify the grammar?
Can someone help me with the approach?
Edit: The job names don’t have any particular form. The minimum length of a job name is 6 and the job names are alphanumeric with underscores.
Advertisement
Answer
Given that we can assume that job names are alphanumeric + _ and length at least 6, we should be able to do this just with a regex since it appears nothing else in the given strings look like that.
import regex exp = '( s(job__A, "11:00") & f(job__B) ) | ( s(job__C) & t(job__D) )' name_regex = "([a-zA-Zd_]{6,})" # at least 6 alphanumeric + _ characters prefix = "prefix_" new_exp = regex.sub(name_regex, f"{prefix}\1", exp) print(new_exp)