Python 智能获取两个字符之间的文本

Python 智能获取两个字符之间的文本,python,string,python-3.x,Python,String,Python 3.x,假设我有这样一个字符串: (a(b(p(m()())))) (x(q(y(w()())(k()()))())(a(z()())(d(f()())()))) 并要检索子字符串: a(b(p(m()()))) b(p(m()())) p(m()()) m()() 任意提取封装括号之间的文本将导致如下结果: a(b(p(m( ['x(q(y(w()())(k()()))())(a(z()())(d(f()())()))', 'q(y(w()())(k()()))()', 'y(w()())(k

假设我有这样一个字符串:

(a(b(p(m()()))))
(x(q(y(w()())(k()()))())(a(z()())(d(f()())())))
并要检索子字符串:

a(b(p(m()())))
b(p(m()()))
p(m()())
m()()
任意提取封装括号之间的文本将导致如下结果:

a(b(p(m(
['x(q(y(w()())(k()()))())(a(z()())(d(f()())()))', 'q(y(w()())(k()()))()', 'y(w()())(k()())', 'w()()', 'k()()', 'a(z()())(d(f()())())', 'z()()', 'd(f()())()', 'f()()']
这就是我如何规划处理此问题的功能:

def get_encapsulated_text(s):
    t = ''
    it = cycle(s)
    count = 0
    for c in it:
        if c is '(':
            print(c)
            while count != 0:
                t += next(it)
                print(t)
                nxt = next(it)
                if nxt is '(':
                    count += 1
                elif nxt is ')':
                    count -= 1
但它显然进入了一个无限循环,我不是蟒蛇。非常感谢您的帮助

我想让它针对一个更复杂的例子,比如:

(a(b(p(m()()))))
(x(q(y(w()())(k()()))())(a(z()())(d(f()())())))
具有如下预期输出:

a(b(p(m(
['x(q(y(w()())(k()()))())(a(z()())(d(f()())()))', 'q(y(w()())(k()()))()', 'y(w()())(k()())', 'w()()', 'k()()', 'a(z()())(d(f()())())', 'z()()', 'd(f()())()', 'f()()']
def get_组件(字符串):
成对,组合=[],[]
对于枚举中的i,c(字符串):
如果c==“(”:
pairs.append([i,])
elif c==”):
对于反向(成对)的p:
如果len(p)<2:
p、 附加(i)
组件插入(0,字符串[p[0]+1:p[1]]
打破
返回[x,如果len(x)>0,则在comps中为x返回x]

这是一张草图。我会设置一个增量变量

increment = 1
然后我将遍历字符串,从
a
(第一个括号后)开始。每次我遇到'('我加1,每次我遇到')'我减去1。当我遇到0时,我知道我有匹配的括号

(a(b(p(m()()))))
1^2 3 4 54543210
一旦我有了它,我就可以把括号里的东西拿出来(我现在知道了它的位置)

然后,我将递归调用相同的函数,并执行相同的步骤。然后将递归调用的输出附加到我拥有的字符串中

a(b(p(m()())))
 1^2 3 4343210
我们可以在
m()()

在这种情况下,它会给我们两对匹配的括号。举个更复杂的例子

x(q(y(w()())(k()()))())(a(z()())(d(f()())()))
 1^2 3 434323 4343212101 2 323212 3 434323210
现在它可以在那里智能地找到
q(y(w())(k())()
a(z())(d(f())())

编辑:我想我应该把一些东西打出来

def get_encapsulated_text(s):
    count = 0
    t = ""
    for c in s:
      if count != 0:
        t += c
      if c is '(':
        count += 1
      elif c is ')':
        count -= 1;
        if count == 0:
          output = t[:-1]
          t = ""
          if(output != ""):
            print(output)
            get_encapsulated_text(output)

我认为这里的关键是递归。

因为它是嵌套的,所以您可能希望使用
str.split('(',1)
str.rsplit(')',1)
来隔离数据。为什么不也使用
m()
呢?当然也可以使用。我只是想帮助说明一下这个概念。
(x(q(y)(w())(k())(a(z())(d(f()))))
这方面的预期输出是什么我会使用一个变量,遇到“(”时递增,遇到“)”时递减,这样你就可以找到“匹配的括号”。我可能还会使用一点递归。*检查我的最新编辑以获得更好的挑战:这会导致此中断,因为规则和模式已更改。*检查我的最新编辑以获得更好的挑战:这会导致此中断。您能否回答cryptonome关于更复杂字符串的预期输出的问题?如果不是,我会添加
substr:
在将子字符串添加到
comps
之前,避免空字符串。有没有办法避免额外的迭代周期,但有类似于“清洁度”的东西?我相信它可能会更简洁,但现在它只横穿
string
一次。不过,您的更新版本会反转整个输出字符串。有没有一种方法可以在保持此版本的效率的同时获得初始版本返回的内容?是的,使用
.insert()
而不是
.append()
;见上文。
def get_encapsulated_text(text):
    stack = []
    for c in text:
        if c == ')':
            inner = stack.pop()
            if inner:
                yield ''.join(inner)
        for s in stack:
            s.append(c)
        if c == '(':
            stack.append([])
def get_encapsulated_text(text):
    stack = []
    for c in text:
        if c == ')':
            inner = stack.pop()
            if inner:
                yield ''.join(inner)
        for s in stack:
            s.append(c)
        if c == '(':
            stack.append([])