简体   繁体   中英

Finding Inner Parantheses string and outer parantheses string in python

suppose I have a string input

str=Length(name, concat(name,  concat(name, name) )  )

I need to get output starting from inner parantheses like:

concat(name, name)
concat(name,  concat(name, name) )
Length(name, concat(name,  concat(name, name) )  )

I have tried something like below in the code but its not giving proper result.The function name need not be concat it can be any.I have tried with only concat.Please help me with this

matches = re.finditer('concat',str)
positions = [match.start() for match in matches]
positions.sort(reverse=True)
print(positions)
for i in positions:
    out_expr = re.compile("\((.+)\)")
    res = re.search(out_expr,str[i:])
    inner = res.group(1)
    print(inner)

It's not clear from you description how you want to parse the word before the parenthesis, but a regular expressions are unlikely to be the correct solution here.

What you probably want is to parse a simple tree based on the parenthesis, such as

ex_str = "Length(name, concat(name,  concat(name, name) )  )"

def parse_paranthesis_tree(string):
    """
    Parses a tree containing the use of parenthesis within a string.
    """

    depth = 0
    active_node_per_depth = {}
    root_node = None
    for pos,char in enumerate(string):
        if char == '(':
            cur_node = {'start' : pos,
                    'end' : -1,
                    'depth': depth,
                    'children' : []}
            
            active_node_per_depth[depth] = cur_node
            if depth > 0:
                active_node_per_depth[depth-1]\
                        ['children'].append(cur_node)
            else:
                root_node = cur_node
            depth += 1

        if char == ')':
            active_node_per_depth[depth-1]['end'] = pos
            active_node_per_depth[depth-1] = None
            depth -= 1
    return root_node

def print_paranthesis_tree(node,string):
    print (string[node['start']:node['end']+1])
    for child_node in node['children']:
        print_paranthesis_tree(child_node,string)

print_paranthesis_tree(parse_paranthesis_tree(ex_str),ex_str)

This outputs,

(name, concat(name,  concat(name, name) )  )
(name,  concat(name, name) )
(name, name)

Note, this can be extended easily to parse the word before the parenthesis if you give a clear grammar or set of rules to follow when parsing the word (for example should white-space be ignored?)

I made minor changes to your code. I used the find function. See if this works for you.

import re
a='Length(name, concat(name, concat(name, name) ) )'
matches = re.finditer('concat',a)
positions = [match.start() for match in matches]
positions.sort(reverse=True)
li = []
x = 0
for i in positions:
    x = a.find(')',x) + 1
    li.append(a[i:x])
li.append(a)

for c in li: print (c)

Output is:

concat(name, name)
concat(name, concat(name, name) )
Length(name, concat(name, concat(name, name) ) )

I modified the code further. Here's an updated version. Let me know if this works for you. Assumption: the outer parenthesis is expected to be have one space in between them.

import re
a='Length(name, concat(name, concat(name, name) ) )'
start_pos=0
end_pos = len(a) - 2
matches = re.finditer('\(',a)
positions = [match.start() for match in matches]
positions.pop(0)
print(a)
for i in positions:
    start_pos = a[:i].rfind(',') + 2
    print(a[start_pos: end_pos])
    end_pos -= 2

Output is the same as earlier:

concat(name, name)
concat(name, concat(name, name) )
Length(name, concat(name, concat(name, name) ) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM