3

次のような文字列があります。

a = '{CGPoint={CGPoint=d{CGPoint=dd}}}{CGSize=dd}dd{CSize=aa}'

現在、私はこのreステートメントを使用して目的の結果を取得しています:

filter(None, re.split("\\{(.*?)\\}", a))

しかし、これは私に与えます:

['CGPoint={CGPoint=d{CGPoint=dd', '}}', 'CGSize=dd', 'dd', 'CSize=aa']

これは私の現在の状況では正しくありません。次のようなリストが必要です。

['CGPoint={CGPoint=d{CGPoint=dd}}', 'CGSize=dd', 'dd', 'CSize=aa']
4

4 に答える 4

4

@m.buettner がコメントで指摘しているように、Python の正規表現の実装は、任意の程度にネストされたシンボルのペアと一致できません。(他の言語、特に現在のバージョンの Perl では可能です。) 正規表現で解析できないテキストがある場合に Python で行うべきことは、再帰降下パーサーを使用することです。

ただし、自分で作成して車輪を再発明する必要はありません。使いやすい解析ライブラリが数多くあります。コード内で文法を直接定義し、一致したトークンにアクションを簡単にアタッチできるpyparsingをお勧めします。コードは次のようになります。

import pyparsing

lbrace = Literal('{')
rbrace = Literal('}')  
contents = Word(printables)
expr = Forward()
expr << Combine(Suppress(lbrace) + contents + Suppress(rbrace) + expr)

for line in lines:
    results = expr.parseString(line)
于 2013-07-01T14:46:39.260 に答える
2

再帰パターンをサポートする、私が本当に気に入っている Python 用の代替正規表現モジュールがあります: https://pypi.python.org/pypi/regex

pip install regex

次に、次のスクリプトに示すように、正規表現で再帰パターンを使用できます。

import regex
from pprint import pprint


thestr = '{CGPoint={CGPoint=d{CGPoint=dd}}}{CGSize=dd}dd{CSize=aa}'

theregex = r'''
    (
        {
            (?<match>
                [^{}]*
                (?:
                    (?1)
                    [^{}]*
                )+
                |
                [^{}]+
            )
        }
        |
        (?<match>
            [^{}]+
        )
    )
'''

matches = regex.findall(theregex, thestr, regex.X)

print 'all matches:\n'
pprint(matches)

print '\ndesired matches:\n'
print [match[1] for match in matches]

これは以下を出力します:

all matches:

[('{CGPoint={CGPoint=d{CGPoint=dd}}}', 'CGPoint={CGPoint=d{CGPoint=dd}}'),
 ('{CGSize=dd}', 'CGSize=dd'),
 ('dd', 'dd'),
 ('{CSize=aa}', 'CSize=aa')]

desired matches:

['CGPoint={CGPoint=d{CGPoint=dd}}', 'CGSize=dd', 'dd', 'CSize=aa']
于 2013-07-01T15:50:36.010 に答える
2

pyparsingには、nestedExprネストされた式を照合する関数があります。

import pyparsing as pp

ident = pp.Word(pp.alphanums)
expr = pp.nestedExpr("{", "}") | ident

thestr = '{CGPoint={CGPoint=d{CGPoint=dd}}}{CGSize=dd}dd{CSize=aa}'
for result in expr.searchString(thestr):
    print(result)

収量

[['CGPoint=', ['CGPoint=d', ['CGPoint=dd']]]]
[['CGSize=dd']]
['dd']
[['CSize=aa']]
于 2013-07-01T21:29:45.253 に答える