计算python字符串中的匹配括号

时间:2012-07-19 08:27:19

标签: python

用户键入包含正则表达式的字符串,如下所示:

'I have the string "(.*)"'

'when user enters (\d+) times text "(.*)" truncate spaces'

我需要将每个匹配括号的出现计为用户类型,因此上面的文本将返回第一个文本的第一个和第二个的第二个。另一方面,不应计算没有匹配的括号:

'I am in the middle of writing this ('

另外,我想避免计算嵌套括号。 由于此代码将在某些情况下在vim中的每个键击中执行(它是UltiSnips片段的一部分,因此当我创建片段并输入给定占位符时,此计数函数应评估我输入的内容每个新的char)它需要快速;)

总结要求:

  1. 计算括号对
  2. 如果没有匹配的支架,请不要计算支架
  3. 不计算嵌套括号
  4. 快速计算;)
  5. 根据要求 - 这是我最初的努力: https://gist.github.com/3142334

    它有效,但不幸的是它也算内部括号,所以我需要更多调整它。

    这是另一个只计算外括号的解决方案:

    def fb(string, c=0):
        left_bracket = string.find("(")
        if left_bracket > -1:
            string = string[left_bracket + 1:]
            right_bracket = string.find(")")
            if right_bracket > -1:
                if string[:right_bracket].find("(") == -1:
                    c += 1
                string = string[right_bracket + 1:]
            return fb(string, c)
        else:
            return c
    

4 个答案:

答案 0 :(得分:2)

对于使用Stack ADT的这类任务很有用。每当你看到一个开口支架将其放入堆叠时,当你看到关闭支架从堆叠中弹出它并增加计数器时。

答案 1 :(得分:1)

关于这个主题已经存在类似的问题:Regular Expression to match outer brackets。正则表达式不是解决方案。

答案 2 :(得分:1)

这是一个基于堆栈的解决方案。当输入是某个控制字符时,仅计算整个字符串中的大括号会更快,但由于在键入之前进行文本选择和其他原因,这很棘手。这也不是非常pythonic,但它似乎工作,它相对较快:

#!/usr/bin/env python

import re

def bracecounter(s):
    count = 0; open = 0; braces = []
    for c in s:
        if c in '()':
            braces.append(c)
            if c == '(':
                open += 1
            else:
                if ''.join(braces[-2:]) == '()':
                    braces = braces[:-2]
                    if open == 1:
                        count += 1
                    open -= 1
                else:
                    pass # closing brace without matching opening brace
    return count

fix = [
    (1, 'I have the string "(.*)"'),
    (2, 'when user enters (\d+) times text "(.*)" truncate spaces'),
    (0, 'I am in the middle of writing this ('),
    (1, ') Nested ((braces) will (not) count))))))).'),
    ]

def test():
    for exp, s in fix:
        res = bracecounter(s)
        assert exp == res, "Brace count %s != %s for '%s'" % (res, exp, s)

if __name__ == '__main__':
    test()

答案 3 :(得分:0)

我正在解决计算作业问题的方括号,并使用列表作为堆栈是我弄清楚的方式,如下代码:

def bracket_match(text):

    stack = []
    pairs = 0

    #iterate through the string
    for letter in text:

        if letter == '(':
            stack.append(letter)

        elif letter == ')':

            if len(stack) == 0:
                pass
            else:
                stack.pop()
                pairs += 1

    return pairs

bracket_match('())(')