我想提取与a
关联的括号内的(外部)项目数。
例如,以下示例:
a(b(c d) f)
a
有两项b(c d)
和f
,因此输出为2.
e(a(h f))
a
有两项h
和f
,因此输出为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()
解决这个问题的最佳方法是什么?
答案 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]