2

I want to parse a string with nested brackets into a nested list.

Example - parse_nested("abc(def(gh)ij)klm") -> ["abc", ["def", ["gh"], "ij"], "klm"].

My code works, but I was wondering if there was better way of doing this.

Here my code (I will write checks to catch malformed input later):

def match(s, start, stop):
    start = c = s.index(start)
    level = 0
    while c < len(s):
        if s[c] == start:
            level += 1
        elif s[c] == stop:
            level -= 1
        if level == 0:
            return (start+1, c)
        c += 1
    return None

def parse_nested(s):
    if start not in s and stop not in s:
        return s
    else:
        g = match(s, start, stop)
        first = s[:g[0]-1]
        middle = parse_nested(s[g[0]:g[1]])
        last = parse_nested(s[g[1]+1:])
        result = [first] if first else []
        if type(middle) == str:
            result.append([middle])
        else:
            result.append(middle)
        if last:
            if type(last) == str:
                result.append(last)
            else:
                result += last
        return result

Short of using a parsing library, is there any much shorter/better way of doing this?

rlms
  • 10,650
  • 8
  • 44
  • 61
  • Seems to be more suitable for http://codereview.stackexchange.com/ – Bart Kiers Feb 01 '14 at 18:48
  • @BartKiers I was originally planning to post there, but I'm looking for a completely different approach, so I thought it would be more suited to here. Perhaps I shouldn't have changed my mind. – rlms Feb 01 '14 at 18:51
  • I agree that this is a duplicate of that question, I don't know how I failed to see it when I when I was searching. – rlms Feb 01 '14 at 18:54
  • 1
    I written [this code](http://codepad.org/9DESMka0) – Grijesh Chauhan Feb 01 '14 at 18:57
  • @GrijeshChauhan I thought of a solution similar to that, but it doesn't seem extensible to parsing a string with different types of nesting characters (e.g. "(" and "<"), or usable in a language without `eval`. – rlms Feb 01 '14 at 19:35
  • @sweeneyrod Instead of eval you can use [`31.2. ast — Abstract Syntax Trees¶`](http://stackoverflow.com/questions/18416464/convert-array-formatted-as-a-string-python). Why not it is possible with different Just change `(` by `>` in code. (I used eval because Codepad doesn't `import ast`) – Grijesh Chauhan Feb 01 '14 at 19:38
  • @GrijeshChauhan As in if I wanted to extend it so that instead of lists, I had container objects that had both elements within them and the type of delimiter used to create them. – rlms Feb 01 '14 at 19:39
  • then write code as function something like `def parse(string, delimiter):` `code ..s = s.replace("," + delimiter, string)`...1 – Grijesh Chauhan Feb 01 '14 at 19:42

0 Answers0