2013-03-07 57 views
1

我有一个这样的字符串:'aaa(cc(kkk)c)ddd[lll]{m(aa)mm}'。从该字符串我想要得到以下结构:['aaa', '(cc(kkk)c)', 'ddd', '[lll]', '{m(aa)mm}']。换句话说,我想分开不同类型括号中的子字符串。Python是否有简单的字符串解析器?

+0

为什么你的'(cc(kkk)c)'结构变成'(cc {kkk} c)'? – 2013-03-07 10:38:28

+0

对不起,我犯了一个错误。它应该是(cc(kkk)c)。 – Roman 2013-03-07 10:39:15

+0

正确,所以你的括号和括号可以嵌套。 – 2013-03-07 10:39:56

回答

7

您需要使用堆栈的方式来跟踪嵌套层数:

pairs = {'{': '}', '[': ']', '(': ')'} 

def parse_groups(string): 
    stack = [] 
    last = 0 
    for i, c in enumerate(string): 
     if c in pairs: 
      # push onto the stack when we find an opener 
      if not stack and last < i: 
       # yield anything *not* grouped 
       yield string[last:i] 
      stack.append((c, i)) 
     elif c in pairs: 
      if stack and pairs[stack[-1][0]] == c: 
       # Found a closing bracket, pop the stack 
       start = stack.pop()[1] 
       if not stack: 
        # Group fully closed, yield 
        yield string[start:i + 1] 
        last = i + 1 
      else: 
       raise ValueError('Missing opening parethesis') 

    if stack: 
     raise ValueError('Missing closing parethesis') 

    if last < len(string): 
     # yield the tail 
     yield string[last:] 

这将产生群体,转换为一个列表,如果你需要一个:

>>> list(parse_groups('aaa(cc(kkk)c)ddd[lll]{m(aa)mm}')) 
['aaa', '(cc(kkk)c)', 'ddd', '[lll]', '{m(aa)mm}'] 

如果括号/括号不均衡,将引发一个异常:

>>> list(parse_groups('aa(bb')) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 19, in parse_groups 
ValueError: Missing closing parethesis 
>>> list(parse_groups('aa[{bb}}')) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 20, in parse_groups 
ValueError: Missing opening parethesis 
>>> list(parse_groups('aa)bb')) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "<stdin>", line 20, in parse_groups 
ValueError: Missing opening parethesis 
0

我想你可以试试Custom String Parser库(我是它的作者)。它的设计与具有任何逻辑结构数据的工作,所以你可以自定义你想要的方式;)

+0

请确实披露您正在链接到您自己的项目;请参阅[FAQ#promotion]。这很好,但它很快被视为垃圾邮件,而不是帮助OP。 :-) – 2013-03-07 11:50:58

+0

如果你能解决你的问题,我不应该推荐一个库(即使我是作者)? – 2013-03-07 12:20:54

+0

你可以推荐一个图书馆,但如果它是*你的*项目,请这么说。 :-) – 2013-03-07 12:22:15

1

你也可以看看pyparsing。有趣的是,这可以作为一个堆栈来实现,当你发现{[(并且当你发现时弹出)]时你可以推送字符串片段。