用户键入包含正则表达式的字符串,如下所示:
'I have the string "(.*)"'
或
'when user enters (\d+) times text "(.*)" truncate spaces'
我需要将每个匹配括号的出现计为用户类型,因此上面的文本将返回第一个文本的第一个和第二个的第二个。另一方面,不应计算没有匹配的括号:
'I am in the middle of writing this ('
另外,我想避免计算嵌套括号。 由于此代码将在某些情况下在vim中的每个键击中执行(它是UltiSnips片段的一部分,因此当我创建片段并输入给定占位符时,此计数函数应评估我输入的内容每个新的char)它需要快速;)
总结要求:
根据要求 - 这是我最初的努力: 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
答案 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('())(')