0

Suppose I have an expression as shown below:

expression = "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])), 'chaichai', 'chai'))"

Required output:

['UPPER([ProductName]+[ProductName])','Lower(UPPER([ProductName]+[ProductName]))','Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai')','LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))']

I have tried the below code but not getting required result:

exp_splits = expression.strip(')').split('(')
for i_enm, i in enumerate(range(len(exp_splits)-2, -1, -1), start=1):
     result.append(f"{'('.join(exp_splits[i:])}{')'*i_enm}")
print(result)

my code's output:

["UPPER([ProductName]+[ProductName])),'chaichai','chai')", "Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))", "Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai')))", "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))))"]
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
shee
  • 165
  • 1
  • 10
  • First count # of `(` and `)` brackets you have. Then find the n-2th open bracket. Extract all data from that point till the first close bracket. You will have what you need – Joe Ferndz Jan 18 '21 at 14:19
  • @JoeFerndz can you please show with example.Can you please show it in my example – shee Jan 18 '21 at 14:24
  • Does this answer your question? [parsing nested parentheses in python, grab content by level](https://stackoverflow.com/questions/4284991/parsing-nested-parentheses-in-python-grab-content-by-level) – Tomerikoo Jan 18 '21 at 16:03

2 Answers2

0
import re

e = "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))"

print ([e[i:j+1] for i in range(len(e)) for j in range(len(e)) if e[i:j+1].count('(') == e[i:j+1].count(')') != 0 and (e[i-1] == '(' or i == 0) and e[j] == ')'])

Output:

["LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))", "Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai')", 'Lower(UPPER([ProductName]+[ProductName]))', 'UPPER([ProductName]+[ProductName])']

Unfolded version:

for i in range(len(e)):
    for j in range(len(e)):
        #Check for same number of opening/closing parenthesis
        if e[i:j+1].count('(') == e[i:j+1].count(')') != 0:
            #Check that (first char is preceded by an opening parenthesis OR that first char is the beginning of e) AND last char is a parenthesis
            if (e[i-1] == '(' or i == 0) and e[j] == ')':
                print (e[i:j+1])

Output:

LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))
Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai')
Lower(UPPER([ProductName]+[ProductName]))
UPPER([ProductName]+[ProductName])
Synthase
  • 5,849
  • 2
  • 12
  • 34
  • Hi @Synthase ,it is not working for this expression `DATENAME('weekday',DATEADD('month',3,[OrderDate]))` return output as `[ "DATENAME('weekday',DATEADD('month',3,[OrderDate]))","'weekday',DATEADD('month',3,[OrderDate])"]` whereas output should be `["DATENAME('weekday',DATEADD('month',3,[OrderDate]))","DATEADD('month',3,[OrderDate])"] ` – shee Feb 02 '21 at 07:40
-1

Approach using split and for loop

Here's another approach to get this done. In this approach, I am splitting the string into parts. Splitting them by left parenthesis and right parenthesis. Then concatenating them each time to create the expression

Assumption: The expression has equal number of left and right parenthesis

  • Step 1: Count the number of left parenthesis in the string
  • Step 2: Split the expression by left parenthesis
  • Step 3: pop the last expression from the list of left parenthesis and store into right expression. This contains right parenthesis
  • Step 4: Split the expression by right parenthesis
  • Step 5: Now that you have both the sides, stitch them together
  • Note: While concatenating the expression, left side goes from right to left (index -1 thru 0) and right side goes from left to right (index 0 to -1)
  • Note: For each iteration, you need to concatenate the previous answer with left and right

Code is as shown below:

expression = "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))"

n = expression.count('(')

exp_left = expression.split('(')
exp_right = exp_left.pop().split(')')
    
exp_list = []

exp_string = ''

for i in range(n):
    exp_string = exp_left[-i-1] + '(' + exp_string + exp_right[i] + ')'
    exp_list.append(exp_string)

for exp in exp_list: print (exp)

The output of this will be:

UPPER([ProductName]+[ProductName])
Lower(UPPER([ProductName]+[ProductName]))
Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai')
LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))

Below code is the same as above. I have added comments to each line for you to understand what's being done.

expression = "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))"

#find the number of equations in the string. Count of '(' will give you the number
n = expression.count('(')

#split the string by left parenthesis. You get all the functions + middle part + right hand side 
exp_left = expression.split('(')
#middle + right hand part is at position index -1. Use pop to remove the last value
#Use the popped string to split by right parenthesis
#result will be middle part + all right hand side parts.
#empty string if there was no text between two right parenthesis
exp_right = exp_left.pop().split(')')

#define a list to store all the expressions
exp_list = []

#Now put it all together looping thru n times
#store the expression in a string so you can concat left and right to it each time
exp_string = ''

for i in range(n):
    #for each iteration, concat left side + ( + middle string + right side + )
    #left hand side: concat from right to left (-1 to 0)
    #right hand side: concat from left to right (0 to n-1)
    exp_string = exp_left[-i-1] + '(' + exp_string + exp_right[i] + ')'
    #append the expression to the expression list
    exp_list.append(exp_string)

#print each string separately
for exp in exp_list: print (exp)

Approach using While Statement

Here's how to do the search and extract version.

e = "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))"

x = e.count('(')

for i in range(x-1): e = e[e.find('(')+1:]
expression = e[:e.find(')')+1]

print (expression)

The result of this will be:

UPPER([ProductName]+[ProductName])

If you want all of them, then you can do this until you reach the innermost brackets.

e = "LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))"

#x = e.count('(')
#for i in range(x-1): e = e[e.find('(')+1:]
#expression = e[:e.find(')')+1]


exp_list = [e]
while e.count('(') > 1:
    e = e[e.find('(')+1:e.rfind(')')]
    while e[-1] != ')': e = e[:e.rfind(')')+1]

    exp_list.append(e)

for exp in exp_list:
    print (exp)

The output of this will be:

LEN(Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai'))
Replace(Lower(UPPER([ProductName]+[ProductName])),'chaichai','chai')
Lower(UPPER([ProductName]+[ProductName]))
UPPER([ProductName]+[ProductName])
Joe Ferndz
  • 8,417
  • 2
  • 13
  • 33