提取括号内的(外部)项目数

时间:2018-06-05 14:28:49

标签: python regex string algorithm

我想提取与a关联的括号内的(外部)项目数。 例如,以下示例:

a(b(c d) f)

a有两项b(c d)f,因此输出为2.

e(a(h f))

a有两项hf,因此输出为2.

b(c a(d(f) h(i j) l(2 k z)))

a有三项d(f)h(i j)以及l(2 k z),因此输出为3。

不确定如何解决这个问题,但首先我尝试将字符串转换为a(

开头的位置
m=re.search("a\((.*)\)\)", string)
print m.group()

解决这个问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

您可以使用具有递归的类来构建具有嵌套列表的结构,以在括号中表示每个项及其内容:

from typing import NamedTuple
import re
class Token(NamedTuple):
   value:str
   type:str

class Parse:
  grammer = r'\w+|\)|\('
  types = [('alpha', '\w+'), ('Oparen', '\('), ('Cparen', '\)')]
  def __init__(self, parsed):
     self.parsed = iter(parsed)
     self.stack = []
     self.parse()
  def parse(self):
    start = next(self.parsed, None)
    if start and start.type != 'Cparen':
      if start.type == 'alpha':
         self.stack.append(start.value)
      elif start.type == 'Oparen':
         _p = Parse(self.parsed)
         self.parsed = _p.parsed
         self.stack.append(_p.stack)
      self.parse()
  def __len__(self):
     return sum(isinstance(i, str) for i in self.stack[-1])
  def __getitem__(self, func):
     return self.__class__.find_length(func, self.stack)
  @classmethod
  def find_length(cls, val, params):
     for i in range(len(params)-1):
        if params[i] == val:
          return sum(not isinstance(i, list) for i in params[i+1])
        if isinstance(params[i+1], list):
          return cls.find_length(val, params[i+1])
  @staticmethod
  def tokenize(d):
    return [Token(i, [a for a, b in Parse.types if re.findall(b, i)][0]) for i in re.findall(Parse.grammer, d)]
s = ['a(b(c d) f)', 'e(a(h f))', 'b(c a(d(f) h(i j) l(2 k z)))']
c = list(map(lambda x:Parse(Parse.tokenize(x)), s))
print([i['a'] for i in c])

输出:

[2, 2, 3]