0

ユーザーは、次のような正規表現を含む文字列を入力します。

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

また

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

一致する各ブラケットの出現をユーザー タイプとしてカウントする必要があるため、上記のテキストは最初のテキストに対してカウント 1 を返し、2 番目のテキストに対してカウント 2 を返します。一方、一致するブラケットのないブラケットはカウントされません。

'I am in the middle of writing this ('

また、ネストされた括弧を数えないようにしたいと思います。このコードは特定の状況で vim のすべてのキーストロークで実行されるため (これは UltiSnips のスニペットの一部であるため、スニペットを作成して特定のプレースホルダーに入ると、このカウント関数は新しい文字ごとに入力した内容を評価する必要があります)早くして ;)

要件を要約するには:

  1. 括弧のペアを数える
  2. ブラケットが一致しないとカウントしない
  3. ネストされたブラケットをカウントしない
  4. 速く数えます;)

要求に応じて-これを機能させるための私の最初の努力は次のとおりです: 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

3 に答える 3

2

Stack ADTを使用したこの種のタスクには、便利です。開始ブラケットが表示されたら、それをスタックに置き、終了ブラケットが表示されたら、スタックからポップしてカウンターをインクリメントします。

于 2012-07-19T08:45:21.240 に答える
1

これは、スタックベースのソリューションの 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()
于 2012-07-19T09:41:14.293 に答える